下面是代码。在迭代字典的过程中,代码会多次查询。执行查询或多次Pinging数据库是最佳实践吗?
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()
发布于 2018-07-11 01:06:11
您可以运行单个查询并获取所有内容:
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
。
发布于 2018-07-11 08:14:35
对于像这样的“批处理”更新,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语句。这是一个安全漏洞,而且性能也很差。始终使用绑定变量
https://stackoverflow.com/questions/51269817
复制相似问题