subconsulta - eliminar registros de varias tablas sql server
¿Cómo elimino de varias tablas usando INNER JOIN en el servidor SQL? (13)
Siempre puede configurar eliminaciones en cascada en las relaciones de las tablas.
Puede encapsular las eliminaciones múltiples en un procedimiento almacenado.
Puede usar una transacción para asegurar una unidad de trabajo.
En MySQL puedes usar la sintaxis
DELETE t1,t2
FROM table1 AS t1
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
¿Cómo hago lo mismo en SQL Server?
$ sql = "ELIMINAR DE basic_tbl
, education_tbl
, personal_tbl
, address_tbl
, department_tbl
USAR basic_tbl
, education_tbl
, personal_tbl
, address_tbl
, department_tbl
DONDE b_id
= e_id
= p_id
= a_id
= d_id
= ''". $ id. "''"; $ rs = mysqli_query ($ con, $ sql);
Básicamente, no tienes que hacer tres declaraciones de eliminación en una transacción, primero hijos y luego padres. La configuración de eliminaciones en cascada es una buena idea si esto no es algo único y su existencia no entrará en conflicto con ninguna configuración de activación existente.
Como ya ha señalado Aaron, puede establecer el comportamiento de eliminación en CASCADE y eliminará los registros secundarios cuando se elimine un registro principal. A menos que desee que ocurra algún tipo de otra magia (en cuyo caso los puntos 2, 3 de la respuesta de Aaron serían útiles), no veo por qué debería eliminar con combinaciones internas.
Ejemplo para eliminar algunos registros de la tabla maestra y los registros correspondientes de dos tablas de detalles:
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
En el servidor SQL no hay forma de eliminar varias tablas usando join. Por lo tanto, debe eliminar del elemento secundario antes de eliminar el elemento principal.
Esta es una forma alternativa de eliminar registros sin dejar huérfanos.
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
Para construir sobre la respuesta de John Gibb, para eliminar un conjunto de datos en dos tablas con una relación 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;
Puede aprovechar la pseudo tabla "eliminada" en este ejemplo. Algo como:
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;
Obviamente, puedes hacer una ''salida eliminada''. en el segundo borra también, si necesitabas algo para unirte a la tercera tabla.
Como nota al margen, también puede hacer insert. * En una instrucción de inserción, y ambos insertados. * Y eliminados. * En una declaración de actualización.
EDITAR: Además, ¿ha considerado agregar un desencadenador en la tabla1 para eliminarlo de la tabla2 + 3? Estará dentro de una transacción implícita y también tendrá las pseudo-tablas "insertado " y "eliminado ".
Puede usar la sintaxis JOIN en la cláusula FROM en DELETE en SQL Server, pero aún así eliminar de la primera tabla solamente y es una extensión patentada de Transact-SQL que es alternativa a la subconsulta.
De ejemplo 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;
Solo me preguntaba ... ¿eso es realmente posible en MySQL? borrará t1 y t2? o simplemente malentendí la pregunta.
Pero si solo quiere eliminar table1 con múltiples condiciones de unión, simplemente no alias la tabla que desea eliminar
esta:
DELETE t1,t2
FROM table1 AS t1
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
debería escribirse así para trabajar en MSSQL:
DELETE table1
FROM table1
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
para contrastar cómo los otros dos RDBMS comunes realizan una operación de eliminación:
http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html
Todo ha sido señalado. Solo use DELETE ON CASCADE
en la table
padre o elimínelo de la child-table
para el parent
.
DELETE TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON CONDITION
WHERE CONDITION