使用带有 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 KEYS
与ON
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:如何在带有“NOT IN”条件的“Where”子句中使用“and”和“or”
在mysql中使用带有单个关键字的单个where条件搜索表的所有列