我有一个sql server“而不是insert”触发器,用于填充单个列(PromoCode)。这一切都很完美,但我不喜欢我必须在实际的INSERT语句中对列进行硬编码的事实:
CREATE TRIGGER PopulateOrderPromoCode ON Order
INSTEAD OF INSERT
AS BEGIN
--// Get the Promo Code
DECLARE @PromoCode int;
EXEC GetPromoCode @PromoCode OUTPUT;
--// Insert the order with the new Promo Code
INSERT INTO Order (Id, CustomerId, PromoCode)
SELECT Id, CustomerId, @PromoCode FROM inserted;
END
我更愿意只使用@PromoCode替换inserted.PromoCode中的值,然后可以使用:
INSERT INTO Order
SELECT * FROM inserted;
可以这样做吗?
答案 0 :(得分:2)
不要使用INSTEAD OF INSERT触发器(你必须接管插入逻辑)
使用普通的INSERT触发器(除了插件外,还允许你做
)这假设你可以插入没有促销代码(允许空值)或促销代码默认为某种东西。
CREATE TRIGGER PopulateOrderPromoCode ON Order
FOR INSERT
AS
BEGIN
--// Get the Promo Code
DECLARE @PromoCode int;
EXEC GetPromoCode @PromoCode OUTPUT;
--// update the order with the new Promo Code
UPDATE Order SET PromoCode = @PromoCode
WHERE ID IN (SELECT ID FROM inserted)
END
答案 1 :(得分:0)
INSERTED是一个只读临时表,可以在任何触发器中访问。你不能修改它。
您使用INSERT的方式是最好的方法。所以,它没有任何问题。在执行INSERT时指定列是很好的(根据我的说法)。
答案 2 :(得分:-2)
动态SQL将是您唯一的其他选择。试试这个:
CREATE TRIGGER PopulateOrderPromoCode
ON Order
INSTEAD OF INSERT
AS
BEGIN
--// Get the Promo Code
DECLARE @PromoCode int;
EXEC GetPromoCode @PromoCode OUTPUT;
DECLARE @InsertSQL nvarchar(2000), @SelectSQL nvarchar(2000)
SET @InsertSQL = 'INSERT INTO Order ('
SET @SelectSQL = 'SELECT '
DECLARE @CurrentCol sysname
SET @CurrentCol = ''
WHILE EXISTS ( SELECT TOP 1 QUOTENAME(name)
FROM sys.syscolumns
WHERE object_name(id) = 'Order'
AND name <> 'PromoCode'
AND name > @CurrentCol)
BEGIN
SET @CurrentCol = ( SELECT TOP 1 QUOTENAME(name)
FROM sys.syscolumns
WHERE object_name(id) = 'Order'
AND name <> 'PromoCode'
AND QUOTENAME(name) > @CurrentCol
ORDER BY name)
IF @CurrentCol IS NULL Break;
SET @InsertSQL = @InsertSQL + @CurrentCol + ', '
SET @SelectSQL = @SelectSQL + @CurrentCol + ', '
END
--Finish and concatenate the strings
SET @InsertSQL = @InsertSQL + 'PromoCode) '
SET @SelectSQL = @SelectSQL + '''' + @PromoCode + '''' + ' FROM INSERTED'
DECLARE @MasterSQL nvarchar(2000)
SET @MasterSQL = @InsertSQL + @SelectSQL
EXEC (@MasterSQL)
END
BTW - “order”对于表名来说是一个糟糕的选择 - 它也是SQL中的保留字。尝试订单或OrderHeader。