简体   繁体   English

使用 cx_Oracle 从存储过程中捕获标准输出 output

[英]Capturing stdout output from stored procedures with cx_Oracle

Is there a way in cx_Oracle to capture the stdout output from an oracle stored procedure? cx_Oracle 中有没有办法从 oracle 存储过程中捕获标准输出 output? These show up when using Oracle's SQL Developer or SQL Plus, but there does not seem to be a way to fetch it using the database drivers.这些在使用 Oracle 的 SQL Developer 或 SQL Plus 时出现,但似乎没有办法使用数据库驱动程序获取它。

You can retrieve dbms_output with DBMS_OUTPUT.GET_LINE(buffer, status) .您可以使用DBMS_OUTPUT.GET_LINE(buffer, status)检索 dbms_output。 Status is 0 on success and 1 when there's no more data.成功时状态为 0,没有更多数据时状态为 1。

You can also use get_lines(lines, numlines) .您还可以使用get_lines(lines, numlines) numlines is input-output. numlines是输入输出。 You set it to the max number of lines and it is set to the actual number on output.您将其设置为最大行数,并将其设置为输出的实际数量。 You can call this in a loop and exit when the returned numlines is less than your input.您可以在循环中调用它并在返回的numlines小于您的输入时退出。 lines is an output array. lines是一个输出数组。

Whatever you put using put_line , you read using get_line ;无论您使用put_line放置什么,您都可以使用get_line读取; I believe this is how all these tools work, probably including the very SQL*Plus.我相信这就是所有这些工具的工作方式,可能包括 SQL*Plus。

Note that you need to call get_line enough times to exhaust the buffer.请注意,您需要多次调用get_line以耗尽缓冲区。 If you don't, the unread part will be overwritten by the next put_line .如果不这样做,未读部分将被下一个put_line覆盖。

Herby a code example based on redcayuga's first answer: Herby 基于 redcayuga 的第一个答案的代码示例:

def dbms_lines( cursor):
    status = cursor.var( cx_Oracle.NUMBER)
    line   = cursor.var( cx_Oracle.STRING)

    lines = []
    while True:
        cursor.callproc( 'DBMS_OUTPUT.GET_LINE', (line, status))
        if status.getvalue() == 0:
            lines.append( line.getvalue())
        else:
            break

    return lines

Then run it after calling your stored procedure with:然后在调用存储过程后运行它:

    for line in dbms_lines( cursor):
        log.debug( line)

Do not forget to call别忘了打电话

cursor.callproc("dbms_output.enable") 

before calling your actual procedure, otherwise the buffer will be empty.在调用您的实际过程之前,否则缓冲区将为空。

So building on the other two answers here, an example would be (proc_name is your procedure - schema.package.procedure):因此,基于此处的其他两个答案,一个示例是(proc_name 是您的过程 - schema.package.procedure):

def execute_proc(cursor,proc_name):
    cursor.callproc("dbms_output.enable")
    cursor.callproc(proc_name)
    for line in dbms_lines( cursor):
        print( line)

Did you tried this?你试过这个吗?

>>> conn = cx_Oracle.connect('user/pw@SCHEMA')
>>> cursor = conn.cursor()
>>> output = cursor.callproc("dbms_output.put_line", ['foo',])
>>> output
['foo']

The first argument is the procedure to call and the second a sequence of arguments or a dict for bindvars.第一个参数是要调用的过程,第二个参数是参数序列或绑定变量的字典。

see also: http://cx-oracle.sourceforge.net/html/cursor.html另见: http : //cx-oracle.sourceforge.net/html/cursor.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM