我有一个我在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()
理想情况下,我希望避免以这种方式使用连接对象,并在让SqlAlchemy管理游标的同时执行该过程。如果那是不可能的,那么抓取是否需要这么长时间?
谢谢,
扎克
答案 0 :(得分:0)
我看到这个问题没有得到回答,所以我决定跳进去。首先,让我说,对于您的情况,没有比SYS_REFCURSOR更好的选择了。当然,您还有其他选择。
Oracle游标是一个存储区位置,用于存储执行SQL语句的指令。 Ref游标只是指向游标位置的指针。 SYS_REFCURSOR是由oracle定义的特定类型的ref游标。因此,当您将SYS_REFCURSOR变量返回给客户端时,您将返回一个指向执行SQL的指令所在的内存位置的指针。您的客户现在可以使用FETCH操作执行指令并获取行。因此,这是将结果集返回给客户端的最佳方法。
作为替代,您可以使用PIPELINED FUNCTION,但是我可以向您保证,您不会获得任何更好的性能。 AskTom在本文中对此比较有很好的解释
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532870400346178516
另一种情况是您是否要分析在EXECUTE阶段或FETCH阶段消耗时间的位置。如果您在FETCH中花费大量时间,也许您可以考虑以另一种方式将数据传输到客户端。如果您在执行方面遇到问题,则需要对过程进行调优练习。