Sql server 2008 在检查约束中选择
我想为我的表创建一个检查约束,如果新的预订范围开始日期、结束日期与已提交的行相交,则不能添加新行。 但我不能将查询置于检查约束中。你知道怎么做吗 各表:Sql server 2008 在检查约束中选择,sql-server-2008,check-constraints,Sql Server 2008,Check Constraints,我想为我的表创建一个检查约束,如果新的预订范围开始日期、结束日期与已提交的行相交,则不能添加新行。 但我不能将查询置于检查约束中。你知道怎么做吗 各表: APARTMAN id INT price INT BOOKINGS id INT start_date DATE end_date DATE apartman_id INT [apartman_id] IN (SELECT [id] FR
APARTMAN
id INT
price INT
BOOKINGS
id INT
start_date DATE
end_date DATE
apartman_id INT
[apartman_id] IN (SELECT [id] FROM [dbo].[APARTMAN]
WHERE [id] NOT IN (
SELECT [apartman_id] FROM
[dbo].[BOOKINGS]
WHERE
([start_date] <= "requested end_date" AND
[end_date] >= "requested start_date" )
OR
([start_date] <= "requested start_date" AND
[end_date] >= "requested end_date" )
OR
(([start_date] <= "requested end_date" AND [end_date] >= "requested start_date" )
OR
([end_date] <= "requested start_date" AND [end_date] >= "requested end_date" ))
)
)
这里有一个替代触发器,我认为它可以处理所有场景
CREATE TRIGGER dbo.PreventOverlappingBookings
ON dbo.BOOKINGS INSTEAD OF INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT 1 FROM inserted AS i
INNER JOIN dbo.BOOKINGS AS b
ON (b.id <> i.id OR i.id = 0) -- 0 for insert
AND b.apartman_id = i.apartman_id
AND ((b.start_date <= i.end_date AND b.end_date >= i.start_date)
OR (b.start_date <= i.start_date AND b.end_date >= i.end_date)
OR (b.end_date <= i.start_date AND b.end_date >= i.end_date))
) OR EXISTS (
-- also make sure there are no overlaps in a set-based insert/update
SELECT 1 FROM inserted AS i
INNER JOIN inserted AS b
ON (b.id <> i.id OR i.id = 0) -- 0 for insert
AND b.apartman_id = i.apartman_id
AND ((b.start_date <= i.end_date AND b.end_date >= i.start_date)
OR (b.start_date <= i.start_date AND b.end_date >= i.end_date)
OR (b.end_date <= i.start_date AND b.end_date >= i.end_date))
)
BEGIN
RAISERROR('Overlapping date range.', 11, 1);
END
ELSE
BEGIN
UPDATE b SET start_date = i.start_date, end_date = i.end_date
FROM dbo.BOOKINGS AS b
INNER JOIN inserted AS i
ON b.id = i.id;
IF @@ROWCOUNT > 0
BEGIN
INSERT dbo.BOOKINGS(start_date, end_date, apartman_id)
SELECT start_date, end_date, apartman_id FROM inserted AS i;
END
END
END
GO
有一些答案,但是。从另一个角度来看,通过存储过程进行插入是否可以接受?我建议使用触发器而不是表级约束。你也必须保护更新吗?@hotcips你不能真正使用存储过程来保护数据,因为人们不需要通过存储过程就可以访问表。当然,人们也可以禁用触发器,但这是故意的恶意,如果这是最坏的事情,有这么多特权伤害你的数据库,认为自己相当幸运。您也可以使用存储过程,但它们不应该是唯一的防线。