Sql server 插入视图,而不是触发器、标识、多个表?

Sql server 插入视图,而不是触发器、标识、多个表?,sql-server,view,triggers,Sql Server,View,Triggers,这里是我的表格Entier=Integer//Caractère long variable=Varchar: 我创建了一个视图,查看联系人、电话号码、电子邮件、姓名、城市、地址 我尝试在该视图上创建触发器,以允许用户更新该视图: CREATE TRIGGER test ON V_Entreprise INSTEAD OF INSERT AS DECLARE @T_ContactId INT BEGIN INSERT INTO T_Contact SELECT i.phone

这里是我的表格Entier=Integer//Caractère long variable=Varchar:

我创建了一个视图,查看联系人、电话号码、电子邮件、姓名、城市、地址

我尝试在该视图上创建触发器,以允许用户更新该视图:

CREATE TRIGGER test
ON V_Entreprise
INSTEAD OF INSERT
AS 
DECLARE @T_ContactId INT
BEGIN
    INSERT INTO T_Contact 
    SELECT i.phoneNumber, i.email
    FROM Inserted i 

    SELECT @T_ContactId = @@IDENTITY

    INSERT INTO T_Entreprise
    SELECT @T_ContactId, i.name, i.city, i.adress
    FROM Inserted i 
END ;

正如我所料,它可以处理简单的插入,但当我一次添加几行时,它失败了,因为@T_ContactId只包含第一个id。有人能帮我修复它吗?我觉得我应该使用内部连接插入,但我不知道如何处理它。

好的,永远不要将标量变量设置为触发器中插入或删除的值


使用OUTPUT子句取回您的id值。

好的,您不应该在触发器的inserted或delted中将标量变量设置为值

使用OUTPUT子句取回您的id值。

如果电话号码和电子邮件是T_联系人中的唯一键,则您可以执行以下操作:

CREATE TRIGGER test
ON V_Entreprise
INSTEAD OF INSERT
AS 
DECLARE @T_ContactId INT
BEGIN
    INSERT INTO T_Contact 
    SELECT i.phoneNumber, i.email
    FROM Inserted i 

    SELECT @T_ContactId = @@IDENTITY

    INSERT INTO T_Entreprise
    SELECT
        (SELECT idContact FROM T_Contact
            WHERE phoneNumber = i.phoneNumber AND email = i.email),
        i.name, i.city, i.adress
    FROM Inserted i 
END ;
如果电话号码和电子邮件是T_Contact中的唯一键,则您可以执行以下操作:

CREATE TRIGGER test
ON V_Entreprise
INSTEAD OF INSERT
AS 
DECLARE @T_ContactId INT
BEGIN
    INSERT INTO T_Contact 
    SELECT i.phoneNumber, i.email
    FROM Inserted i 

    SELECT @T_ContactId = @@IDENTITY

    INSERT INTO T_Entreprise
    SELECT
        (SELECT idContact FROM T_Contact
            WHERE phoneNumber = i.phoneNumber AND email = i.email),
        i.name, i.city, i.adress
    FROM Inserted i 
END ;

此触发器在游标上使用循环,不需要表中的任何特定唯一性

CREATE TRIGGER test
ON V_Enterprise
INSTEAD OF INSERT
AS 
BEGIN
   DECLARE @name    VARCHAR(32)
   DECLARE @city    VARCHAR(32)
   DECLARE @address VARCHAR(32)
   DECLARE @pn      VARCHAR(32)
   DECLARE @email   VARCHAR(32)

   DECLARE cursor1 CURSOR FOR
      SELECT name,city,address,phoneNumber,email FROM inserted;

    OPEN cursor1;
    FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    WHILE @@FETCH_STATUS = 0
    BEGIN
      INSERT INTO T_Contact (phoneNumber,email) VALUES (@pn, @email);
      INSERT INTO T_Enterprise (idcontact,name,city,address) VALUES
         (@@IDENTITY,@name,@city,@address);
      FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    END
    CLOSE cursor1;
    DEALLOCATE cursor1;
END
GO

