插入视图,代替触发器,身份,多个表?
Posted
技术标签:
【中文标题】插入视图,代替触发器,身份,多个表?【英文标题】:INSERT INTO View, INSTEAD OF Trigger, Identity, multiple tables? 【发布时间】:2013-03-01 15:35:10 【问题描述】:这里是我的表(Entier = Integer // Caractère long variable = Varchar):
http://i.stack.imgur.com/lNjyy.jpg
我创建了一个视图 V_Enterprise(idContact, phoneNumber, email, name, city, adress)
我尝试在该视图上创建一个触发器以允许用户更新视图:
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。有人可以帮我解决吗?我觉得我应该使用 INNER JOIN 插入,但我不知道如何处理它。
【问题讨论】:
phoneNumber
和 email
是 T_Contact
中的唯一键吗?
出于好奇,你用什么来得到那个数据模型设计图?
这是 Sybase 的 PowerAMC,试用版。 sybase.fr/products/modelingdevelopment/poweramc
【参考方案1】:
好的,您永远不应该将标量变量设置为触发器中插入或删除的值。
使用 OUTPUT 子句取回您的 id 值。
【讨论】:
【参考方案2】:此触发器在游标上使用循环,并且不需要表中有任何特定的唯一性;
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
【讨论】:
【参考方案3】:我不知道这是否是一种好的方法,但您可以做到这一点,而无需依赖唯一列或使用游标使用 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;
【讨论】:
【参考方案4】:如果phoneNumber
和email
是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 ;
【讨论】:
嗯,它应该可以解决问题(我在示例中跳过了一些列。在我的真实数据库中,我可以放置十几个参数)。但我期待的东西更...强大:-) @FlorianC:But I expected something more... robust
,你到底是什么意思?
首先,对不起我糟糕的英语。我的意思是:没关系,它会起作用,因为用户不应该添加两次相同的联系人。但是用户总是表现得很奇怪,所以我试图想办法避免在这种特殊情况下出现故障。我显然可以在“客户端”管理它,但我认为在数据库中有更好的方法来处理它,我真的很想找到它!
@FlorianC,好的,现在我明白了。您可以做的是在这两个(或更多,如果需要)字段上为该表添加一个唯一约束,以便您将知道记录是唯一的。您当然也应该在客户端处理它 - 但这是具体的安全层。以上是关于插入视图,代替触发器,身份,多个表?的主要内容,如果未能解决你的问题,请参考以下文章
您能否在视图上编写触发器,该视图在更改其基表后利用插入和删除表中的数据?