是否可以根据其他两个表中的条件添加检查约束?我有三个表:集合,会话和session_detail。我的目标是从同一个集合中使用相同的会话类型阻止多个结构出现在session_detail中。
将我到目前为止的功能应用于 sessions 表检查唯一的集合和会话,但不检查唯一的结构。
ALTER FUNCTION [dbo].[checkSessionType](@collection as varchar(max), @type as varchar(max))
RETURNS int
AS
BEGIN
DECLARE @sessionType varchar(max)
SELECT @sessionType = case when @type = 'R' then @type When @type = 'T' then @type END
DECLARE @retval int
SELECT @retval = COUNT(*)
FROM (SELECT a.structure_id, b.collection, b.session_type
FROM session_detail a
INNER JOIN sessions b ON a.session_id = b.session_id
WHERE b.collection = @collection
AND b.session_Type = @sessionType
) AS tempResults
RETURN @retval
END;
这是表格的简化版本:
collections(collection)
sessions(session_id, collection, session_type)
session_detail(detail_id, session_id, structure_id)
那么,只要具有不同的会话类型,我怎么能让结构多次出现在同一个集合中呢?我可以用触发器做这个,但我更喜欢约束。
答案 0 :(得分:2)
您可以使用索引视图,例如:
CREATE VIEW v_session_detail
WITH SCHEMABINDING AS
SELECT sd.structure_id, s.collection, s.session_type
FROM dbo.session_detail sd
INNER JOIN dbo.sessions s ON s.session_id=sd.session_id
GO
CREATE UNIQUE CLUSTERED INDEX PK_v_session_detail ON v_session_detail(structure_id, collection, session_type)
答案 1 :(得分:1)
如果您想将控制作为检查约束:
CREATE FUNCTION [dbo].[checkSessionType](@session_id as INT, @structure_id as INT)
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = COUNT(*)
FROM sessions a
INNER JOIN session_detail b ON a.session_id = b.session_id
WHERE b.structure_id = @structure_id
AND b.session_id = @session_id
GROUP BY a.collection, a.session_type, b.structure_id
RETURN @retval
END
GO
ALTER TABLE [session_detail] ADD CONSTRAINT ck_session_detail CHECK ([dbo].[checkSessionType](session_id, structure_id) <= 1)
同样,您还需要在sessions
表上进行检查。为此,您可以创建另一个函数,仅用于检查sessions
表或自定义上一个表以适应两种情况:
CREATE FUNCTION [dbo].[checkSessionType](@session_id as INT, @collection as INT, @structure_id as INT)
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = COUNT(*)
FROM sessions a
INNER JOIN session_detail b ON a.session_id = b.session_id
WHERE b.structure_id = ISNULL(@structure_id, b.structure_id)
AND a.collection = ISNULL(@collection, a.collection)
AND b.session_id = @session_id
GROUP BY a.collection, a.session_type, b.structure_id
RETURN @retval
END
GO
ALTER TABLE [sessions] ADD CONSTRAINT ck_sessions CHECK ([dbo].[checkSessionType](session_id, collection, null) <= 1)
ALTER TABLE [session_detail] ADD CONSTRAINT ck_session_detail CHECK ([dbo].[checkSessionType](session_id, null, structure_id) <= 1)