2009-06-09 10 views
2

Est-ce que quelqu'un connaît un moyen plus facile de travailler avec les types définis par l'utilisateur dans Oracle en utilisant cx_Oracle?cx_Oracle et les types définis par l'utilisateur

Par exemple, si j'ai ces deux types:

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 
/

Et puis une procédure en paquet my_package comme suit:

PROCEDURE my_procedure (param in my_type_tab); 

Pour exécuter la procédure PL/SQL que je peux faire quelque chose comme ceci:

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; 

Cependant, je me demandais comment je peux le faire en Python, simila r à ce code:

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) 

Si le paramètre est une chaîne que je peux le faire comme ci-dessus, mais comme il est un type défini par l'utilisateur, je ne sais pas comment l'appeler sans avoir recours à pur code PL/SQL . Désolé, j'aurais dû dire que je cherchais des façons de faire plus de code Python au lieu de PL/SQL.

Répondre

0

Essayez-vous de remplir la table des objets plus efficacement?

Si vous pouvez faire une commande SELECT, jetez un oeil à l'VRAC COLLECT clause INTO

-1

Je ne suis pas tout à fait sûr de ce que vous entendez par codé en dur, mais vous pouvez construire un tableau dynamique comme celui-ci:

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 

Cela a été testé avec Oracle 11.1.0.6.

3

Bien que cx_Oracle puisse sélectionner des types définis par l'utilisateur, il ne me semble pas que la prise en charge passe par des types définis par l'utilisateur en tant que variables de liaison. Ainsi, par exemple ce qui suit fonctionnera:

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

Cependant ce que vous ne pouvez pas faire est de construire un objet Python, passer comme argument d'entrée et ensuite cx_Oracle « traduire » l'objet Python dans votre type Oracle. Donc je dirais que vous allez devoir construire votre argument d'entrée dans un bloc PL/SQL.

Vous pouvez passer dans les listes Python, ce qui suit devrait fonctionner:

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) 
Questions connexes