2015-10-19 65 views
2

在SQLServer表中,我想將colB中的值更新爲transformColumn(colA),其中transformColumn是一個我不想轉換爲SQL的python函數。 我嘗試下面的代碼,但顯然我不能以這種方式在同一時間查詢和更新:在pyodbc中更新一列作爲另一個Python函數

Error: ('HY000', '[HY000] [Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt (0) (SQLExecDirectW)') 

我如何能實現我的目標是什麼?

import pyodbc 

def transformColumn(colValue): 
    #complicated transformation that I don't want to do in SQL here 

cs = 'DRIVER={SQL Server};Server=mySvr;Database=myDB;Trusted_Connection=Yes;' 
cn = pyodbc.connect(cs, autocommit=True) 

sqlSelect = """ 
    SELECT id, colA 
    FROM myTable  
""" 

sqlUpdate = """ 
    UPDATE myTable 
    SET colB=? WHERE id=? 
""" 

csrSelect = cn.cursor() 
rows = csrSelect.execute(sqlSelect) 
csrUpdate = cn.cursor() 

row = csrSelect.fetchone() 
while row is not None: 
    colB = transformColumn(row.colA) 
    csrUpdate.execute(sqlUpdate, colB, row.id)  
    row = csrSelect.fetchone() 

csrSelect.close() 
csrUpdate.close() 
cn.close() 
+0

我剛剛意識到我可以通過在不同的連接上運行更新來完成這項工作,但我想知道是否有更好的甚至根本不同的連接做法。 – Lobert

回答

1

將在myTable數據總是足夠小,以適應在內存中執行了這段代碼的機器上(例如總是小的查找表,還是會隨時間持續增長)?

閱讀myTable行到使用Cursor.fetchall()從而釋放光標爲使用UPDATE

# starting line 19 in the code sample 
csr = cn.cursor() 
# this creates a list of pyodbc.Row objects, 
# freeing the cursor for update statement execution 
rows = csr.execute(sqlSelect).fetchall() 
for row in rows: 
    colB = transformColumn(row.colA) 
    csr.execute(sqlUpdate, colB, row.id)  
cn.commit() 

沒有

至於你提到的列表,使用單獨的連接用於select和update語句。對於大量數據,這將比上述表現好得多。它需要管理兩個連接和遊標對象,因爲更新將在遍歷選擇遊標時執行。

# starting at line 7 in the code sample 
cnSelect = pyodbc.connect(cs, autocommit=True) 
cnUpdate = pyodbc.connect(cs, autocommit=True) 

sqlSelect = """ 
    SELECT id, colA 
    FROM myTable  
""" 

sqlUpdate = """ 
    UPDATE myTable 
    SET colB=? WHERE id=? 
""" 

csrSelect = cnSelect.cursor() 
csrUpdate = cnUpdate.cursor() 
rows = csrSelect.execute(sqlSelect) 
for row in rows: 
    colB = transformColumn(row.colA) 
    csrUpdate.execute(sqlUpdate, colB, row.id)  
cnUpdate.commit() 
1

以下方法可能是一個可行的選擇,如果有在[可樂]的索引:

crsr = cnxn.cursor() 
crsr.execute("SELECT DISTINCT colA FROM myTable") 
aList = [item[0] for item in crsr.fetchall()] 
for aValue in aList: 
    crsr.execute("UPDATE myTable SET colB=? WHERE colA=?", (transformColumn(aValue), aValue)) 
crsr.close() 
cnxn.commit() 

如果有,因爲變換是在[可樂]重複值那將是特別有用只計算併爲每個獨特的[可樂]值

-1

的簡單解決方案是使用光標施加一次,

cnxn = pyodbc.connect("YOUR SERVER DETAILS, CREDENTIALS") 
cursor = cnxn.cursor() 

query1 = "SELECT * FROM myTable1" 
cursor.execute(query1) 

query2 = "SELECT * FROM myTable2" 
cursor.execute(query2) 

這種方式你不需要在同一個程序中有多個連接,

相關問題