Es posible eliminar de varias tablas en la misma instrucción SQL?
Es posible eliminar usando instrucciones join para calificar el conjunto a ser eliminado, como lo siguiente:
DELETE J
FROM Users U
inner join LinkingTable J on U.id = J.U_id
inner join Groups G on J.G_id = G.id
WHERE G.Name = 'Whatever'
and U.Name not in ('Exclude list')
Sin embargo, estoy interesado en eliminar ambos lados de los criterios de unión, tanto el registro LinkingTable
como el registro de Usuario del que depende. No puedo activar las cascadas porque mi solución es Entity Framework code first y las relaciones bidireccionales crean múltiples rutas en cascada.
Idealmente, me gustaría algo como:
DELETE J, U
FROM Users U
inner join LinkingTable J on U.id = J.U_id
...
Sintácticamente esto no trabajar, pero tengo curiosidad si algo como esto es posible?
5 answers
No, tendría que ejecutar varias sentencias.
Debido a que necesita eliminar de dos tablas, considere crear una tabla temporal de los id coincidentes:
SELECT U.Id INTO #RecordsToDelete
FROM Users U
JOIN LinkingTable J ON U.Id = J.U_Id
...
Y luego eliminar de cada una de las tablas:
DELETE FROM Users
WHERE Id IN (SELECT Id FROM #RecordsToDelete)
DELETE FROM LinkingTable
WHERE Id IN (SELECT Id FROM #RecordsToDelete)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-09 03:06:17
La forma en que dices es Posible en MY SQL
pero no para SQL SERVER
Puede usar la pseudo tabla" deleted " para eliminar los valores de Dos Tablas a la vez como,
begin transaction;
declare @deletedIds table ( samcol1 varchar(25) );
delete #temp1
output deleted.samcol1 into @deletedIds
from #temp1 t1
join #temp2 t2
on t2.samcol1 = t1.samcol1
delete #temp2
from #temp2 t2
join @deletedIds d
on d.samcol1 = t2.samcol1;
commit transaction;
Para una breve explicación, puede echar un vistazo a este Enlace
Y para Conocer el Uso de la Tabla Eliminada puede seguir esta Utilizando las Tablas insertadas y eliminadas
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:41
La única manera que se me ocurre es romper lógicamente las claves foráneas bidireccionales de una manera procedural.
Este enfoque puede tener un gran impacto en el lado de su aplicación si no tiene algunas banderas para visualization
estado o status
Algo así como
-
INSERT
filas ficticias no visibles para los usuarios (con algo comoId = -1
para valores ficticios) -
Agregue a
LinkingTable
una columna alternativa para apuntar de nuevo aUsers
, la llamaréU_ComesFrom
ALTER TABLE LinkingTagble ADD U_ComesFrom_U_id INT DEFAULT (-1)
-
Añadir
FOREIGN KEY
conNOCHECK
ALTER TABLE LinkingTable WITH NOCHECK
CLAVE FORÁNEA (U_ComesFrom_U_id)
REFERENCIAS Usuarios (Id); -
Añadir a la columna
Users
ALTER TABLE Users ADD MarkedForDeletion BIT NOT NULL DEFAULT (0)
Entonces su SQL se vería como
BEGIN TRANSACTION
UPDATE J
SET U_Comes_From_U_id = U_ID, U_id = -1 -- or some N/R value that you define in Users
FROM Users U
inner join LinkingTable J on U.id = J.U_id
inner join Groups G on J.G_id = G.id
WHERE G.Name = 'Whatever'
and U.Name not in ('Exclude list')
UPDATE U
SET MarkedForDeletion = 1
FROM Users
inner join LinkingTable J on U.id = J.U_ComesFrom_U_id
WHERE U_id > 0
DELETE FROM LinkingTable
WHERE U_ComesFrom_U_id > 0
DELETE FROM Users
WHERE MarkedForDeletion = 1
COMMIT
Este enfoque afectaría el rendimiento ya que cada la transacción sería al menos 4 operaciones DML por claves bidireccionales.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-09 05:33:01
Use TRY CATCH con Transaction
BEGIN TRANSACTION
BEGIN TRY
DELETE from A WHERE id=1
DELETE FROM b WHERE id=1
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
O también puede utilizar el procedimiento de la tienda para el mismo Usando El Procedimiento Almacenado Con La Transacción:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-09 05:56:46
Si está creando la clave foránea a través de T-SQL, debe agregar la opción ON DELETE CASCADE a la clave foránea:
Code Snippet
ALTER TABLE <tablename>
ADD CONSTRAINT <constraintname> FOREIGN KEY (<columnname(s)>)
REFERENCES <referencedtablename> (<columnname(s)>)
ON DELETE CASCADE;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-31 09:29:40