Как удалить из нескольких таблиц с помощью внутреннего соединения в SQL server



в MySQL вы можете использовать синтаксис



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


Как сделать то же самое в SQL Server?

894   13  

13 ответов:

вы можете воспользоваться "удаленной" псевдо-таблицей в этом примере. Что-то вроде:

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;

очевидно, вы можете сделать 'выход удален.- на втором тоже удалите, если вам нужно было что-то добавить к третьему столу.

в качестве примечания вы также можете сделать вставку.* на инструкции insert, и оба вставлены.* и удалены.* по инструкции обновления.

EDIT: Кроме того, вы рассматривали возможность добавления триггера на table1 для удаления из таблицы 2 + 3? Вы будете внутри неявной транзакции, а также будете иметь " вставлено." и "исключить." псевдо-таблиц.

  1. вы всегда можете настроить каскадные удаления для отношений таблиц.

  2. вы можете инкапсулировать несколько удалений в одной хранимой процедуре.

  3. вы можете использовать транзакцию для обеспечения одной единицы работы.

вы можете использовать синтаксис соединения в предложении FROM в DELETE в SQL Server, но вы все равно удаляете только из первой таблицы, и это собственное расширение Transact-SQL, которое является альтернативой подзапросу.

пример здесь:

 -- 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;

пример удаления некоторых записей из главной таблицы и соответствующих записей из двух таблиц деталей:

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

просто интересно.. это возможно в MySQL? он удалит t1 и t2? или я просто неправильно понял вопрос.

но если вы просто хотите удалить table1 с несколькими условиями соединения, просто не псевдоним таблицы, которую вы хотите удалить

это:

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 ...

чтобы сравнить, как другие две общие СУБД делают удаление операция:

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

в принципе, нет, вам нужно сделать три оператора удаления в транзакции, сначала дети, а затем родители. Настройка каскадных удалений-это хорошая идея, если это не одноразовая вещь, и ее существование не будет конфликтовать с любой существующей настройкой триггера.

в SQL server Нет способа удалить несколько таблиц с помощью join. Таким образом, вы должны удалить из ребенка, прежде чем удалить форму родителя.

Это альтернативный способ удаления записей, не оставляя сирот.


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

все было указано. Просто использовать DELETE ON CASCADE на родительском table или удалить child-table до parent.

Как уже указывал Аарон, вы можете установить поведение удаления в каскад, и это приведет к удалению дочерних записей при удалении родительской записи. Если вы не хотите, чтобы произошло какое-то другое волшебство (в этом случае были бы полезны пункты 2, 3 ответа Аарона), я не понимаю, почему вам нужно удалить с помощью внутренних соединений.

чтобы построить ответ Джона Гибба, для удаления набора данных в двух таблицах с отношением 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;
DELETE     TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON  CONDITION
WHERE CONDITION

$sql= " удалить из basic_tbl,education_tbl, personal_tbl,address_tbl,department_tbl С ПОМОЩЬЮ basic_tbl,education_tbl, personal_tbl,address_tbl,department_tbl ГДЕ b_id=e_id=p_id=a_id=d_id='".$идентификатор."' "; $rs=mysqli_query($con,$sql);

Comments

    Ничего не найдено.