2016-02-15 2 views
1

Я создал хранимую процедуру Oracle в пакете. Я сделал так:Как создать хранимую процедуру oracle с параметром массива

CREATE OR REPLACE PACKAGE PACKFACE IS 
TYPE LIST_IDS IS TABLE OF INT INDEX BY BINARY_INTEGER; 
PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT,IDS_NOT IN LIST_IDS); 
END; 

И тело пакета:

CREATE OR REPLACE PACKAGE BODY PACKFACE IS 
    PROCEDURE P_SELECT_IDBFRIENDS (CONSULTA OUT SYS_REFCURSOR,COD_US IN INT, IDS_NOT IN LIST_IDS) IS 
    BEGIN 
     OPEN CONSULTA FOR 
     SELECT ID_US1,ID_US2 FROM T_FRIENDSHIP WHERE ID_US1=COD_US AND ID_US2 NOT IN (SELECT COLUMN_VALUE FROM TABLE(IDS_NOT)); 
    END; 
END; 
/

Это нормально в моем 12c сервере Oracle, но я тот же самый код в Oracle 11g появилась ошибка, не может доступ к строкам из не вложенной таблицы. Каким будет решение? Заранее спасибо После устранения этой проблемы. Появляется другой код моего Python. У меня есть эта процедура:

def select_ids(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("PROC_SELECT_IDS_ENT_AMISTADES", [cursor, cod_us, varray]) 
     lista = l_query[0] 
     return lista 
    except cx_Oracle.DatabaseError as ex: 
     error, = ex.args 
     print(error.message) 
     return lista 

PLS-00306 неправильное количество или тип аргументов при вызове процедуры. Это было нормально, используя Oracle 12c. Спасибо заранее.

+0

Я считаю, что вам нужно будет определить тип вашей коллекции в SQL. Есть ли причина, по которой вам нужен ассоциативный массив (который может быть определен только в PL/SQL), а не вложенная таблица (которая может быть определена как в SQL, так и в PL/SQL)? –

+0

Я искал решение той же ошибки –

+0

Прежде всего, я должен исключить идентификаторы, хранящиеся в массиве, после чего я делаю выбор, используя in, исключая идентификаторы (переменный размер) – lgerras84

ответ

0

Прежде всего, вы должны создать тип оракула, как это:

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 FACEBOOK.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 ID_US1,ID_US2 FROM T_FRIENDSHIP WHERE ID_US1=COD_US AND ID_US2 NOT IN (SELECT COLUMN_VALUE FROM TABLE(num_array)); 
    END; 
END; 

Я сделал это, и я получил решение на неправильный номер или типа параметры ошибок питона. Удачи.

+0

Я попробую. Большое спасибо за ваш код – lgerras84

+0

Отлично. Оно работает. Спасибо всем. – lgerras84

1

Вы не можете использовать тип коллекции, определенный в PL/SQL в запросе SQL в Oracle 11.

Если вы хотите использовать коллекцию как в SQL и PL/SQL, то вам придется определить его в SQL :

CREATE TYPE LIST_IDS IS TABLE OF INT; 

Тогда вы можете сделать:

CREATE OR REPLACE PACKAGE PACKFACE IS 
    PROCEDURE P_SELECT_IDBFRIENDS (
    CONSULTA OUT SYS_REFCURSOR, 
    COD_US IN INT, 
    IDS_NOT IN LIST_IDS 
); 
END; 
/
SHOW ERRORS; 

CREATE OR REPLACE PACKAGE BODY PACKFACE IS 
    PROCEDURE P_SELECT_IDBFRIENDS (
    CONSULTA OUT SYS_REFCURSOR, 
    COD_US IN INT, 
    IDS_NOT IN LIST_IDS 
) 
    IS 
    BEGIN 
    OPEN CONSULTA FOR 
    SELECT ID_US1,ID_US2 
    FROM T_FRIENDSHIP 
    WHERE ID_US1=COD_US 
    AND ID_US2 NOT MEMBER OF IDS_NOT; 
    END; 
END; 
/
SHOW ERRORS; 
+0

Спасибо большое, оно было исправлено. Теперь проблема в моем коде python. Я изменю свой вопрос – lgerras84