Python 2.7 如何将python数组传递给oracle存储过程?

Python 2.7 如何将python数组传递给oracle存储过程?,python-2.7,stored-procedures,cx-oracle,Python 2.7,Stored Procedures,Cx Oracle,我有个问题。当我传递Python数组时: self.notPermited = [2,3] 这是我的程序 def select_ids_entre_amistades(self,cod_us,ids_not): lista = [] try: cursor = self.__cursor.var(cx_Oracle.CURSOR) print ids_not data = self.__cursor.arrayvar(cx_Ora

我有个问题。当我传递Python数组时:

self.notPermited = [2,3]
这是我的程序

def select_ids_entre_amistades(self,cod_us,ids_not):
    lista = []
    try:
        cursor = self.__cursor.var(cx_Oracle.CURSOR)
        print ids_not
        data = self.__cursor.arrayvar(cx_Oracle.NUMBER, ids_not)
        print data
        l_query = self.__cursor.callproc("SCHEMA.PROC_SELECT_IDS_ENT_AMISTADES", [cursor,cod_us,data])
        lista = l_query[0]
        return lista
    except cx_Oracle.DatabaseError as ex:
        error, = ex.args
        print(error.message)
        return lista
问题是当我使用以下方法调用该过程时:

self.select_ids_entre_amistades(int_id,self.notPermited)
我在控制台中显示以下消息:

PLS-00306:调用'PROC'时参数的数量或类型错误

在数据库中,我创建了如下数组对象:

CREATE TYPE SCHEMA.ARRAY_ID_FRIENDS AS TABLE OF INT;
CREATE OR REPLACE PROCEDURE FACEBOOK.PROC_SELECT_IDS_ENT_AMISTADES
(CONSULTA OUT SYS_REFCURSOR,COD_US IN INT, IDS_FRIEND IN SCHEMA.ARRAY_ID_FRIENDS)
Oracle存储过程的启动方式如下:

CREATE TYPE SCHEMA.ARRAY_ID_FRIENDS AS TABLE OF INT;
CREATE OR REPLACE PROCEDURE FACEBOOK.PROC_SELECT_IDS_ENT_AMISTADES
(CONSULTA OUT SYS_REFCURSOR,COD_US IN INT, IDS_FRIEND IN SCHEMA.ARRAY_ID_FRIENDS)

我不知道问题是什么,我相信
cx\u Oracle.NUMBER
不是整数,但没有其他数字类型。提前感谢。

当您查看
cx\U Oracle
文档时,它说您可以创建这样的阵列

创建一个与给定类型和大小的游标关联的数组变量,并返回一个变量对象(变量对象)。该值可以是一个整数,指定要分配的元素数,也可以是一个列表,分配的元素数从列表的大小中提取。如果该值是一个列表,则该变量也将与列表的内容一起设置。如果未指定大小且类型为字符串或二进制,则分配4000字节(Oracle允许的最大值)。这是将数组传递给PL/SQL(在列表可能为空且无法自动确定类型的情况下)或从PL/SQL返回数组时所必需的

只要数组类型与
PL/SQL
过程的参数兼容,就可以传递数组。下面是一个创建数组的简单示例

>>> myarray=cursor.arrayvar(cx_Oracle.NUMBER,range(0,10))
>>> myarray
<cx_Oracle.NUMBER with value [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]>

当您查看
cx\u Oracle
文档时,它说您可以这样创建阵列

创建一个与给定类型和大小的游标关联的数组变量,并返回一个变量对象(变量对象)。该值可以是一个整数,指定要分配的元素数,也可以是一个列表,分配的元素数从列表的大小中提取。如果该值是一个列表,则该变量也将与列表的内容一起设置。如果未指定大小且类型为字符串或二进制,则分配4000字节(Oracle允许的最大值)。这是将数组传递给PL/SQL(在列表可能为空且无法自动确定类型的情况下)或从PL/SQL返回数组时所必需的

只要数组类型与
PL/SQL
过程的参数兼容,就可以传递数组。下面是一个创建数组的简单示例

>>> myarray=cursor.arrayvar(cx_Oracle.NUMBER,range(0,10))
>>> myarray
<cx_Oracle.NUMBER with value [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]>

尝试在过程的参数中使用plsql数组,然后传递sql数组的内容。最后一个将用于将sql语句插入到过程中。它解决了我在使用oracle database 11g时遇到的问题,因为在12g中,您不需要将内容传递给sql数组。这可能是代码:

def select_ids_entre_amistades(self,cod_us,ids_not):
    lista = []
    try:
        cursor = self.__cursor.var(cx_Oracle.CURSOR)
        varray = self.__cursor.arrayvar(cx_Oracle.NUMBER,ids_not)
        l_query = self.__cursor.callproc("PACKFACE.P_SELECT_IDBFRIENDS", [cursor, cod_us, varray])
        lista = l_query[0]
        return lista
    except cx_Oracle.DatabaseError as ex:
        error, = ex.args
        self.guardar_errores('dato ' + str(error.message))
        return lista
存储过程如下所示: 首先创建一个类型

CREATE OR REPLACE TYPE LIST_IDS AS TABLE OF INT;
然后创建包

CREATE OR REPLACE PACKAGE PACKFACE IS
TYPE LISTADO_IDS IS TABLE OF INT INDEX BY PLS_INTEGER;
PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT,IDS_NOT IN LISTADO_IDS);
END;
最后创建包的主体

