Jam*_*mes 11 sql sql-server-2008
我使用SQL Server 2008,我有两个现有的表,venues和events.
我正在尝试使用检查约束创建自定义函数,以确保表中event_expected_attendance列中的整数events始终小于或等于表中的venue_max_capacity整数venues.
我正在努力使用自定义函数的语法以及join语句,因为检查约束在两个表之间.
谢谢您的帮助!我会尽快回答任何其他问题.
jpw*_*jpw 16
正如Martin Smith所说,使用UDF的检查约束有一些问题,可能会对性能产生负面影响,但是如果你想尝试它,那么这段代码应该可以工作:
CREATE FUNCTION dbo.CheckVenueCapacity (@venue_id int, @capacity int)
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = CASE WHEN venue_max_capacity >= @capacity THEN 0 ELSE 1 END
FROM venues
WHERE venue_id = @venue_id
RETURN @retval
END;
GO
ALTER TABLE events
ADD CONSTRAINT chkVenueCapacity
CHECK (dbo.CheckVenueCapacity(event_venue_id, event_expected_attendance) = 0);
Run Code Online (Sandbox Code Playgroud)
Mar*_*ith 12
您可以使用标量UDF,但在检查约束中使用那些已经记录良好的问题(例如,查看包含在CHECK约束中的标量UDF非常慢,并且可能因多行更新或快照隔离而失败:对完整性的威胁?系列.
也可以让数据库引擎使用索引视图来强制执行此操作
它需要一个包含2行作为CTE的辅助表,并且UNION在索引视图中不允许使用.我们的想法是视图定义应始终返回零行,如果存在违规,则会将所返回的行加倍.因此导致违反视图上的唯一约束并导致错误发生并且语句失败.
CREATE TABLE dbo.TwoNums
(
Num INT PRIMARY KEY
)
INSERT INTO dbo.TwoNums
VALUES (1),
(2)
Run Code Online (Sandbox Code Playgroud)
然后是视图定义
CREATE VIEW dbo.PreventOverCapacity
WITH SCHEMABINDING
AS
SELECT V.Venueid,
E.EventId,
E.Expected,
V.Capacity
FROM dbo.Venues V
JOIN dbo.Events E
ON E.venueid = V.venueid
AND E.Expected > V.Capacity
CROSS JOIN dbo.TwoNums
Run Code Online (Sandbox Code Playgroud)
并且View上有一个独特的索引
CREATE UNIQUE CLUSTERED INDEX [UIX_PreventOverCapacity (Venueid, EventId, Expected, Capacity)]
ON dbo.PreventOverCapacity(Venueid, EventId, Expected, Capacity)
Run Code Online (Sandbox Code Playgroud)
包含所有四列的原因是所有必需的值都显示在错误消息中.
无法在对象'dbo.PreventOverCapacity'中插入具有唯一索引'UIX_PreventOverCapacity(Venueid,EventId,Expected,Capacity)'的重复键行.
重复键值为(1,97,110,100).