【问题标题】:Delete rows from multiple tables using a single query (SQL Express 2005) with a WHERE condition使用带有 WHERE 条件的单个查询 (SQL Express 2005) 从多个表中删除行
【发布时间】: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 约束。我不想问另一个问题,因为这会是这个问题的欺骗。

标签: sql sql-server sql-server-express sql-server-2005-express


【解决方案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;
              

              参考信息:

              【讨论】:

                【解决方案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
                    

                    【讨论】:

                    【解决方案13】:

                    试试这个查询

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

                    【讨论】:

                      猜你喜欢
                      • 2023-01-22
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-03-17
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多