sql-server - 列上的 MS SQL 约束
问题描述
我有一个名为 Products 的表,这就是它的样子,我正在尝试在 [IsDefaultProductKey] 列上创建一个约束,只要向其中添加一个值,它就必须是一个活动的产品密钥。
CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultProductKey] [int] NULL,
CONSTRAINT [PK_dbo.Products] PRIMARY KEY CLUSTERED
(
[ProductId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Products] ADD CONSTRAINT [DF_products_IsActive] DEFAULT ((1)) FOR [IsActive]
GO
ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Product_IsDefaultProductKey] FOREIGN KEY([IsDefaultProductKey])
REFERENCES [dbo].[Products] ([ProductId])
GO
ALTER TABLE [dbo].[Products] CHECK CONSTRAINT [FK_Products_Product_IsDefaultProductKey]
GO
如果这些是表中的条目,则不应允许第 4 行的值为 1,因为 1 是不活动的。我如何才能为此在表上添加约束
ProductId Name IsActive IsDefaultProductKey
1 Test1 0 NULL
2 Test2 1 NULL
3 Test3 0 2
4 Test4 0 1 (Should not let me do this)
根据建议,我创建了这个 UDF。但仍然没有按照我想要的方式 100% 行事。请提出建议。
CREATE TABLE [dbo].[Products]( [ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultProductKey] [int] NULL,
)
go
Create FUNCTION dbo.CheckProduct (@IsDefaultProductKey int)
RETURNS int
AS
BEGIN
DECLARE @retval int
SELECT @retval = 0
Select @retval = 1
FROM [Products]
WHERE ProductId = @IsDefaultProductKey and IsActive = 1
RETURN @retval
END;
GO
--Select CheckProduct(1)
ALTER TABLE [Products]
ADD CONSTRAINT chkActiveProduct
CHECK (IsDefaultProductKey = null or dbo.CheckProduct(IsDefaultProductKey) = 1);
go
解决方案
您可以使用调用 UDF 的 CHECK CONSTRAINT 来查询表以查看所引用的 ProductId 是否处于IsDefaultProductKey
活动状态。
编辑:
由于您需要约束来检查两种方式,您将创建一个具有参数的ProductId
UDFIsActive
和IsDefaultProductKey
。
在函数内部,如果 有非 NULL 值IsDefaultProductKey
,则需要查询表以查看具有该值的行是否ProductId
为 Active。如果不是,则该函数需要返回false
。
此外,如果IsActive
参数传递的值为 0,那么您需要检查表以确保没有行IsDefaultProductKey
与参数的值相等ProductId
。如果有这样一行,那么函数需要返回false
。
但如果这两种情况都没有发生,则函数返回true
,然后在 CHECK CONSTRAINT 中,您只需测试函数是否返回true
。
推荐阅读
- python - 无法使用 pyinstaller 将我的 .py 文件打包成 .exe 文件
- c# - 如何修复“每个表只能配置一列'Identity'。在Ef Core和Oracle中调用'ValueGeneratedNever'......
- laravel - Laravel:如何使用模型运行之外的数据创建 groupBy 并使用 where claus
- python - 根据 lambda 函数将 NumPy 整数列表值映射到列表
- vue.js - 无法即时更改过渡组的过渡
- java - 将密钥标识符作为 X509SubjectKeyIdentifier 签名失败的 SOAP XML WS-Security
- django - Django 使用略有不同的模板发送邮件
- encoding - 用于编码“UTF8”的无效字节序列:当我尝试使用 FormData 对象向服务器发布和图像时出现 0x00 响应
- c# - 命名空间“Microsoft”中不存在类型或命名空间名称“AspNetCore”(您是否缺少程序集引用?)
- python - 输入一次而不是多次询问