Necesito crear un procedimiento que me permita eliminar datos de varias tablas a la vez, buscando a través de CUIT. Aquí se muestran cuatro tablas:

enter image description here

Debo pasar un valor CUIT, y si coincide con algún elemento guardado en la base de datos, necesito que se elimine. No pude encontrar la sintaxis para poder borrar más de dos tablas a la vez, si pudiera echarme una mano lo agradecería enormemente. Aclaro por las dudas que el procedimiento es en realidad mucho más grande, en total sería de unas 12 tablas, pero como me interesa solo la sintaxis le paso este fragmento.

Tengo problemas para intentar unirme a las tablas con INNER JOIN.

Estoy usando SQL Server 2016. Gracias

0
Mauro 20 feb. 2020 a las 14:23

2 respuestas

La mejor respuesta

Teniendo en cuenta su diseño, implementaría Cascading en su clave externa. Esta es una muestra, pero debería llevarlo por el camino correcto:

USE Sandbox;
GO

CREATE TABLE dbo.ParentTable (PK int IDENTITY PRIMARY KEY,
                              I int);

CREATE TABLE dbo.ChildTable1 (PK int IDENTITY PRIMARY KEY,
                              FK int,
                              S varchar(10));

CREATE TABLE dbo.ChildTable2 (PK int IDENTITY PRIMARY KEY,
                              FK int,
                              S varchar(10));

CREATE TABLE dbo.ChildTable3 (PK int IDENTITY PRIMARY KEY,
                              FK int,
                              S varchar(10));
GO
--Create keys with CASCADE ON DELETE
ALTER TABLE dbo.ChildTable1 ADD CONSTRAINT FK1 FOREIGN KEY (FK) REFERENCES dbo.ParentTable(PK) ON DELETE CASCADE;
GO
ALTER TABLE dbo.ChildTable2 ADD CONSTRAINT FK2 FOREIGN KEY (FK) REFERENCES dbo.ParentTable(PK) ON DELETE CASCADE;
GO
ALTER TABLE dbo.ChildTable3 ADD CONSTRAINT FK3 FOREIGN KEY (FK) REFERENCES dbo.ParentTable(PK) ON DELETE CASCADE;
GO


INSERT INTO dbo.ParentTable (I)
VALUES(1),(7),(9);

INSERT INTO dbo.ChildTable1 (FK,
                            S)
VALUES(1,'abc'),(3,'def');

INSERT INTO dbo.ChildTable2 (FK,
                            S)
VALUES(1,'xyz'),(2,'qwe');

INSERT INTO dbo.ChildTable3 (FK,
                            S)
VALUES(1,'123');
GO

SELECT *
FROM dbo.ParentTable PT
     LEFT JOIN dbo.ChildTable1 CT1 ON PT.PK = CT1.PK
     LEFT JOIN dbo.ChildTable2 CT2 ON PT.PK = CT2.PK
     LEFT JOIN dbo.ChildTable3 CT3 ON PT.PK = CT3.PK;

--1, as we're going to DELETE that
SELECT *
FROM dbo.ChildTable1 CT1
WHERE CT1.FK = 1;

SELECT *
FROM dbo.ChildTable1 CT2
WHERE CT2.FK = 1;

SELECT *
FROM dbo.ChildTable1 CT3
WHERE CT3.FK = 1;
GO

--Perform the DELETE, which will CASCADE to the child tables.    
DELETE FROM dbo.ParentTable
WHERE PK = 1;
GO
--no rows
SELECT *
FROM dbo.ParentTable PT
     LEFT JOIN dbo.ChildTable1 CT1 ON PT.PK = CT1.PK
     LEFT JOIN dbo.ChildTable2 CT2 ON PT.PK = CT2.PK
     LEFT JOIN dbo.ChildTable3 CT3 ON PT.PK = CT3.PK;

SELECT *
FROM dbo.ChildTable1 CT1
WHERE CT1.FK = 1;

SELECT *
FROM dbo.ChildTable1 CT2
WHERE CT2.FK = 1;

