2009-04-23 63 views

回答

92

在此示例中,您可以利用“已删除”伪表。例如:

begin transaction; 

    declare @deletedIds table (id int); 

    delete t1 
    output deleted.id into @deletedIds 
    from table1 t1 
    join table2 t2 
     on t2.id = t1.id 
    join table3 t3 
     on t3.id = t2.id; 

    delete t2 
    from table2 t2 
    join @deletedIds d 
     on d.id = t2.id; 

    delete t3 
    from table3 t3 ... 

commit transaction; 

显然你可以做一个'输出删除'。第二次删除,如果你需要加入第三张表的话。

另外,还可以在插入语句中插入。*,并在更新语句中插入。*和deleted。*。

编辑: 另外,你有没有考虑在table1上添加一个触发器从table2 + 3删除?您将处于隐式事务中,并且还将具有“已插入。”和“已删除。”可用的伪表。

+2

只是删除从table1 WHERE id = x,然后从下一个表中删除,而不是使用内部连接,并通过所有这些额外的文本?基本上,跳过内部连接我只需要2个简单的查询....或者这种方法更有效吗? – Colandus 2013-03-10 13:16:59

13
  1. 您始终可以设置表关系上的级联删除。

  2. 您可以将多次删除封装在一个存储过程中。

  3. 您可以使用交易来确保一个工作单元。

+3

绝对有可能删除连接语句,我只是想从一个以上的删除表一次。 – 2009-04-24 16:58:50

+0

错误的答案,可以使用删除联接 – rboarman 2010-11-04 18:06:30

+0

答案现在正确。 – Robino 2014-06-27 13:50:07

1

正如Aaron已经指出的那样,您可以将删除行为设置为CASCADE,并且会在删除父记录时删除子记录。除非你想要某种其他的魔法发生(在这种情况下,Aaron的答复的2,3点是有用的),我不明白为什么你需要用内部联接来删除。

10

您可以在SQL Server的DELETE中的FROM子句中使用JOIN语法,但您仍然只从第一个表中删除,并且它是专有的Transact-SQL扩展,它是子查询的替代方法。

从例如here

-- Transact-SQL extension 
DELETE 
    FROM Sales.SalesPersonQuotaHistory 
    FROM Sales.SalesPersonQuotaHistory AS spqh INNER JOIN 
      Sales.SalesPerson AS sp ON spqh.BusinessEntityID = sp.BusinessEntityID 
    WHERE sp.SalesYTD > 2500000.00; 
+2

实施例d:DELETE FROM Sales.SalesPersonQuotaHistory FROM Sales.SalesPersonQuotaHistory AS spqh INNER JOIN Sales.SalesPerson AS SP ON spqh.BusinessEntityID = sp.BusinessEntityID WHERE sp.SalesYTD> 2500000.00; – 2012-12-13 18:19:19

7

基本上,没有你不得不在交易3条DELETE语句,儿童先的父母。设置级联删除是一个好主意,如果这不是一次性的,它的存在不会与任何现有的触发器设置冲突。

+0

我希望我不必那样做,我想我必须将ID选择到临时表中,因为这种关系不是父子关系。一旦一个表中的行消失,就无法获取其他行。 – 2009-04-24 17:01:02

2

在SQL服务器中,无法使用连接删除多个表。 因此,您必须在删除表单父项之前先从子项中删除。

9

只是想知道..是真的可能在MySQL?它会删除t1和t2?或者我只是误解了这个问题。

但如果你只是想删除表1有多个连接条件,只是不别名要删除表

这样的:

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ... 
INNER JOIN table3 t3 ... 

应该这样写在MSSQL工作:

DELETE table1 
FROM table1 
INNER JOIN table2 t2 ... 
INNER JOIN table3 t3 ... 

对比其他两个常见的RDBMS怎么做删除操作:

http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html

+0

感谢您的SQL Server提示,我不得不根据这些行调整SQL。 – Pauk 2011-05-19 09:32:37

