【问题标题】:Retrieving column names from ref cursor with cx_Oracle使用 cx_Oracle 从 ref 游标中检索列名
【发布时间】:2022-04-09 05:33:29
【问题描述】:

在使用 cx_Oracle 调用一个简单的存储过程时,我可以轻松地从过程中获取数据,如下所示:

db = db_class() #Sets up stuff, etc.
conn = db.connect() #Returns a connection to the database

cursor = conn.cursor()
l_results = cursor.var(cx_Oracle.CURSOR)

res = cursor.callproc("PROG.DATA.GET_EVENTS", [1,2,l_results]) 
#params = siteID, userID, ref cursor

res[2] 最终成为某种可枚举的对象,我可以像这样轻松地遍历:

data = [row for row in res[2]]

我最终得到了一个列表/元组列表,它为我提供了值,但我还需要列名。我尝试了以下方法:

cols = cursor.description if cursor.description is not None else [] #Returns None
cols = res[2].description if res[2].description is not None else [] 
#Returns an error. Same if l_results is used instead

如何从 l_results 中获取列名?我已经确定 l_results 是一个变量对象而不是游标,所以它不起作用。与 res[2] 相同。但我就是无法从 curs 中获取列。

这之后的 curs.description 似乎是一个 None 值,而它应该是一个 7 项元组的列表

我到底错过了什么?


编辑 1:我尝试将其从 callproc 更改为以下内容。同样的问题。

res = cursor.execute("BEGIN PROG.DATA.GET_EVENTS(:1,:2,:3); END;", {"1": 1,"2": 2,"3":, l_results})
cols = cursor.description #Returns None, again.

调用确实返回数据,所以我不确定为什么没有设置 description

【问题讨论】:

  • 来自官方文档:“Cursor.description - 这个只读属性是一个由 7 项序列组成的序列。这些序列中的每一个都包含描述一个结果列的信息:(name, type, display_size, internal_size, precision, scale, null_ok). This attribute will be None for operations that do not return rows or if the cursor has not h̲a̲d̲ ̲a̲n̲ ̲o̲p̲e̲r̲a̲t̲i̲o̲n̲ ̲i̲n̲v̲o̲k̲e̲d̲ ̲v̲i̲a̲ ̲t̲h̲e̲ ̲e̲x̲e̲c̲u̲t̲e̲(̲)̲ ̲m̲e̲t̲h̲o̲d̲ yet."
  • 试过了。添加了我尝试过的编辑。即使其他结果返回数据,结果游标中也没有数据。

标签: python cx-oracle


【解决方案1】:

引用游标的列可以从引用游标本身确定。给定如下过程:

create or replace procedure so50399550 (
    a_Input1            number,
    a_Input2            number,
    a_Output            out sys_refcursor
) is
begin
    open a_Output for
    select a_Input1 as num, a_Input1 * a_Input1 as square from dual
    union all
    select a_Input2, a_Input2 * a_Input2 from dual;
end;
/

Python代码可以如下:

refCursorVar = cursor.var(cx_Oracle.CURSOR)
cursor.callproc("so50399550", [1, 2, refCursorVar])
refCursor = refCursorVar.getvalue()
print("Rows:")
for row in refCursor:
    print(row)
print()
print("Column Info:")
for column in refCursor.description:
    print(column)
print()

但是,您可以使用以下代码更简单地完成此操作。您不必实际创建变量。可以直接绑定光标。

refCursor = conn.cursor()
cursor.callproc("so50399550", [1, 2, refCursor])
print("Rows:")
for row in refCursor:
    print(row)
print()
print("Column Info:")
for column in refCursor.description:
    print(column)
print()

可以在here找到样本。

【讨论】:

  • 该死的家伙,这实际上解决了我的问题。 cx_Oracle 网站上的文档确实没有说明这一点。谢谢。
  • 很高兴听到这个消息。是的,可以改进 cx_Oracle 的文档。 :-) 因为我是作者,所以我会把它当作一些建设性的批评...... :-)
  • 啊,公平。无论如何,它仍然是一个有用的模块,所以它没什么大不了的。祝你有美好的一天。
  • @AnthonyTuinga 非常感谢这个例子。此外,评论中的链接似乎不起作用(404)。干杯!
  • 我已删除该评论并在答案中添加了示例链接。
猜你喜欢
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多