下面是代码。在迭代字典时,代码多次查询。多次执行查询或对数据库执行Ping操作是最佳做法吗?
import cx_Oracle
connDev = 'username/password@hostname:port/service'
connDev = cx_Oracle.connect(connDev)
cursor = connDev.cursor()
d = {'2006': '20170019201',
'2006172': '2017000002',
'200617123': '200003'
}
for key,value in d.items():
cursDev.execute('SELECT columnName from tableName where columnName={}'.format(key))
if len(cursDev.fetchall())!=0:
# cursDev.execute('UPDATE tableName SET columnName= {0} WHERE columnName= {1} '.format(value, key))
else:
continue
connDev.commit()
cursDev.close()
connDev.close()
答案 0 :(得分:0)
您可以运行一个查询并获得所有内容:
cursDev.execute(
'SELECT columnName FROM tableName WHERE columnName IN ({})'.format(
','.join(':p{}'.format(n) for n in range(len(d))),
{'p{}'.format(n): k for n, k in enumerate(d)}
)
或直接运行更新-如果找不到该行,它们将不执行任何操作:
for k, v in d.items():
cursDev.execute(
'UPDATE tableName SET columnName = {} WHERE columnName = :value',
{'value': v}
)
请注意,两个示例都在使用参数化查询-数据与查询分开传递,并且数据库的工作是进行参数插值-这样除使性能更好外,还使您摆脱了报价地狱并自动防止注入。
代码使用:value
个命名型参数占位符,因为cx_Oracle
使用的是占位符-请参见documentation on cx_Oracle.paramstyle
。
答案 1 :(得分:0)
对于这样的“批处理”更新,executemany()
调用将是最有效的方法。
正如@nosklo所指出的,SELECT调用不是必需的-它们只需要时间。而且,使用executemany()
,您无需重复进行execute()
的呼叫,这又是一个节省。
来自samples/ArrayDMLRowCounts.py
:
# delete the following parent IDs only
parentIdsToDelete = [20, 30, 50]
print("Deleting Parent IDs:", parentIdsToDelete)
print()
# enable array DML row counts for each iteration executed in executemany()
cursor.executemany("""
delete from ChildTable
where ParentId = :1""",
[(i,) for i in parentIdsToDelete],
arraydmlrowcounts = True)
# display the number of rows deleted for each parent ID
rowCounts = cursor.getarraydmlrowcounts()
for parentId, count in zip(parentIdsToDelete, rowCounts):
print("Parent ID:", parentId, "deleted", count, "rows.")
有关更多示例,请参见Efficient and Scalable Batch Statement Execution in Python cx_Oracle,包括那些具有多个绑定的示例。
[绝不(特殊情况除外)通过串联字符串来构建SQL语句。这是一个安全漏洞,也可能导致性能下降。始终使用绑定变量]