【问题标题】:How to delete large quantity of records from Oracle Table that has no primary key如何从没有主键的Oracle表中删除大量记录
【发布时间】:2019-02-21 16:31:22
【问题描述】:

情况:我正在将整个 SQL 表加载到我的程序中。为方便起见,我使用 pandas 来维护行数据。然后,我正在创建一个我想从 SQL 表中删除的行的数据框。不幸的是(我不能改变这个)除了内置的 Oracle ROWID(它不是一个真正的表列,它是一个伪列)之外,该表没有任何主键,但我可以如果需要,将 ROWID 作为我的数据框的一部分。

该表有数十万行,我可能会在每次运行程序时删除几千条记录。

问题: 使用 Cx_Oracle 删除没有主键的多行/记录的最佳方法是什么?我不认为创建一个循环来提交数千个删除语句是非常有效的或 Pythonic。虽然我担心构建一个以 ROWID 为键并包含包含数千个项目的子句的单个 SQL 删除语句:

Where ROWID IN ('eg1','eg2',........, 'eg2345')

这种担忧有效吗?有什么建议吗?

【问题讨论】:

  • 我并不特别了解 CX-Oracle,但我过去在 TSQL 中生成过非常大量的类似“IN”子句并且从未遇到过问题。我说试试看。 . .如果有限制,则可能很大,因此您可以将代码更改为一次执行 1024 次(或施加任何限制)。

标签: python pandas cx-oracle


【解决方案1】:

使用 ROWID

既然您可以使用ROWID,那将是理想的方式。并且根据 Oracle 版本的不同,查询长度限制可能足够大,可以满足 IN 子句中包含这么多元素的查询。问题在于IN 表达式列表 - limited to 1000 中的元素数量

因此,您要么必须一次将 RowID 列表分成 1000 个一组,要么一次只删除一行;有或没有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 子句中指定所有列,并且一次执行多行,它们需要被 OR'd 在一起:

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 后创建它参数化。不确定限制是什么。)executemany() 方式绝对更容易编写和执行,但为了速度,单个大型查询(以上两个中的任何一个)都可能在数千个项目上胜过 executemany。

【讨论】:

  • 感谢您澄清情况!
【解决方案2】:

您可以使用 cursor.executemany() 一次删除多行。像下面这样的东西应该可以工作:

dataToDelete = [['eg1'], ['eg2'], ...., ['eg2345']]
cursor.executemany("delete from sometable where rowid = :1", dataToDelete)

【讨论】:

    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 2021-02-04
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多