CREATE OR REPLACE PACKAGE BODY PACKFACE IS
    PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT, IDS_NOT IN LISTADO_IDS) 
    IS
        num_array LIST_IDS;
    BEGIN
        num_array:=LIST_IDS();
        for i in 1 .. IDS_NOT.count
        loop
            num_array.extend(1);
            num_array(i) := IDS_NOT(i);
        end loop; 
        OPEN CONSULTA FOR 
        SELECT * FROM T_TABLE WHERE ID IN (SELECT COLUMN_VALUE FROM TABLE(num_array));
    END;
END;

我希望它能帮助您。

尝试在过程的参数中使用plsql数组,然后传递sql数组的内容。最后一个将用于将sql语句插入到过程中。它解决了我在使用oracle database 11g时遇到的问题,因为在12g中,您不需要将内容传递给sql数组。这可能是代码:

def select_ids_entre_amistades(self,cod_us,ids_not):
    lista = []
    try:
        cursor = self.__cursor.var(cx_Oracle.CURSOR)
        varray = self.__cursor.arrayvar(cx_Oracle.NUMBER,ids_not)
        l_query = self.__cursor.callproc("PACKFACE.P_SELECT_IDBFRIENDS", [cursor, cod_us, varray])
        lista = l_query[0]
        return lista
    except cx_Oracle.DatabaseError as ex:
        error, = ex.args
        self.guardar_errores('dato ' + str(error.message))
        return lista
存储过程如下所示: 首先创建一个类型

CREATE OR REPLACE TYPE LIST_IDS AS TABLE OF INT;
然后创建包

CREATE OR REPLACE PACKAGE PACKFACE IS
TYPE LISTADO_IDS IS TABLE OF INT INDEX BY PLS_INTEGER;
PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT,IDS_NOT IN LISTADO_IDS);
END;
最后创建包的主体

CREATE OR REPLACE PACKAGE BODY PACKFACE IS
    PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT, IDS_NOT IN LISTADO_IDS) 
    IS
        num_array LIST_IDS;
    BEGIN
        num_array:=LIST_IDS();
        for i in 1 .. IDS_NOT.count
        loop
            num_array.extend(1);
            num_array(i) := IDS_NOT(i);
        end loop; 
        OPEN CONSULTA FOR 
        SELECT * FROM T_TABLE WHERE ID IN (SELECT COLUMN_VALUE FROM TABLE(num_array));
    END;
END;

我希望它能帮助您。

如果我传递的是一个变量,而不是范围(0,10),我该如何更改?请帮助我。您可以制作列表,arrayvar
cursor.arrayvar(cx_Oracle.[DataType],…])
例如
cursor.arrayvar(cx_Oracle.DATETIME,[dt1,dt2])
是的,我这样做:varray=cursor.arrayvar(cx_Oracle.NUMBER,ids\u not),然后我调用cursor.callproc(“PROC_SELECT\u id\u,[cursor,cod\u us,varray]),id\u没有[10.0,20.0],varray也是,但错误仍然存在PLS-00306:参数类型的数量PROC\U SELECT\U IDS\U我不确定,但您可以创建游标,就像
cursor=connection.cursor()
而不是
cursor=self.\uu cursor.var(cx\u Oracle.cursor)
。请试试这个。我在没有varray的情况下修改了代码,运行正常。问题在于瓦雷。我读过关于二进制整数索引的文章,但我不知道如何声明。我做到了:创建类型ARRAY\u ID\u FRIENDS作为数字表;如果我传递的是一个变量而不是范围(0,10),我该如何更改?请帮助我。您可以制作列表,arrayvar
cursor.arrayvar(cx_Oracle.[DataType],…])
例如
cursor.arrayvar(cx_Oracle.DATETIME,[dt1,dt2])
是的,我这样做:varray=cursor.arrayvar(cx_Oracle.NUMBER,ids\u not),然后我调用cursor.callproc(“PROC_SELECT\u id\u,[cursor,cod\u us,varray]),id\u没有[10.0,20.0],varray也是,但错误仍然存在PLS-00306:参数类型的数量PROC\U SELECT\U IDS\U我不确定,但您可以创建游标,就像
cursor=connection.cursor()
而不是
cursor=self.\uu cursor.var(cx\u Oracle.cursor)
。请试试这个。我在没有varray的情况下修改了代码,运行正常。问题在于瓦雷。我读过关于二进制整数索引的文章,但我不知道如何声明。我做到了:创建类型ARRAY\u ID\u FRIENDS作为数字表;