首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以在一条语句中从两个表中删除条目吗?

问我可以在一条语句中从两个表中删除条目吗?
EN

Stack Overflow用户
提问于 2020-09-17 13:29:03
回答 1查看 150关注 0票数 3

我必须从两个表中各删除一行,它们由ID链接,但不具有正确的PK - FK关系(此db没有外键!)

这些表有一个假设的1-1关系。我不知道为什么他们不只是放在同一张桌子上,但我没有权利改变它。

人民

代码语言:javascript
复制
PersonId | Name | OwnsMonkey
----------------------------
    1       Jim       true
    2       Jim       false
    3       Gaz       true

信息

代码语言:javascript
复制
PersonId |    FurtherInfo
-----------------------------
    1       Hates his monkey
    2        Wants a monkey
    3       Loves his monkey

要决定删除什么,我必须找到一个用户名,以及它们是否拥有猴子:

代码语言:javascript
复制
Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false'

因此,我使用这个想法做两个单独的语句,先从Info中删除,然后从People中删除

代码语言:javascript
复制
delete from Info where PersonId = (Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false');

delete from People where PersonId = (Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false');

我找到了一个很有希望的答案,在StackOverflow上

代码语言:javascript
复制
delete      a.*, b.*
from        People a
inner join  Info b
where       a.People = b.Info
            and a.PersonId = 
            (Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false')

但是它在Server (2012)中出现语法错误,我也尝试过没有别名,但似乎不可能同时删除两个表

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-17 13:56:35

我可以在一条语句中从两个表中删除条目吗?

不是的。一条语句只能从中的一个表中删除行。

您所提到的关于MySQL和MySQL的答案确实允许用一条语句从几个表中删除,这在MySQL文档中可以看到。MS不支持这一点,在文档中可以看到这一点。Server中的DELETE语句中没有包含多个表的语法。如果尝试从视图中删除,而不是从表中删除,也有一个限制:

table_or_view_name引用的视图必须是可更新的,并且必须完全引用视图定义的FROM子句中的一个基表。

我希望避免在偶然的情况下使用两个单独的语句,而第二个语句由于任何原因而不起作用,中断-并发--真的,我想TRY/CATCH会很好地解决这个问题。

这就是事务的用途。您可以在一个事务中放置多个语句,要么所有语句都成功,要么所有语句都失败。要么全部要么什么都不做。

在您的情况下,您不仅可以,而且应该将两个DELETE语句放在一个事务中。

TRY/CATCH帮助以一种更可控的方式处理可能的错误,但是主要的概念是“事务”。

代码语言:javascript
复制
BEGIN TRANSACTION

delete from Info where PersonId = (Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false');

delete from People where PersonId = (Select PersonId from People where Name = 'Jim' and OwnsMonkey = 'false');

COMMIT

我强烈推荐阅读Erland的一篇伟大的文章SQL Server中的错误和事务处理。

如果你想变得狡猾,就像这样:

代码语言:javascript
复制
WITH
CTE
AS
(
    SELECT
        Info.PersonId AS ID1, People.PersonId AS ID2
    FROM
        Info
        INNER JOIN People ON Info.PersonId = People.PersonId
)
DELETE FROM CTE
WHERE ID1 = 1;

您将得到一个错误:

视图或函数“CTE”不能更新,因为修改会影响多个基表。

或者像这样:

代码语言:javascript
复制
WITH
CTE
AS
(
    SELECT
    PersonId
    FROM Info

    UNION ALL

    SELECT
    PersonId
    FROM People
)
DELETE FROM CTE
WHERE PersonId = 1;

您将得到另一个错误:

视图'CTE‘不能更新,因为定义包含一个UNION运算符。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63939131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档