我需要创建一个过程,使我可以一次通过CUIT
搜索从多个表中删除数据。这里显示了四个表:
我必须传入CUIT
值,并且如果它与数据库中保存的任何项目匹配,则需要将其删除。我找不到能够一次擦除两个以上表的语法,如果您能帮我一下,我将不胜感激。通过怀疑,我澄清了该过程实际上实际上要大得多,总共大约有12个表,但是由于我只对语法感兴趣,因此我通过了此片段。
我在尝试使用INNER JOIN
联接表时遇到问题。
我正在使用SQL Server2016。谢谢
考虑到您的设计,我会在您的外键上实现级联。这是一个示例,但是应该使您走上正确的道路:
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;
[如果您不想更改数据库架构,则可以选择INSTEAD OF TRIGGER
。
触发器允许您在执行特定操作时执行任何任务。在这种情况下,您可以在父/主表上写入INSTEAD OF DELETE
触发器,而在触发器内,您可以从子表中删除相关条目。看下面的例子。
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;
以上代码仅适用于主表上的一个删除条目,如果删除操作影响父表中的多个条目,那么您需要将JOIN
表与子表一起deleted
进行删除。