2009-06-09 2 views
2

Кто-нибудь знает, как проще работать с определенными пользователем типами в Oracle с помощью cx_Oracle?cx_Oracle и определяемые пользователем типы

Например, если у меня есть эти два типа:

CREATE type my_type as object(
component varchar2(30) 
,key varchar2(100) 
,value varchar2(4000)) 
/
CREATE type my_type_tab as table of my_type 
/

, а затем процедура в пакете my_package следующим образом:

PROCEDURE my_procedure (param in my_type_tab); 

Чтобы выполнить процедуру, описанную в PL/SQL я могу сделать что-то например:

declare 
    l_parms my_type_tab; 
    l_cnt  pls_integer; 
begin 
    l_parms := my_type_tab(); 
    l_parms.extend; 
    l_cnt := l_parms.count; 
    l_parms(l_cnt) := my_type('foo','bar','hello'); 
    l_parms.extend; 
    l_cnt := l_parms.count; 
    l_parms(l_cnt) := my_type('faz','baz','world'); 
    my_package.my_procedure(l_parms); 
end; 

Однако мне было интересно, как я могу это сделать в Python, simila г к этому коду:

import cx_Oracle 
orcl = cx_Oracle.connect('foo:[email protected]:5555/blah' + instance) 
curs = orcl.cursor() 
params = ??? 
curs.execute('begin my_package.my_procedure(:params)', params=params) 

Если параметр был строкой я могу сделать это, как указано выше, но так как это пользователь определенный тип, я понятия не имею, как это назвать, не прибегая к чистому PL/код SQL ,

Редактировать: Извините, мне следовало сказать, что я искал способы сделать больше в коде Python вместо PL/SQL.

ответ

0

Вы пытаетесь более эффективно заполнить таблицу объектов?

Если вы можете сделать SELECT, имеют вид на BULK COLLECT INTO п

-1

Я не совсем уверен, что вы имеете в виду жестко, но вы можете создать динамический массив, как это:

SQL> desc my_procedure 
Parameter Type  Mode Default? 
--------- ----------- ---- -------- 
P_IN  MY_TYPE_TAB IN 

SQL> declare 
    2  l_tab my_type_tab; 
    3 begin 
    4  select my_type(owner, table_name, column_name) 
    5  bulk collect into l_tab 
    6  from all_tab_columns 
    7  where rownum <= 10; 
    8  my_procedure (l_tab); 
    9 end; 
10/

PL/SQL procedure successfully completed 

Это было протестировано с помощью Oracle 11.1.0.6.

3

В то время как cx_Oracle может выбирать определенные пользователем типы, я не знаю, что поддержка поддержки передается в пользовательских типах как переменные привязки. Так, например, следующие будут работать:

cursor.execute("select my_type('foo', 'bar', 'hello') from dual") 
val, = cursor.fetchone() 
print val.COMPONENT, val.KEY, val.VALUE 

Однако то, что вы не можете сделать, это построить объект Python, передать его в качестве входного аргумента и затем cx_Oracle «перевести» объект Python в вашем типа Oracle. Поэтому я бы сказал, что вам нужно будет создать свой входной аргумент в блоке PL/SQL.

Вы можете передать в списках Python, так что должно работать:

components=["foo", "faz"] 
values=["bar", "baz"] 
keys=["hello", "world"] 
cursor.execute(""" 
declare 
    type udt_StringList is table of varchar2(4000) index by binary_integer; 
    l_components udt_StringList := :p_components; 
    l_keys udt_StringList := :p_keys; 
    l_values udt_StringList := :p_values; 
    l_parms my_type_tab; 
begin 
    l_parms.extend(l_components.count); 
    for i in 1..l_components.count loop 
    l_parms(i) := my_type(l_components(i), l_keys(i), l_values(i)); 
    end loop; 

    my_package.my_procedure(l_parms); 
end;""", p_components=components, p_values=values, p_keys=keys) 
Смежные вопросы