【发布时间】:2015-06-02 13:29:13
【问题描述】:
我有两个表:表 A 和表 B。这两个表通过 A 中的主键和 B 中的外键链接。
表 A:
CREATE TABLE [BIO].[table_A](
[table_A_id] [int] IDENTITY(1,1) NOT NULL,
[type_id] [nvarchar](2) NOT NULL
CONSTRAINT [PK_table_A] PRIMARY KEY CLUSTERED
(
[table_A_id] ASC
))
表 B:
CREATE TABLE [BIO].[table_B](
[table_B_id] [int] IDENTITY(1,1) NOT NULL,
[table_A_id] [int] NOT NULL,
[analysis_id] [tinyint] NOT NULL
CONSTRAINT [PK_table_B] PRIMARY KEY CLUSTERED
(
[table_B_id] ASC
))
ALTER TABLE [BIO].[table_B] WITH CHECK
ADD CONSTRAINT [FK_table_B_table_A] FOREIGN KEY([table_A_id])
REFERENCES [BIO].[table_A] ([table_A_id])
GO
ALTER TABLE [BIO].[table_B] CHECK CONSTRAINT [FK_table_B_table_A]
GO
表 B 必须仅包含根据表 A 中的值的特定值。 比如我A表有BL,B表只能有1或3;如果我在 A 表中有 ST,我在 B 表中只能有 2 或 4 个。
我已经设置了一个桥接表,它定义了这些组合:BL→1 或 3,ST→2 或 4。
桥牌桌:
CREATE TABLE [QRY].[bridge_table](
[type_id] [nvarchar](2) NOT NULL,
[analysis_id] [tinyint] NOT NULL,
CONSTRAINT [PK_bridge_table] PRIMARY KEY CLUSTERED
(
[type_id] ASC,
[analysis_id] ASC
))
我目前对每个表使用一个约束,以确保根据桥表中定义的组合,任何插入或更新都是正确的。这两个约束基于 UDF。
对表 B 的约束:
ALTER TABLE [BIO].[Table_B] WITH CHECK
ADD CONSTRAINT [CK_chkAnalysisType]
CHECK (([QRY].[TypeAnalysisMatch_table_B]([table_A_id])>(0)))
GO
UDF:
CREATE FUNCTION [QRY].[TypeAnalysisMatch_table_B] (@table_A_id int)
RETURNS int
AS
BEGIN
RETURN
(
SELECT
Count(BIO.table_A.table_A_id) AS cnt_rec
FROM
QRY.bridge_table
INNER JOIN BIO.table_A ON QRY.bridge_table.type_id = BIO.table_A.type_id
INNER JOIN BIO.table_B ON
QRY.bridge_table.analysis_id = BIO.table_B.analysis_id
AND BIO.table_A.table_A_id = BIO.table_B.table_A_id
WHERE
BIO.table_A.table_A_id = @table_A_id
)
END
它适用于INSERT,但不适用于UPDATE。此外,当我读到应避免使用约束中的 UDF 时,我正在寻找更好的解决方案。
什么是这些约束的有效替代方案?
【问题讨论】:
-
请编辑您的问题以包含一些示例数据的 ddl+dml。另外,包括您当前使用的 UDF。
-
@ZoharPeled:使用数据定义编辑的问题。谢谢
标签: sql-server sql-server-2008-r2 constraints user-defined-functions