使用ROWID
因为您可以使用ROWID,所以这是一种理想的方法。根据Oracle版本的不同,查询长度限制可能足够大,以满足在IN子句中包含那么多元素的查询。问题是IN表达式列表-limited to 1000中元素的数量。你知道吗
因此,您要么一次将rowid列表分解为1000个行,要么一次只删除一行;有executemany()或没有executemany()。你知道吗>>> len(delrows) # rowids to delete
5000
>>> q = 'DELETE FROM sometable WHERE ROWID IN (' + ', '.join(f"'{row}'" for row in delrows) + ')'
>>> len(q) # length of the query
55037
>>> # let's try with just the first 1000 id's and no extra spaces
... q = 'DELETE FROM sometable WHERE ROWID IN (' + ','.join(f"'{row}'" for row in delrows[:1000]) + ')'
>>> len(q)
10038
您可能在查询长度限制内,甚至可以使用最小的','项分隔符保存一些字符。你知道吗
没有ROWID
如果没有主键或ROWID,标识每一行的唯一方法是指定WHERE子句中的所有列,并且要一次执行多行操作,需要将它们放在一起:DELETE FROM sometable
WHERE ( col1 = 'val1'
AND col2 = 'val2'
AND col3 = 'val3' ) row 1
OR ( col1 = 'other2'
AND col2 = 'value2'
AND col3 = 'val3' ) row 2
OR ( ... ) etc
正如您所看到的,它不是构造的最好的查询,但是允许您在没有rowid的情况下进行。你知道吗
在这两种情况下,您可能不需要使用参数化查询,因为1中的IN列表或2中的OR分组是可变的。(是的,您可以在使用数千个参数构建整个扩展SQL之后创建参数化的SQL。executemany()方法确实更易于编写和执行,但是为了提高速度,单个大型查询(以上两种查询中的任何一种)的性能可能会比executemany好几千项。你知道吗