如何在python cx_Oracle中创建Oracle用户定义类型?

如何在python cx_Oracle中创建Oracle用户定义类型?,python,cx-oracle,Python,Cx Oracle,Python 3.4.3,cx_Oracle 5.2 11g,Oracle DB 11.2.0.1 你好!! 我想通过cx\u Oracle从python获取数据泵作业的状态 为了解决这个问题,我调用Oracledbms\u datapump.get\u status过程: DBMS_DATAPUMP.GET_STATUS( handle IN NUMBER, mask IN BINARY_INTEGER, timeout IN NUMBER DEFAULT NUL

Python 3.4.3
cx_Oracle 5.2 11g
Oracle DB 11.2.0.1

你好!! 我想通过
cx\u Oracle
从python获取数据泵作业的状态

为了解决这个问题,我调用Oracle
dbms\u datapump.get\u status过程

DBMS_DATAPUMP.GET_STATUS( 
    handle IN NUMBER, 
    mask IN BINARY_INTEGER, 
    timeout IN NUMBER DEFAULT NULL, 
    job_state OUT VARCHAR2, 
    status OUT ku$_Status1120);
从python
cx\u Oracle

get_status_params = {'handle': job_handler,
                     'mask': 1,
                     'timeout': -1,
                     'job_state': job_state,
                     'status': ??????
                     }
cursor.callproc('dbms_datapump.get_status', keywordParameters=get_status_params)
Oracle中的结构
ku$\u Status1120

CREATE TYPE sys.ku$_Status1120 IS OBJECT
(
    mask NUMBER, 
    wip ku$_LogEntry1010, 
    job_description ku$_JobDesc1020, 
    job_status ku$_JobStatus1120,
    error ku$_LogEntry1010 
)
job\u status
在oracle中键入,例如:

CREATE TYPE sys.ku$_JobStatus1120 IS OBJECT
        (
            job_name        VARCHAR2(30),           
            operation       VARCHAR2(30),           
            job_mode        VARCHAR2(30),           
            bytes_processed NUMBER,                 
            total_bytes     NUMBER,                 
            percent_done    NUMBER,                 
            degree          NUMBER,                 
            error_count     NUMBER,                 
            state           VARCHAR2(30),           
            phase           NUMBER,                 
            restart_count   NUMBER,                 
            worker_status_list ku$_WorkerStatusList1120,                                                        
            files           ku$_DumpFileSet1010    
    )

如何在Python中重复Oracle type
sys.ku$\u Status1120

我有一篇关于使用cx\u Oracle实现CRUD功能的短文,在本文中,我使用以下内容检索returning子句的值

new_id = cur.var(cx_Oracle.NUMBER)

statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id into :4'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id))

sandy_id = new_id.getvalue()
对于单值
cur.var(cx_Oracle.NUMBER)
和数组
cur.arrayvar(cx_Oracle.NUMBER,1000)
,我使用了相同的方法,没有从程序中取出参数

我没有专门使用
cx\u Oracle.OBJECT
类型,但我认为它的工作原理与其他类型类似

医生:和

试试这个

job_status_out = cursor.var(cx_Oracle.OBJECT)

get_status_params = {'handle': job_handler,
                     'mask': 1,
                     'timeout': -1,
                     'job_state': job_state,
                     'status': job_status_out
                     }
cursor.callproc('dbms_datapump.get_status', keywordParameters=get_status_params)

job_status = job_status_out.getvalue()
最坏的情况是,如果您在从cur.var(cx_Oracle.NUMBER)变量获取值时遇到问题;您可以将
dbms\u datapump.get\u status
封装在pl/sql函数中,该函数以字符串形式返回值并调用该值。我知道这是可行的。

这个答案是我给出的另一个答案的替代答案。另一个答案是更好的解决方案,假设返回类型没有任何问题

此解决方案将与任何可以对数据库进行SQL调用的语言配合使用。因此,即使您使用的应用程序语言不支持调用PL/SQL函数,您仍然可以获得所需的内容

如果无法从Oracle数据库(如自定义类型或复杂数据集)中获取某些内容,则可以编写一个

管道表函数允许您在pl/sql端执行所需的任何操作,并以您选择的表格格式格式化/返回结果

然后在应用层上,您可以从这个函数中进行选择,就像它是一个表一样

我已经解释了如何在NodeJS调用中使用它,但是我修改了这个示例以使用Python

在PL/SQL中:

(这不必在包中,这只是我使用的示例)

之后,它是一个简单的从应用程序中选择状态

在Python中:

cur = con.cursor()
statement = 'SELECT member_id, dino_name FROM TABLE(text_only(:memberId, :keywords)) ORDER BY dino_name'
cur.execute(statement, (35, 'Rocks'))
res = cur.fetchall()
print (res)

对于您的特定问题,您可以将对
dbms\u数据泵的调用包装起来。在管道函数中获取\u status
,而不是使用示例中的select。

谢谢!我以前尝试过使用cursor.var(cx_Oracle.OBJECT)。结果:job\u status\u out=cursor.var(cx\u Oracle.OBJECT)类型错误:对象变量需要类型名称。当我尝试其他解决方案时,我会留下评论。cx_Oracle的开发版本中添加了对绑定对象的支持。是的,您确实需要将typename=添加到上面提到的cursor.var()语句中。今天我尝试使用job\u status=cursor.var(cx\u Oracle.OBJECT,typename='ku$\u Status1010')。cursor.callproc('dbms\u datapump.get\u status',keywordParameters=get\u status\u params)cx\u Oracle.NotSupportedError:Variable\u TypeByValue():未处理的数据类型cx\u Oracle.OBJECTVAR
cur = con.cursor()
statement = 'SELECT member_id, dino_name FROM TABLE(text_only(:memberId, :keywords)) ORDER BY dino_name'
cur.execute(statement, (35, 'Rocks'))
res = cur.fetchall()
print (res)