带有外键的SQL Server触发器表

时间:2010-11-14 15:38:39

标签: sql-server triggers identity

我有以下情况(SQL Server Express):

  • 通过pk-fk约束连接的2个表
  • 加入这两个表的视图
  • 使用数据库的程序只能访问视图
  • 而不是触发视图上的插入

想法是触发器将数据输入1.表 - >通过IDENTITY创建一个新的PK,第二个表现在必须包含1.表的ID作为其主键的一部分......

如何在多连接环境中访问新创建的1.表的PK?这是数据库的简化/修改版本:

CREATE TABLE Training (  
Training_ID INT IDENTITY NOT NULL PRIMARY KEY,  
Name NVARCHAR(30) NOT NULL);

CREATE TABLE Kilometer (
Training_ID INT NOT NULL REFERENCES Training(Training_ID),  
Kilometer_ID INT NOT NULL,
Timestamp DATETIME NOT NULL,
PRIMARY KEY(Training_ID, Kilometer_ID);

CREATE VIEW TrainingView (  
SELECT t.Name, k.Timestamp
FROM Training t LEFT JOIN Kilometer k ON (t.Training_ID = k.Training_ID));

CREATE TRIGGER TrainingTrigger ON TrainingView INSTEAD OF INSERT AS BEGIN
INSERT INTO Training(Name) SELECT Name FROM inserted;
INSERT INTO Kilometer(Training_ID, Kilometer_ID, Timestamp) SELECT @@Identity, 0, Timestamp FROM inserted;
END;

由于数据库中的其他定义,Kilometer_ID的默认值为'0',合并这两个表不是一个选项... 虽然触发器似乎正常运行,但我不确定它是否会在多用户环境中(如果另一个连接改变了表,@@ Identity会发生什么?)

这个触发器有更好的解决方案吗?

Greetz Michael

2 个答案:

答案 0 :(得分:2)

如果您对@@ Identity的关注是唯一的问题,请使用SCOPE_IDENTITY(),它会从同一范围返回最近创建的ID。

此处解释的差异:http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

答案 1 :(得分:0)

如果在单插入的低容量环境中,您的方法可能会一直运行。在SQL Server中,如果使用SCOPE_IDENTITY更好,因为它只从当前范围获取标识。

如果您想一次在此视图中插入多行(例如insert into TrainingView select ...),这将会中断,因为您需要多个TrainingID。为此,您可以使用SQL Server's OUTPUT clause获取该插入内容的所有ID。