如何检查DATE
中inserted
updated
或table
是否介于另一个表的two other dates
之间。
网络信息
我有2 tables
:
Activity
:
StartDate
日期非空 EndDate
日期 NULLABLE
SubActivity
:
SubActivityDate
日期非空
我
EndDate IS NOT NULL
时检查:StartDate
是否SubActivityDate
≤EndDate
EndDate IS NULL
时,我会检查:StartDate
是否为SubActivityDate
我试图写一个 BEFORE INSERT触发器,但我发现它不存在。
那么我能做什么?
如何解决这个问题?
我刚接受 CHECK约束 + 功能:
约束:
ALTER TABLE SubActivity
ADD CONSTRAINT CK_SubActivity_Date CHECK (dbo.ufnIsSubactivityDateValid(ActivityID, SubActivityDate) = 1);
功能
CREATE FUNCTION ufnIsSubactivityDateValid(@ActivityID [int], @SubActivityDate [date])
RETURNS [bit]
AS
BEGIN
DECLARE @StartDate date, @EndDate date;
SELECT @StartDate = StartDate , @EndDate = EndDate
FROM Activity
WHERE ActivityID = @ActivityID;
IF (@SubActivityDate < @StartDate )
RETURN 0; -- out of range date
IF (@EndDate IS NULL)
RETURN 1; -- good date
ELSE
IF (@SubActivityDate > @EndDate)
RETURN 0; -- out of range date
RETURN 1; -- good date
END
答案 0 :(得分:0)
最好的情况是情况。约束保证正确的值,但在一个错误的值上回滚整个事务。触发器允许您进行更多控制,但由于它更复杂。
IF OBJECT_ID('dbo.yourTable') IS NOT NULL
DROP TABLE yourTable;
CREATE TABLE yourTable
(
ID INT IDENTITY(1,1) PRIMARY KEY,
StartDate DATE NOT NULL,
SubActivityDate DATE NULL,
EndDate DATE NULL
);
INSERT INTO yourTable(StartDate,SubActivityDate,EndDate)
VALUES ('20150101',NULL,NULL),
('20150101',NULL,NULL),
('20150101',NULL,'20150201'),
('20150101',NULL,'20150201');
ALTER TABLE yourTable
ADD CONSTRAINT chk_date CHECK (StartDate <= SubActivityDate AND SubActivityDate <= EndDate);
UPDATE yourTable
SET SubActivityDate = CASE
WHEN ID = 1 THEN '20140101' --bad
WHEN ID = 2 THEN '20150102' --good
WHEN ID = 3 THEN '20140101' --bad
WHEN ID = 4 THEN '20150102' --good
END
SELECT *
FROM yourTable;
由于至少存在不符合约束的值,因此将回滚整个事务,结果是SubActivitDate保持为NULL。
结果:
ID StartDate SubActivityDate EndDate
----------- ---------- --------------- ----------
1 2015-01-01 NULL NULL
2 2015-01-01 NULL NULL
3 2015-01-01 NULL 2015-02-01
4 2015-01-01 NULL 2015-02-01
CREATE TRIGGER trg_check_date ON yourTable
INSTEAD OF UPDATE
AS
BEGIN
UPDATE yourTable
SET SubActivityDate = CASE
WHEN inserted.SubActivityDate >= inserted.StartDate AND ((Inserted.EndDate IS NULL) OR Inserted.SubActivityDate <= Inserted.EndDate) THEN inserted.SubActivityDate
ELSE NULL
END
FROM yourTable
INNER JOIN inserted
ON yourTable.ID = inserted.ID
END;
GO
UPDATE yourTable
SET SubActivityDate = CASE
WHEN ID = 1 THEN '20140101' --bad
WHEN ID = 2 THEN '20150102' --good
WHEN ID = 3 THEN '20140101' --bad
WHEN ID = 4 THEN '20150102' --good
END
SELECT *
FROM yourTable
此方法允许使用正确的值,并为不正确的值返回null。如果需要,您甚至可以将插入表中的错误值导出到日志表中,以便了解哪些不起作用。或者引发错误消息并列出不起作用的值。简而言之,您完全可以控制局势。
结果:
ID StartDate SubActivityDate EndDate
----------- ---------- --------------- ----------
1 2015-01-01 NULL NULL
2 2015-01-01 2015-01-02 NULL
3 2015-01-01 NULL 2015-02-01
4 2015-01-01 2015-01-02 2015-02-01
答案 1 :(得分:0)
<强>约束:强>
ALTER TABLE SubActivity
ADD CONSTRAINT CK_SubActivity_Date CHECK (dbo.ufnIsSubactivityDateValid(ActivityID, SubActivityDate) = 1);
<强>功能强>
CREATE FUNCTION ufnIsSubactivityDateValid(@ActivityID [int], @SubActivityDate [date])
RETURNS [bit]
AS
BEGIN
DECLARE @StartDate date, @EndDate date;
SELECT @StartDate = StartDate , @EndDate = EndDate
FROM Activity
WHERE ActivityID = @ActivityID;
IF (@SubActivityDate < @StartDate )
RETURN 0; -- out of range date
IF (@EndDate IS NULL)
RETURN 1; -- good date
ELSE
IF (@SubActivityDate > @EndDate)
RETURN 0; -- out of range date
RETURN 1; -- good date
END