【问题标题】:cx_Oracle: select query following an insert produces no resultcx_Oracle:插入后的选择查询不产生结果
【发布时间】:2022-07-28 08:22:20
【问题描述】:

在我的 python 代码中,我将一个值插入到一个表中。

在表中,有一个序列会自动分配一个ID。

插入后,我想把它放回我的 python 应用程序:

import cx_Oracle, sys
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
                with conn.cursor() as cur:
                    cur.execute("Insert into my_table columns(data) values ('Hello')") 
                    conn.commit()

with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
           with conn.cursor() as cur:
               r = cur.execute("select id from my_table where data = 'Hello'") 
               print(r)       
               if r is None:
                  print("Cannot retrieve ID")
                  sys.exit()

不幸的是,结果集r 始终为“无”,即使该值已正确插入(通过 sqldeveloper 检查)。

我做错了什么? 我什至打开了一个新连接,以确保获得价值......

【问题讨论】:

    标签: python cx-oracle


    【解决方案1】:

    在为 SELECT 语句调用 execute() 后,您需要调用 fetchone()fetchmany()fetchall(),如 cx_Oracle 文档 SQL Queries 中所示。

    或者你可以使用迭代器:

    with connection.cursor() as cursor:
        try:
    
            sql = """select systimestamp from dual"""
            for r in cursor.execute(sql):
                print(r)
    
            sql = """select 123 from dual"""
            (c_id,) = cursor.execute(sql).fetchone()
            print(c_id)
    
        except oracledb.Error as e:
            error, = e.args
            print(sql)
            print('*'.rjust(error.offset+1, ' '))
            print(error.message)
    

    但是,要在不产生额外 SELECT 开销的情况下返回自动生成的 ID,您可以将 INSERT 语句更改为使用 RETURNING INTO 子句。 cx_Oracle 文档DML RETURNING Bind Variables 中有一个示例显示了更新。您可以在 INSERT 中使用类似的语法。

    附表:

    CREATE TABLE mytable
      (myid NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
       mydata VARCHAR2(20));
    

    您可以像这样插入并获取生成的密钥:

    myidvar = cursor.var(int)
    sql = "INSERT INTO mytable (mydata) VALUES ('abc') RETURNING myid INTO :bv"
    cursor.execute(sql, bv=myidvar)
    i, = myidvar.getvalue()
    print(i)
    

    如果您只需要一个唯一标识符,则无需绑定变量即可获得插入行的 ROWID。执行 INSERT 后简单访问 cursor.lastrowid

    【讨论】:

      猜你喜欢
      • 2020-02-25
      • 2015-09-23
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多