我正在尝试将过程的输出传递给触发器主体。以下是我对我认为可能是一个非常简单的答案的尝试。谢谢!
INSTEAD OF INSERT
AS BEGIN
SET NOCOUNT ON;
DECLARE @id INT, @num_ids INT;
EXEC [dbo].[i14_get_ids] 2, 1, @id OUTPUT, @num_ids OUTPUT;
INSERT dbo.tbl_Events(
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date,
ObjectID
)
SELECT
a.Event_ID, a.Location_ID, a.Event_Group_ID,
a.Protocol_Name, a.Start_Date,
b.ObjectID
From
(SELECT
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date
--deosn't work
--ObjectID as @id
--**********************************
FROM inserted) AS a
--doesn't work
@id ;
end
答案 0 :(得分:3)
你的语法有点偏。您在变量中有一个值,您不必为了访问它而构成一些表或别名。
ALTER TRIGGER dbo.Name_Of_Trigger_You_Left_Out
ON dbo.Name_Of_Table_You_Left_Out
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @id INT, @num_ids INT;
EXEC [dbo].[i14_get_ids] 2, 1, @id OUTPUT, @num_ids OUTPUT;
INSERT dbo.tbl_Events
(
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date, ObjectID
)
SELECT
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date, ObjectID = @id
FROM inserted;
END
GO
ObjectID =
别名不是必需的,我只想明确表示它是一个变量。您有ObjectID as @id
- 这是向后的,您说“使用别名@id显示列ObjectID” - 您的真正含义是@id AS ObjectID
- 但在这种情况下,它只是一个值包含在选择列表中,没有严格要求在这里提供别名。
如果您要依赖此处理仅单行插入,您应该考虑在继续之前通过检查inserted
中的行数来强制执行该操作。仅仅因为应用程序逻辑有限并不意味着不会触发在应用程序逻辑控制之外发生的插入,或者应用程序逻辑中永远不会出现错误。
修改强>
如果请求的应用程序被其连接字符串标识为“我的酷应用程序”,则完全绕过逻辑:
ALTER TRIGGER dbo.Name_Of_Trigger_You_Left_Out
ON dbo.Name_Of_Table_You_Left_Out
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS
(
SELECT 1 FROM sys.dm_exec_sessions
WHERE session_id = @@SPID
AND program_name = 'My Cool Application'
)
BEGIN
DECLARE @id INT, @num_ids INT;
EXEC [dbo].[i14_get_ids] 2, 1, @id OUTPUT, @num_ids OUTPUT;
INSERT dbo.tbl_Events
(
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date, ObjectID
)
SELECT
Event_ID, Location_ID, Event_Group_ID,
Protocol_Name, Start_Date, ObjectID = @id
FROM inserted;
END
END
GO
如果通过登录识别它,您只需检查IF SUSER_SNAME() <> 'MyMultiRowLogin'
或类似的东西......