使用单个查询(SQL Express 2005)和WHERE条件从多个表中删除行

33

这是我正在使用的查询:

 DELETE TB1.*, TB2.*
   FROM TB1
        INNER JOIN TB2 ON TB1.PersonID = TB2.PersonID 
  WHERE (TB1.PersonID)='2'

在MS Access中它运行良好,但在SQL Server Express 2005中出现错误(“附近有语法错误','”)。

如何解决?请帮忙。


2
这在SQL Server 2012或2014中现在是否可行?我的课程项目中有一组构造混乱的表,同时在两个表上都有ON DELETE RESTRICT约束。我不想再问一个问题,因为那将是重复的。 - trysis
我认为在SQL Server中仍不支持此功能。 - Jack Casas
16个回答

22

在SQL 2005或任何其他标准的SQL中,都不能使用单个表达式从多个表中DELETE - Access是此类情况下的例外。

获得此效果的最佳方法是在表之间指定FOREIGN KEYS,并使用ON DELETE trigger


这一定是为什么我在分隔表格的逗号处得到了“语法错误”DELETE table1,table2'。附近有语法错误','。 - Rich
它在MariaDB中运行。DELETE t1,t2 FROM t1 JOIN t2 ON t2.id = t1.t2_id WHERE t1.id ='5' - Nexarius

13

为什么不使用 DELETE CASCADE FK


4
为什么您不详细阐述一下您的答案呢? - Jan Köhler

4
这不能在一条语句中完成。您需要使用两个语句。
DELETE FROM TB1 WHERE PersonID = '2';
DELETE FROM TB2 WHERE PersonID = '2';

2

据我所知,你不能在一句话中完成这个操作。

但是你可以建立一个存储过程,在一个事务中执行你想要删除的任何表中的内容,这几乎是相同的。


1

我认为你不能一次从多个表中删除(尽管我不确定)。

然而,对我来说,最好的方法是使用级联删除关系来实现这种效果。如果你这样做,你将能够从一个表中删除记录,另一个表中的记录将自动删除。

例如,假设这两个表代表一个客户和客户的订单。如果你设置了级联删除关系,你只需删除客户表中的记录,订单将自动被删除。

请参阅MSDN文档级联引用完整性约束


1

为细节表指定外键,该外键引用主表的主键,并设置删除规则=级联。

现在,当您从主表中删除记录时,基于删除行的主键值的所有其他详细信息表记录将自动删除。

因此,在这种情况下,主表的单个删除查询可以同时删除主表数据和子表数据。


1

在过程中使用此代码

declare cu cursor for SELECT [name] FROM sys.Tables where [name] like 'tbl_%'
declare @table varchar(100)
declare @sql nvarchar(1000)

OPEN cu  
FETCH NEXT FROM cu INTO @table 

WHILE @@FETCH_STATUS = 0  
BEGIN  
    set @sql = N'delete from ' + @table
    EXEC sp_executesql @sql
    FETCH NEXT FROM cu INTO @table 
END   
CLOSE cu;  
DEALLOCATE cu;

1

我不确定为什么有些人把这件事情搞得那么复杂。实际上,我们是可以从多个表中删除行的。以下是我的查询语句,已经经过验证可行。

$sql = "DELETE clients, equine_notes, client_horses FROM clients INNER JOIN client_horses ON client_horses.cID = clients.id INNER JOIN equine_notes ON equine_notes.cID = clients.id WHERE clients.id = '".$cID."'";

客户表包含客户的姓名。client_horses是客户拥有的多匹马的多行记录,equine_notes是我对特定马匹做出的注释。使用INNER JOIN子句,我可以使用一个查询语句删除与该客户相关的所有内容。

希望这可以帮助到您。


0
通常我会使用一个查询从多个表中进行删除。 在PostgreSQL中可以正常工作,但在MSSQL中无法正常工作,这就是我来到这里的原因。
在Postgres中(我不知道其他数据库),您可以执行以下操作:
WITH obsolete_ids AS (
    SELECT pr_r."ID" AS ids
    FROM "PULL_REQUEST" pr_r
    WHERE 1=1
    AND pr_r."STATUS" IN (1)
) , del_commit_junc AS (
DELETE 
FROM "PR_TO_COMMIT"
WHERE "REQUEST_ID" IN (SELECT ids FROM obsolete_ids)
)
DELETE
FROM "PULL_REQUEST" pr_out
WHERE pr_out ."ID" IN (SELECT ids FROM obsolete_ids)

实际上,在我的原始查询中,我删除了另外两个表中的外键,但在这里我只粘贴了一个示例。这样我解决了“PR_TO_COMMIT”表中的外键问题。


0
我在SQL Server中删除多个表中的行的方法是什么? 最重要的是在创建表时使用on delete cascade来设置外键。
#Table 1 Create:# 
    
create table Customer_tbl 
(
C_id int primary key, 
C_Name varchar(50), 
C_Address varchar(max), 
City varchar(50)
);


#Table 2: Create with Foreign Key Constraints#

create table [order] 
(
Ord_Id int primary key, 
Item varchar(50), 
Quantity int, 
Price_Of_1 int, 
C_id int foreign key references Customer_tbl(C_id)
on delete cascade

);

delete from Customer_tbl where C_id = 2;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接