【问题标题】:pyodbc python linux iSeriesAccess driver - stored procedure - capture output parameters?pyodbc python linux iSeriesAccess 驱动程序-存储过程-捕获输出参数?
【发布时间】:2018-02-15 13:42:55
【问题描述】:

我已经阅读了几个讨论这个问题的线程 - 但是 - 没有找到一个似乎首先适合我的用例的选项。

Linux (RHEL 7.x)
- IBM iSeriesAccess 驱动程序
- 连接到 AS/400
- Python/pyodbc(ibm_db 似乎不支持 iSeriesAccess 驱动程序)

调用存储过程——调用效果很好——数据按预期返回。问题是这是一组已经存在多年并且也被其他系统使用的程序,而其他系统(即 SQL Server)能够正确检索输出参数,我们发现这对 pyodbc 来说是一个挑战.

使用一个非常基本的脚本来描述这一点——结果集中只有预期的数据行——而不是输出参数(这是我在其他线程上看到的用于捕获输出参数的示例。

import pyodbc

connection = pyodbc.connect("dsn=DEV; UID=USER; PWD=PASSWD")
if connection:
   crsr = connection.cursor()

   # PARM 2 is an OUTPUT parameter type
   parms = (23,0)
   crsr.execute("{CALL GET_DATA(?, ?)}", parms)

   rows = crsr.fetchall()
   while rows:
        print(rows)
        if crsr.nextset():
           rows = crsr.fetchall()
        else:
           rows = None
else:
   print connection
   print "error connection"

【问题讨论】:

  • 您是否尝试过使用类似于here 描述的匿名代码块?
  • 存储过程方面的代码块?如果这是所提到的上下文,那就是一个问题,因为我们有其他几个系统使用的程序,我们无法修改。
  • 不,只是您从 Python 脚本执行的一段代码。它不修改存储过程,而是调用存储过程,然后使用 SELECT 语句将输出参数作为单行结果集返回。
  • 我会看看我是否可以通过 CLP/CLI for AS400 支持的 DB2 语法创建设置 --
  • 此时我还没有找到一个可支持的选项,让匿名代码块可以与 DB2 (i5) 一起使用。返回的一般错误是 pyodbc.Error: ('HY000', u'[HY000] [IBM][System i Access ODBC Driver]Error in host server data stream. (30187) (SQLPrepare)') Fails -- sql=" ""\ BEGIN CALL GET_MSTR_ALMSTP(23, ?); END """ 工作 --- sql= """\CALL GET_MSTR_ALMSTP(23, ?); """

标签: linux ibm-midrange pyodbc db2-400


【解决方案1】:

所以看起来 PyODBC 没有实现callproc。他们确实记录了 way 以绕过某些数据库的此限制,但这不适用于 Db2。我能看到获取值的唯一方法是使用全局变量:

import pyodbc

connection = pyodbc.connect("dsn=DEV; UID=USER; PWD=PASSWD")
if connection:
   crsr = connection.cursor()

   crsr.execute("create or replace variable out_parm integer default 0"))

   crsr.execute("call GET_DATA(?, out_parm)", (23,))

   rows = crsr.fetchall()
   while rows:
        print(rows)
        if crsr.nextset():
           rows = crsr.fetchall()
        else:
           rows = None

   crsr.execute("values(out_parm)")
   print(crsr.fetchall())
else:
   print connection
   print "error connection"

原答案:

您需要使用callproc 而不是execute

import pyodbc

connection = pyodbc.connect("dsn=DEV; UID=USER; PWD=PASSWD")
if connection:
   crsr = connection.cursor()

   # PARM 2 is an OUTPUT parameter type
   parms = (23,0)
   out_parms = crsr.callproc("GET_DATA", parms)

   rows = crsr.fetchall()
   while rows:
        print(rows)
        if crsr.nextset():
           rows = crsr.fetchall()
        else:
           rows = None
else:
   print connection
   print "error connection"

【讨论】:

  • .callproc 方法是可选的,pyodbc 没有实现它。
  • @GordThompson,你是对的。我没有意识到 PyODBC 没有实现输出参数支持。我已经用一种方法更新了我的答案,但是如果您没有创建全局变量的权限,它并不完全漂亮并且可能不容易实现。
猜你喜欢
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2018-09-21
  • 1970-01-01
相关资源
最近更新 更多