感谢您的光临。我正在尝试编写一个SQL Server触发器,当添加包含日期信息的新记录时,会将星期几添加到DayOfWeek列中。这是我的表,按顺序排列各列:
食物表:
FoodName **varchar(20)**
CategoryID (FK) **int**
Price **smallmoney**
StoreID (FK) **int**
Date **datetime**
DayOfWeek **varchar(9)**
ShopperID (FK) **int**
Week **int**
这是我写的触发器:
-- Create a trigger to update day of the week when a record is inserted
CREATE TRIGGER DOW
ON Food
FOR INSERT
AS
BEGIN
-- Declare a variable to hold the date ID
DECLARE @dateID DATETIME
-- Get the date from the new record and store it in @dateID
SELECT @dateID = Date FROM Food
-- Insert day of the week based on the inserted date
INSERT INTO Food (DayOfWeek)
SELECT DATENAME(dw, @dateID)
END
GO
SQL Server似乎接受该过程,但是当我运行另一个过程以插入新记录时,出现此错误:
信息515,级别16,状态2,过程DOW,第8行[批处理开始第21行]
无法将值NULL插入表*******的“周”列中;列不允许为空。 INSERT失败。
我不确定为什么此触发器完全影响“周”列。代码应采用为Date输入的值,并使用DATENAME(dw,...)函数返回星期几,该日期应进入DayOfWeek列。我编写了一个存储过程,该存储过程接受日期作为输入并将相应的星期几插入记录中,并且工作正常,但是此触发器似乎不希望合作。我很困惑!
答案 0 :(得分:0)
触发器的作用:
Date
,不一定是最后插入的值。DayOfWeek
中的Date
的新记录。Week
。我猜您想改为为插入的行更新DayOfWeek
的值。为此,必须有一种方法可以通过了解插入的行的值来标识“食物”表中需要更新的行。为了确保更新正确的行,应该有一个主键可以让您识别它们。当然,您具有这样的主键,而且我猜它的名称为FoodID
,所以您可能想这样做:
CREATE TRIGGER DOW ON Food
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
-- update the day of the week for the inserted rows
UPDATE Food
SET [DayOfWeek] = DATENAME(dw, f.[Date])
FROM Food f
INNER JOIN inserted i ON f.FoodID = i.FoodID
END
GO
答案 1 :(得分:0)
触发器存在一些重大问题。在触发器中,有一个插入的表(在插入和更新时)和已删除的表(在删除和更新时)。您应该使用此表的信息来了解需要更新哪些记录。
This is bad because a trigger can have multiple rows
This SQL simply will not work correctly if you insert multiple rows.
DECLARE @dateID DATETIME
SELECT @dateID = Date FROM Food
This SQL is trying to insert a new row which is causing your NULL error
It is not trying to update the row you are inserting
INSERT INTO Food (DayOfWeek)
SELECT DATENAME(dw, @dateID)
它必须是INSTEAD OF触发器,以避免对列的空约束。沃尔夫冈的答案仍将导致空约束错误,因为在触发器运行之后插入数据之后,就会发生空约束错误。 INSTEAD OF触发器将代替实际的插入物运行。
CREATE TRIGGER DOW ON Food
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
-- update the day of the week for the inserted rows
INSERT INTO Food (FoodName,CategoryID,Price,StoreID,[Date],ShopperID,[Week],[DayOfWeek])
SELECT
FoodName,CategoryID,Price,StoreID,[Date],ShopperID,[Week],DATENAME(dw, [Date]) AS [DayOfWeek]
FROM inserted
END
GO
就个人而言,我认为存储星期和星期几是个坏主意。您已经有一个可以派生该信息的值(日期)。每当您有多个本质上是重复数据的列时,您都会遇到维护难题。