SELECT *
FROM dbo.ChildTable1 CT3
WHERE CT3.FK = 1;

GO
DROP TABLE dbo.ChildTable3;
DROP TABLE dbo.ChildTable2;
DROP TABLE dbo.ChildTable1;
DROP TABLE dbo.ParentTable;
0
Larnu 20 feb. 2020 a las 11:33

En caso de que no desee alterar el esquema de su base de datos, puede elegir INSTEAD OF TRIGGER.

Trigger le permite realizar cualquier tarea cuando se realiza una acción particular. En este caso, puede escribir INSTEAD OF DELETE activador en su tabla principal / principal y dentro del activador puede eliminar entradas relacionadas de las tablas secundarias. Echa un vistazo al siguiente ejemplo.

CREATE TABLE dbo.Gestiones
(
    id_gestione int IDENTITY (1, 1) PRIMARY KEY,
    CUIT INT
);

CREATE TABLE dbo.ChildGestione1
(
    ID INT IDENTITY PRIMARY KEY,
    id_gestioneFK int REFERENCES Gestiones(id_gestione),
    Description VARCHAR(100)
);

CREATE TABLE dbo.ChildGestione2
(
    ID INT IDENTITY PRIMARY KEY,
    id_gestioneFK int REFERENCES Gestiones(id_gestione),
    Description VARCHAR(100)
);

CREATE TABLE dbo.ChildGestione3
(
    ID INT IDENTITY PRIMARY KEY,
    id_gestioneFK int REFERENCES Gestiones(id_gestione),
    Description VARCHAR(100)
);


INSERT INTO dbo.Gestiones (CUIT)
VALUES (10), (20), (30), (40);

INSERT INTO dbo.ChildGestione1 (id_gestioneFK, Description)
VALUES (1,'abc'), (2,'efg');

INSERT INTO dbo.ChildGestione2 (id_gestioneFK, Description)
VALUES (1,'abc'), (3,'pqr');

INSERT INTO dbo.ChildGestione3 (id_gestioneFK, Description)
VALUES (1,'abc'), (3,'pqr'), (4,'stu');

GO


SELECT * FROM dbo.Gestiones
SELECT * FROM dbo.ChildGestione1
SELECT * FROM dbo.ChildGestione2
SELECT * FROM dbo.ChildGestione3

DELETE FROM Gestiones where CUIT = 10

SELECT * FROM dbo.Gestiones
SELECT * FROM dbo.ChildGestione1
SELECT * FROM dbo.ChildGestione2
SELECT * FROM dbo.ChildGestione3


CREATE TRIGGER InsteadOfDELETETriggerExample ON [Gestiones]
INSTEAD OF DELETE
AS 
BEGIN
    DECLARE @id_gestione INT

    SELECT @id_gestione = id_gestione FROM deleted

    IF @id_gestione IS NOT NULL
    BEGIN
        DELETE FROM ChildGestione1 WHERE id_gestioneFK = @id_gestione
        DELETE FROM ChildGestione2 WHERE id_gestioneFK = @id_gestione
        DELETE FROM ChildGestione3 WHERE id_gestioneFK = @id_gestione
        /*...
        and so on...you can right as many child tables as you have
        */

        -- At the last, delete the entry from parent table
        DELETE FROM Gestiones WHERE id_gestione = @id_gestione
    END

    PRINT 'Successfully deleted references of CUIT column from all the child tables.'
END
GO


DROP TRIGGER InsteadOfDELETETriggerExample
GO

DROP TABLE dbo.ChildGestione3;
DROP TABLE dbo.ChildGestione2;
DROP TABLE dbo.ChildGestione1;
DROP TABLE dbo.Gestiones;

El código anterior funcionará solo para una entrada de eliminación en la tabla maestra, si la operación de eliminación afecta a más de una entrada en la tabla principal, entonces debe JOIN la tabla deleted con sus tablas secundarias para eliminar.

0
iVad 21 feb. 2020 a las 05:07