带有外键的 SQL Server 触发器表
我有以下情况(SQL Server Express):
- 2 个表通过 pk-fk 约束连接
- 一个视图连接这两个表
- 使用数据库的程序只能访问视图
- 一个而不是在视图上插入的触发器
想法就是触发器将数据输入到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 会发生什么?)
对此触发器是否有更好的解决方案?
格雷兹·迈克尔
I have the following situation (SQL Server Express):
- 2 tables connected via a pk-fk constraint
- a view that joins these two tables
- the program to use the database only has access to the view
- an instead of trigger for inserts on the view
The idea is that the trigger enters data into the 1. table -> a new PK is created via IDENTITY, the second table now has to contain the 1. table's ID as part of it's primary key...
How can I access the newly created PK of the 1. table in a multi-connection-environment? This is a simplified/modifed version of the database:
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;
The default '0' for Kilometer_ID is mandatory due to other definitions in the database, merging these two tables is not an option...
While the Trigger seems to function right, I'm not sure if it will in a multi-user environment (what happens to @@Identity, if another connection alters the table?)
Is there a better solution to this trigger?
Greetz Michael
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您担心 @@Identity 是唯一的问题,请使用 SCOPE_IDENTITY() ,它会从同一范围返回最近创建的 id。
差异解释如下:
If your concern with @@Identity is the only issue use SCOPE_IDENTITY() , which returns the most recently created id FROM THE SAME SCOPE.
Differences explained here: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/
如果在单次插入的低容量环境中,您的方法可能几乎一直有效。在 SQL Server 中,如果使用 SCOPE_IDENTITY 会更好,因为它仅从当前作用域获取标识。
如果您想一次将多行插入到该视图中(例如,
insert into TrainingView select ...
),这将会中断,因为您将需要多个 TrainingID。为此,您可以使用 SQL Server 的 OUTPUT 子句 来获取所有信息该插入的 ID。Your approach is probably going to work pretty much all the time if it's in a low volume environment of single inserts. In SQL Server, if you use SCOPE_IDENTITY is better because it only gets identities from the current scope.
If you want to insert multiple rows into this view at once (e.g.,
insert into TrainingView select ...
) this is going to break because you'll need more than one TrainingID. For this, you can use SQL Server's OUTPUT clause to get your all your IDs for that insert.