SQL 删除孤儿
假设所有外键都有适当的约束,是否有一个简单的 SQL 语句来删除数据库中任何地方未引用的行?
像 delete from the_table
这样简单的事情,只需跳过带有子记录的任何行?
我试图避免手动循环表格或添加类似 where the_SK not in (a,b,c,d)
的内容。
Assuming that all foreign keys have the appropriate constraint, is there a simple SQL statement to delete rows not referenced anywhere in the DB?
Something as simple as delete from the_table
that simply skip any rows with child record?
I'm trying to avoid manually looping through the table or adding something like where the_SK not in (a,b,c,d)
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您也许可以使用 10g 中包含错误日志记录的扩展
DELETE
语句。首先使用 DBMS_ERRLOG 创建一个日志表(它只是原始表的副本,带有一些附加前缀列:
ORA_ERR_MESG$, ..., ORA_ERR_TAG$
)现在,您可以使用删除语句的 LOG ERRORS 子句来捕获具有现有完整性约束的所有行:
在这种情况下,“holding-breath”注释将进入
ORA_ERR_TAG$
列。您可以在此处阅读完整文档。
如果父表很大并且您只想删除一些杂散行,那么您最终会得到一个
parent_errlog
表,该表本质上是您的父表
的副本桌子。如果这不行,您将不得不做很长的路:You might be able to use the extended
DELETE
statement in 10g that includes error logging.First use
DBMS_ERRLOG
to create a logging table (which is just a copy of the original table with some additional prefixing columns:ORA_ERR_MESG$, ..., ORA_ERR_TAG$
)Now, you can use the LOG ERRORS clause of the delete statement to capture all rows that have existing integrity constraints:
In this case the "holding-breath" comment will go into the
ORA_ERR_TAG$
column.You can read the full documentation here.
If the parent table is huge and you're only looking to delete a few stray rows, you'll end up with a
parent_errlog
table that is essentially a duplicate of yourparent
table. If this isn't ok, you'll have to do it the long way:最简单的方法可能是编写一个应用程序或存储过程,尝试逐一删除表中的行,并简单地忽略由于外键约束而导致的失败。然后,所有不受外键约束的行都应该被删除。根据所需/可能的性能,这可能是一种选择。
The easiest way may be to write an application or stored procedure that attempts to delete the rows in the table one-by-one and simply ignores the failures due to foreign key constraints. Afterwards, all rows not under a foreign key constraint should be removed. Depending on the required/possible performance, this may be an option.
不,显然你可以这样做(但我意识到你宁愿不这样做):
No. Obviously you can do this (but I realise you would rather not):
一种方法是编写如下内容:
如果存在子行,则 DELETE 将失败,并且不会删除任何行,并且您可以继续处理下一个键。
请注意,如果您的表很大,这可能需要相当长的时间。
One way to do this is to write something like the following:
If a child row exists the DELETE will fail and no rows will be deleted, and you can proceed to your next key.
Note that if your table is large this may take quite a while.