2

所有被指出。只需使用父母table上的DELETE ON CASCADE或从child-table删除parent

用于从两个细节表中删除从主表和相应的记录的一些记录
11

实施例:

BEGIN TRAN 

    -- create temporary table for deleted IDs 
    CREATE TABLE #DeleteIds (
    Id INT NOT NULL PRIMARY KEY 
) 

    -- save IDs of master table records (you want to delete) to temporary table  
    INSERT INTO #DeleteIds(Id) 
    SELECT DISTINCT mt.MasterTableId 
    FROM MasterTable mt 
    INNER JOIN ... 
    WHERE ... 

    -- delete from first detail table using join syntax 
    DELETE d 
    FROM DetailTable_1 D 
    INNER JOIN #DeleteIds X 
    ON D.MasterTableId = X.Id 


    -- delete from second detail table using IN clause 
    DELETE FROM DetailTable_2 
    WHERE MasterTableId IN (
    SELECT X.Id 
    FROM #DeleteIds X 
) 


    -- and finally delete from master table 
    DELETE d 
    FROM MasterTable D 
    INNER JOIN #DeleteIds X 
    ON D.MasterTableId = X.Id 

    -- do not forget to drop the temp table 
    DROP TABLE #DeleteIds 

COMMIT 
2

这是删除记录而不留下孤儿的替代方式。

 

Declare @user Table(keyValue int , someString varchar(10)) 
insert into @user 
values(1,'1 value') 

insert into @user 
values(2,'2 value') 

insert into @user 
values(3,'3 value') 

Declare @password Table( keyValue int , details varchar(10)) 
insert into @password 
values(1,'1 Password') 
insert into @password 
values(2,'2 Password') 
insert into @password 
values(3,'3 Password') 

     --before deletion 
    select * from @password a inner join @user b 
       on a.keyvalue = b.keyvalue 
    select * into #deletedID from @user where keyvalue=1 -- this works like the output example 
    delete @user where keyvalue =1 
    delete @password where keyvalue in (select keyvalue from #deletedid) 

    --After deletion-- 
    select * from @password a inner join @user b 
       on a.keyvalue = b.keyvalue 

-3
DELETE  TABLE1 LIN 
FROM TABLE1 LIN 
INNER JOIN TABLE2 LCS ON CONDITION 
WHERE CONDITION 
-4

$ SQL =“DELETE FROM basic_tbleducation_tblpersonal_tbladdress_tbldepartment_tbl 使用 basic_tbleducation_tblpersonal_tbladdress_tbldepartment_tbl WHERE b_id = e_id = p_id = a_id = ' ='“。$ id。”' “; $ rs = mysqli_query($ con,$ sql);

0

要建立在约翰·吉布的回答,删除一组数据的两个表与FK关系:

--*** To delete from tblMain which JOINs to (has a FK of) tblReferredTo's PK 
--  i.e. ON tblMain.Refer_FK = tblReferredTo.ID 
--*** !!! If you're CERTAIN that no other rows anywhere also refer to the 
--  specific rows in tblReferredTo !!! 
BEGIN TRAN; 

    --*** Keep the ID's from tblReferredTo when we DELETE from tblMain 
    DECLARE @tblDeletedRefs TABLE (ID INT); 
    --*** DELETE from the referring table first 
    DELETE FROM tblMain 
    OUTPUT DELETED.Refer_FK INTO @tblDeletedRefs -- doesn't matter that this isn't DISTINCT, the following DELETE still works. 
    WHERE ..... -- be careful if filtering, what if other rows 
       -- in tblMain (or elsewhere) also point to the tblReferredTo rows? 

    --*** Now we can remove the referred to rows, even though tblMain no longer refers to them. 
    DELETE tblReferredTo 
    FROM tblReferredTo INNER JOIN @tblDeletedRefs Removed 
      ON tblReferredTo.ID = Removed.ID; 

COMMIT TRAN;