此触发器在游标上使用循环,不需要表中的任何特定唯一性

CREATE TRIGGER test
ON V_Enterprise
INSTEAD OF INSERT
AS 
BEGIN
   DECLARE @name    VARCHAR(32)
   DECLARE @city    VARCHAR(32)
   DECLARE @address VARCHAR(32)
   DECLARE @pn      VARCHAR(32)
   DECLARE @email   VARCHAR(32)

   DECLARE cursor1 CURSOR FOR
      SELECT name,city,address,phoneNumber,email FROM inserted;

    OPEN cursor1;
    FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    WHILE @@FETCH_STATUS = 0
    BEGIN
      INSERT INTO T_Contact (phoneNumber,email) VALUES (@pn, @email);
      INSERT INTO T_Enterprise (idcontact,name,city,address) VALUES
         (@@IDENTITY,@name,@city,@address);
      FETCH NEXT FROM cursor1 INTO @name, @city, @address, @pn, @email;
    END
    CLOSE cursor1;
    DEALLOCATE cursor1;
END
GO
我不知道这是否是一种很好的方法,但是您可以在不依赖唯一列的情况下或者使用游标(使用OUTPUT子句进行INSERT)的情况下实现这一点。这种方法确实利用了内存中的临时表,它可以通过大的插入而变大

DECLARE @Table table( NewID BIGINT);


INSERT INTO T_Contact (PhoneNumber) 
    OUTPUT Inserted.ID
    INTO @Table
SELECT PhoneNumber FROM inserted WHERE 
;

INSERT INTO T_Enterprise (Contact_ID)
SELECT NewID FROM @Table;
我不知道这是否是一种很好的方法,但是您可以在不依赖唯一列的情况下或者使用游标(使用OUTPUT子句进行INSERT)的情况下实现这一点。这种方法确实利用了内存中的临时表,它可以通过大的插入而变大

DECLARE @Table table( NewID BIGINT);


INSERT INTO T_Contact (PhoneNumber) 
    OUTPUT Inserted.ID
    INTO @Table
SELECT PhoneNumber FROM inserted WHERE 
;

INSERT INTO T_Enterprise (Contact_ID)
SELECT NewID FROM @Table;

电话号码和电子邮件是T_联系人中的唯一键吗?出于好奇,您使用了什么来获取数据模型设计图像?这是Sybase的PowerAMC试用版。电话号码和电子邮件是T_联系人中的唯一键吗?出于好奇,您使用了什么来获取数据模型设计图像?这是Sybase的PowerAMC试用版。嗯,它应该可以做到我在例子中跳过了一些专栏。在我的真实数据库中,我可以输入十几个参数。但我期待更多。。。健壮:-@FlorianC:但我期待更多。。。robust,你这到底是什么意思?首先,对不起,我的英语很差。我的意思是:没关系,它会起作用,因为用户不应该添加两次相同的联系人。但用户的行为总是很怪异,所以我试着想办法避免在这种情况下出现故障。显然,我可以在客户端管理它,但我认为有更好的方法在数据库中处理它,我真的很想找到它@弗洛里安,好吧,现在我明白了。如果需要,您可以在这两个或更多字段上向该表添加唯一约束,以便知道记录是唯一的。当然,您也应该在客户端处理它——但这是具体的安全层。嗯,它应该做到我在示例中跳过了一些专栏的技巧。在我的真实数据库中,我可以输入十几个参数。但我期待更多。。。健壮:-@FlorianC:但我期待更多。。。robust,你这到底是什么意思?首先,对不起,我的英语很差。我的意思是:没关系,它会起作用,因为用户不应该添加两次相同的联系人。但用户的行为总是很怪异,所以我试着想办法避免在这种情况下出现故障。显然,我可以在客户端管理它,但我认为有更好的方法在数据库中处理它,我真的很想找到它@弗洛里安,好吧,现在我明白了。如果需要,您可以在这两个或更多字段上向该表添加唯一约束,以便知道记录是唯一的。当然,您也应该在客户端处理它——但这是具体的安全层。