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

Posted

技术标签:

【中文标题】使用带有 WHERE 条件的单个查询 (SQL Express 2005) 从多个表中删除行【英文标题】:Delete rows from multiple tables using a single query (SQL Express 2005) with a WHERE condition 【发布时间】:2009-11-11 11:18:02 【问题描述】:

这是我正在使用的查询:

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

它在 MS Access 中运行良好,但在 SQL Server Express 2005 中出现错误(',' 附近的语法不正确)。

如何解决?请帮忙。

【问题讨论】:

SQL Server 2012 或 2014 现在可以实现吗?我的班级项目有一组可怕的表,它同时在两个表上都有 ON DELETE RESTRICT 约束。我不想问另一个问题,因为这会是这个问题的欺骗。 【参考方案1】:

您不能在多个表中使用SQL 2005 中的单个表达式来DELETE - 或任何其他标准SQL。 Access 是这里的例外。

获得此效果的最佳方法是在表之间指定FOREIGN KEYSON DELETE trigger

【讨论】:

这一定是为什么我在分隔表 'DELETE table1, table2' 的逗号上收到“不正确的语法错误”,',' 附近的语法不正确。 它在 MariaDB 中工作。 DELETE t1, t2 FROM t1 JOIN t2 ON t2.id = t1.t2_id WHERE t1.id = '5'【参考方案2】:

为什么不使用DELETE CASCADE FK

【讨论】:

【参考方案3】:

这不能在一个语句中完成。您将不得不使用 2 个语句

DELETE FROM TB1 WHERE PersonID = '2';
DELETE FROM TB2 WHERE PersonID = '2';

【讨论】:

【参考方案4】:

据我所知,你不能用一句话来做到这一点。

但是您可以构建一个存储过程,在事务中的任何表中执行您想要的删除操作,几乎相同。

【讨论】:

【参考方案5】:

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

但是,在我看来,最好使用级联删除的关系来实现此效果。如果您这样做,您将能够从一个表中删除记录,而另一个表中的记录将被自动删除。

例如,假设这两个表代表一个客户,以及客户的订单。如果将关系设置为级联删除,只需删除客户表中的记录,订单就会自动删除。

请参阅 cascading referential integrity constraints 上的 MSDN 文档。

【讨论】:

【参考方案6】:

为引用master主键的明细表指定外键并设置Delete rule = Cascade。

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

所以在这种情况下,主表的单个删除查询可以删除主表数据以及子表数据。

【讨论】:

【参考方案7】:

在程序中使用它

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;

【讨论】:

【参考方案8】:

我用它来清理测试/开发数据库中的数据。您可以按表名和记录数进行过滤。

DECLARE @sqlCommand VARCHAR(3000);
DECLARE @tableList TABLE(Value NVARCHAR(128));
DECLARE @TableName VARCHAR(128);
DECLARE @RecordCount INT;

-- get a cursor with a list of table names and their record counts
DECLARE MyCursor CURSOR FAST_FORWARD
FOR SELECT t.name TableName,
           i.rows Records
    FROM sysobjects t,
         sysindexes i
    WHERE 
          t.xtype = 'U'              -- only User tables
          AND i.id = t.id          
          AND i.indid IN(0, 1)       -- 0=Heap, 1=Clustered Index
          AND i.rows < 10            -- Filter by number of records in the table
          AND t.name LIKE 'Test_%';  -- Filter tables by name. You could also provide a list:
                                     -- AND t.name IN ('MyTable1', 'MyTable2', 'MyTable3');
                                     -- or a list of tables to exclude:
                                     -- AND t.name NOT IN ('MySpecialTable', ... );

OPEN MyCursor;

FETCH NEXT FROM MyCursor INTO @TableName, @RecordCount;

-- for each table name in the cursor, delete all records from that table:
WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sqlCommand = 'DELETE FROM ' + @TableName;
        EXEC (@sqlCommand);
        FETCH NEXT FROM MyCursor INTO @TableName, @RecordCount;
    END;

CLOSE MyCursor;
DEALLOCATE MyCursor;

参考信息:

sysobjects sysindexes SQL Server Cursors

【讨论】:

【参考方案9】:

你可以使用类似下面的东西:

DECLARE db_cursor CURSOR FOR  
SELECT name 
FROM master.dbo.sysdatabases 
WHERE name IN ("TB2","TB1")  -- use these databases

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @name   


WHILE @@FETCH_STATUS = 0   
BEGIN   

       DELETE FROM @name WHERE PersonID ='2'

       FETCH NEXT FROM db_cursor INTO @name   
END  

【讨论】:

那行不通。您需要使用类似 exec('DELETE ' + @tableName)【参考方案10】:
CREATE PROCEDURE sp_deleteUserDetails
    @Email varchar(255)
AS
    declare @tempRegId as int
    Delete UserRegistration where Email=@Email  
    set @tempRegId = (select Id from UserRegistration where Email = @Email)
    Delete UserProfile where RegID=@tempRegId

RETURN 0

【讨论】:

【参考方案11】:

$qry = "DELETE lg., l. FROM courses_game lg RIGHT JOIN 课程 l ON lg.lesson_id = l.id WHERE l.id = ?";

课程是主表和 Lesson_game 是子表,所以右加入

【讨论】:

【参考方案12】:
DELETE TB1, TB2
    FROM customer_details
        LEFT JOIN customer_booking on TB1.cust_id = TB2.fk_cust_id
    WHERE TB1.cust_id = $id

【讨论】:

简单的英文解释不会有什么坏处。见***.com/help/how-to-answer【参考方案13】:

试试这个查询

DELETE TB1, TB2 FROM TB1 INNER JOIN TB2  
WHERE TB1.PersonID = TB2.PersonID and TB1.PersonID = '2'

【讨论】:

以上是关于使用带有 WHERE 条件的单个查询 (SQL Express 2005) 从多个表中删除行的主要内容,如果未能解决你的问题,请参考以下文章

sql的where条件中是不是null相关条件怎么写

带有变量“Where”的 SQL 查询

SQL:如何在带有“NOT IN”条件的“Where”子句中使用“and”和“or”

在mysql中使用带有单个关键字的单个where条件搜索表的所有列

sql 对同一字段进行模糊查询时如何将两个条件写入一个like中

常用的SQL语句