【问题标题】:cx_Oracle And User Defined Typescx_Oracle 和用户定义类型
【发布时间】:2010-11-01 13:23:03
【问题描述】:

有谁知道在 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 中做到这一点,类似于以下代码:

import cx_Oracle
orcl = cx_Oracle.connect('foo:bar@mydb.com:5555/blah' + instance)
curs = orcl.cursor()
params = ???
curs.execute('begin my_package.my_procedure(:params)', params=params)

如果参数是一个字符串,我可以像上面那样做,但是由于它是一个用户定义的类型,我不知道如何在不求助于纯 PL/SQL 代码的情况下调用它。

编辑:抱歉,我应该说我正在寻找在 Python 代码而不是 PL/SQL 中做更多事情的方法。

【问题讨论】:

    标签: python oracle cx-oracle


    【解决方案1】:

    您是否尝试更有效地填充对象表?

    如果您可以执行 SELECT,请查看 BULK COLLECT INTO 子句

    【讨论】:

      【解决方案2】:

      我不太清楚你所说的硬编码是什么意思,但你可以像这样构建一个动态数组:

      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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-04
          • 1970-01-01
          • 2016-01-12
          • 2018-01-11
          • 2019-01-03
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          相关资源
          最近更新 更多