Pyodbc游标的回滚功能

时间:2019-09-06 01:07:24

标签: odbc pyodbc informix

使用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

1 个答案:

答案 0 :(得分: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)相同