执行使用SqlAlchemy返回REF CURSOR的Oracle存储过程

zmo*_*ser 7 oracle stored-procedures sqlalchemy

我有一个我在Oracle中定义的存储过程.在那个过程中,我需要返回一个记录集.要做到这一点,我使用的是SYS_REFCURSOR,在Oracle内部(和cx_Oracle,在这个问题上)很好用.在我的应用程序中,我使用SqlAlchemy作用域会话,以支持多线程.

如何使用作用域会话返回REF CURSOR?我能够使其工作的唯一方法是使用在会话中处于活动状态的光标声明一个out游标,然后执行存储过程,如下所示:

sql = """
    BEGIN
        example('%s', '%s', '%s', :cur);
    END;
""" % (cid, show, type)

conn = sa_tool.session.connection()
in_cur = conn._Connection__connection.cursor()
out_cur = conn._Connection__connection.cursor()
in_cur.execute(sql, cur=out_cur)
results = out_cur.fetchall()
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望避免以这种方式使用连接对象,并在让SqlAlchemy管理游标的同时执行该过程.如果那是不可能的,那么获取这么长时间是否有理由?

谢谢,

扎克

Rob*_*dez 0

我看到这个问题没有得到回答,我决定跳进去。首先,我想说的是,对于你的场景来说,没有比 SYS_REFCURSOR 更好的选择了。当然,你还有其他选择。

Oracle 游标是存储执行 SQL 语句的指令的内存区域位置。参考光标只是指向光标位置的指针。SYS_REFCURSOR 是 Oracle 定义的特定类型的引用游标。因此,当您将 SYS_REFCURSOR 变量返回给客户端时,您将返回一个指向执行 SQL 的指令所在内存位置的指针。您的客户端现在可以使用 FETCH 操作执行指令并获取行。所以这是向客户端返回结果集的最佳方式。

作为替代方案,您可以使用管道函数,但我可以向您保证,您不会获得任何更好的性能。AskTom 在这篇文章中对这种比较有很好的解释

https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532870400346178516

另一种情况是您是否想分析时间消耗在哪里,是在 EXECUTE 阶段还是在 FETCH 阶段。如果您在 FETCH 上花费了大量时间,也许您可​​能会考虑以其他方式将数据传输到客户端。如果您在执行中遇到问题,那么您需要对您的过程进行调整。