【问题标题】:pyodbc cursor's rollback functionalitypyodbc 游标的回滚功能
【发布时间】:2019-09-06 01:07:24
【问题描述】:

使用 pyodbc 我正在更新三个数据库表。更新最后一个表时遇到错误,我正在调用 rollback() 函数。即使在 rollback() 上,第二个表也会保留其更新的值;第一个和第三个表没有按预期更新。为什么它会这样?

dbCursor.execute("insert into table1(item11, item12, item13, item14, item15, item16) values(?,?,?,?,?,?)", value1, value2, value3, value4, value5, value6)

dbCursor.execute("update into table2(item21, item22, item23, item24, item25, item26) values(?,?,?,?,?,?)", value1, value2, value3, value4, value5, value6)
---> two rows in the table get updated

dbCursor.execute("select item from table2 where unit_no = ?", unit_number)

tempVal = dbCursor.fetchone()

dbCursor.execute("update table3 set item31=?, item32=? where unit=?", val1, val2, tempVal)
---> Nothing gets updated as there is no tempVal found

if dbCursor.rowcount is 0:
    dbCursor.rollback()

预计rollback()会导致三个表都回滚,但是table2保留了值。

connection.getinfo(pyodbc.SQL_DRIVER_NAME)  --> iclit09b.dll
connection.getinfo(pyodbc.SQL_DRIVER_VER)   --> 4.10.FC4DE

【问题讨论】:

  • edit您的问题包含connection.getinfo(pyodbc.SQL_DRIVER_NAME)connection.getinfo(pyodbc.SQL_DRIVER_VER)返回的值
  • Informix 数据库是否支持事务?您的连接是否关闭了自动提交?
  • 大概你的意思是insert into table2而不是update into table2?该语法适用于 INSERT 语句,但您使用的是 update 而不是 insert
  • 您在 INSERT 语句中有匿名列 itemNN;您使用以前未识别的unit_number 进行选择。这些是如何联系在一起的?为什么新数据要与单元号匹配?
  • 可能 AutoCommit 设置为 true,这意味着您执行的每个 .execute 都会被提交。尝试在第一个 .execute 之前设置“autocommit(conn, 0)”。或在连接字符串中将其设置为关闭。更多信息在这里:github.com/mkleehammer/pyodbc/wiki/Connection

标签: odbc pyodbc informix


【解决方案1】:

使用 'autocommit = False' 的快速测试显示回滚工作正常:

使用以下命令创建测试表:

informix@irk:/data/informix/IBM/OpenInformix/pyodbc# cat p.sql
drop table table1;
drop table table2;
drop table table3;
create table table1(item11 integer, item12 integer, item13 integer, item14 integer, item15 integer, item16 integer)     ;
create table table2(item11 integer, item12 integer, item13 integer, item14 integer, item15 integer, item16 integer)     ;
create table table3(item31 integer, item32 integer, item13 integer, unit integer, item15 integer, item16 integer)       ;
insert into  table2 values (1,1,1,1,1,1);
insert into  table2 values (1,1,1,1,1,1);

informix@irk:/data/informix/IBM/OpenInformix/pyodbc# dbaccess stores7 p
Database selected.
Table dropped.
Table dropped.
Table dropped.
Table created.
Table created.
Table created.
1 row(s) inserted.
1 row(s) inserted.
Database closed.
informix@irk:/data/informix/IBM/OpenInformix/pyodbc# 

'table2' 的两行都有“1,1,1,1,1,1”

下面的python代码将输出'table2'中的数据,关闭AutoCommit并尝试更新。

informix@irk:/data/informix/IBM/OpenInformix/pyodbc# cat p.py 
import pyodbc

cnxn = pyodbc.connect('DSN=irk1210')
dbCursor = cnxn.cursor()

value1          = "2"
value2          = "2"
unit_number     = "1"
val1            = "2"
val2            = "2"
tempVal         = "2"

print("before update")
dbCursor.execute("select item11,item12 from table2")
row = dbCursor.fetchone()
if row:
    print(row)

#Set AutoCommit off
cnxn.autocommit = False

dbCursor.execute("insert into table1(item11, item12) values (?,?)", value1, value2)
dbCursor.execute("update table2 set item11=?, item12=?", value1, value2)

print("after update")
dbCursor.execute("select item11,item12 from table2")
row = dbCursor.fetchone()
if row:
    print(row)

dbCursor.execute("select item11 from table2 where item12 = ?", unit_number)
tempVal = dbCursor.fetchone()
dbCursor.execute("update table3 set item31=?, item32=? where unit=?", val1, val2, tempVal)
if dbCursor.rowcount is 0:
    dbCursor.rollback()

print("after rollback")
dbCursor.execute("select item11,item12 from table2")
row = dbCursor.fetchone()
if row:
    print(row)

informix@irk:/data/informix/IBM/OpenInformix/pyodbc# 

输出:

informix@irk:/data/informix/IBM/OpenInformix/pyodbc# python3 p.py 
before update
(1, 1)
after update
(2, 2)
after rollback
(1, 1)
informix@irk:/data/informix/IBM/OpenInformix/pyodbc# 

最后一个选择显示更新操作已按预期回滚。 两行的值和更新前一样(1,1)

【讨论】:

  • 谢谢,rollback() 对某些表有效。我重新检查了“SQL_TXN_CAPABLE”,它给了我 2 的值。即 SQL_TC_ALL = 2 - 事务可以包含 DML 和 DDL 语句。表 1 按预期工作,表 2 有问题,可能是表 2 是不同类型的表(ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.admin.doc/…)。知道如何检查表格的类型吗?
  • 嗯。你是说你可以回滚table1但不能回滚table2?尝试获取表的schema(dbschema -d database -t table)
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 2018-05-18
  • 2017-07-06
  • 1970-01-01
  • 2013-04-16
  • 2017-05-02
  • 2011-11-07
  • 2022-01-23
相关资源
最近更新 更多