Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 创建从多个表中删除数据的过程。SQL Server_Sql Server_Stored Procedures_Sql Delete - Fatal编程技术网

Sql server 创建从多个表中删除数据的过程。SQL Server

Sql server 创建从多个表中删除数据的过程。SQL Server,sql-server,stored-procedures,sql-delete,Sql Server,Stored Procedures,Sql Delete,我需要创建一个过程,通过搜索CUIT,一次删除多个表中的数据。此处显示了四个表: 我必须传入CUIT值,如果它与数据库中保存的任何项目匹配,我需要将其删除。我找不到能够同时删除两个以上表格的语法,如果您能帮我一把,我将不胜感激。我怀疑这个过程实际上要大得多,总共大约有12个表,但我只对传递这个片段的语法感兴趣 尝试使用内部联接联接表时遇到问题 我正在使用SQL Server 2016。谢谢考虑到您的设计,我将在您的外键上实现级联。这是一个示例,但应该会让您走上正确的道路: USE Sandbo

我需要创建一个过程,通过搜索
CUIT
,一次删除多个表中的数据。此处显示了四个表:

我必须传入
CUIT
值,如果它与数据库中保存的任何项目匹配,我需要将其删除。我找不到能够同时删除两个以上表格的语法,如果您能帮我一把,我将不胜感激。我怀疑这个过程实际上要大得多,总共大约有12个表,但我只对传递这个片段的语法感兴趣

尝试使用
内部联接
联接表时遇到问题


我正在使用SQL Server 2016。谢谢

考虑到您的设计,我将在您的外键上实现级联。这是一个示例,但应该会让您走上正确的道路:

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;

如果您不想更改数据库模式,可以选择
而不是TRIGGER

触发器允许您在执行特定操作时执行任何任务。在这种情况下,您可以在父/主表上写入
而不是删除
触发器,并且在触发器中可以从子表中删除相关条目。看看下面的例子

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;

上述代码仅适用于主表上的一个删除条目,如果删除操作影响父表中的多个条目,则您需要
已删除的
表与您的子表连接起来进行删除。

“我找不到能够一次删除两个以上表的语法”因为没有这样的语法。DML语句一次只能影响一个表。考虑到您想从4个表中
DELETE
,这意味着您将需要4个
DELETE
语句。那么我该如何完成这项任务呢?使用什么来执行这些类型的操作?因为我需要删除与该CUIT相关的所有信息,以及是否必须在表之间建立任何关系。非常感谢。