2009-06-09 18 views
2

cx_Oracleを使用してOracleでユーザー定義型を操作する方が簡単な方はいらっしゃいますか?例えばcx_Oracleとユーザー定義型

、私はこれらの2つのタイプがある場合は、次のように

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で行うことができるのだろうと思っていましたこのコードへR:

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コードに頼ることなく、それを呼び出す方法が分からない場合は。

編集:申し訳ありませんが、私はPL/SQLの代わりにPythonコードでもっと多くのことを行う方法を探していたはずです。

答えて

0

オブジェクトの表をより効率的に作成しようとしていますか?

あなたがSELECTを行うことができます場合は、BULK見句

-1

INTO COLLECTてきた私は、あなたがハードコーディングされたことにより、何を意味するかは非常にわからないんだけど、あなたはこのような動的配列を構築することができます。

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のオブジェクトを作成入力引数として渡すと、あなたのOracle型にcx_Oracle「翻訳」Pythonオブジェクトを持っています。ですから、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)