SQL Server中的约束,其中Col1中的值只能有有限的Col2中的值选择
根据C1的值,我希望能够插入Col2的字符串的选择数量有限。以下代码用于澄清SQL Server中的约束,其中Col1中的值只能有有限的Col2中的值选择,sql,sql-server,tsql,constraints,Sql,Sql Server,Tsql,Constraints,根据C1的值,我希望能够插入Col2的字符串的选择数量有限。以下代码用于澄清 CREATE TABLE [dbo].[tester] ( [C1] [varchar](50) NULL, [C2] [varchar](50) NULL ) ON [PRIMARY] INSERT INTO [dbo].[tester] ([C1], [C2]) VALUES ('ADDRESS', 'Primary') GO 对于字符串'address',我只想给column2一个字符串'pr
CREATE TABLE [dbo].[tester]
(
[C1] [varchar](50) NULL,
[C2] [varchar](50) NULL
) ON [PRIMARY]
INSERT INTO [dbo].[tester] ([C1], [C2])
VALUES ('ADDRESS', 'Primary')
GO
对于字符串'address',我只想给column2一个字符串'primary','secondary','home'的选择
INSERT INTO [dbo].[tester] ([C1], [C2])
VALUES ('phone', 'home')
GO
使用字符串“phone”,我想让第2列只能选择“休闲”、“工作”、“商务”。您可以使用
CASE
语句,并将其放入TRY CATCH
如您所见,我将表中的列设置为不接受NULL
值
DECLARE @tester TABLE
(
[C1] [varchar](50) NOT NULL,
[C2] [varchar](50) NOT NULL
)
DECLARE @col1 VARCHAR(20) = 'ADDRESS' , @col2 VARCHAR(20) = 'work'
BEGIN TRY
INSERT @tester
SELECT CASE WHEN @col1 = 'address' AND @col2 IN ('primary', 'secondary', 'home') THEN @col1
WHEN @col1 = 'phone' AND @col2 IN ('leisure', 'work', 'business') THEN @col1 ELSE NULL END
,CASE WHEN @col1 = 'address' AND @col2 IN ('primary', 'secondary', 'home') THEN @col2
WHEN @col1 = 'phone' AND @col2 IN ('leisure', 'work', 'business') THEN @col2 ELSE NULL END
END TRY
BEGIN CATCH
END CATCH
SELECT * FROM @tester
通常,您会有两个单独的表
AddressTypes
和PhoneTypes
,但如果您坚持,您可以使用constraint并在其中写入允许的选项:
CREATE TABLE [dbo].[tester](
[C1] [varchar](50) NULL,
[C2] [varchar](50) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
ALTER TABLE [dbo].[tester] WITH CHECK ADD CONSTRAINT [CK_Rules] CHECK
(
([C1]='address' AND [C2] IN ('home', 'secondary', 'primary')) OR
([C1]='phone' AND [C2] IN ('leisure', 'work', 'business'))
)
GO
ALTER TABLE [dbo].[tester] CHECK CONSTRAINT [CK_Rules]
GO
测试
INSERT INTO [dbo].[tester] ([C1],[C2]) VALUES
('address', 'home'),
('address', 'primary'),
('phone', 'business');
返回:
(3 row(s) affected)
The INSERT statement conflicted with the CHECK constraint "CK_Rules".
The conflict occurred in database "AdventureWorks2014", table "dbo.tester".
The statement has been terminated.
但是
返回:
(3 row(s) affected)
The INSERT statement conflicted with the CHECK constraint "CK_Rules".
The conflict occurred in database "AdventureWorks2014", table "dbo.tester".
The statement has been terminated.
如果不想更改表结构,请参阅其他两个答案 不过,更好的处理方法是创建一个包含可能的组合的表。示例(可以更好地选择名称): 用cat+sub填充表格,然后允许使用
联系人样式的组合
:
INSERT INTO contact_cat(id,desc)VALUES(1,'Address');
INSERT INTO contact_cat(id,desc)VALUES(2,'Phone');
INSERT INTO contact_sub(id,desc)VALUES(1,'Primary');
INSERT INTO contact_sub(id,desc)VALUES(2,'Leisure');
INSERT INTO contact_style(cat_id,sub_id)VALUES(1,1); -- Address + Primary
INSERT INTO contact_style(cat_id,sub_id)VALUES(2,2); -- Phone + Leisure
向检测仪添加信息:
INSERT INTO tester(cat_id,sub_id,information)VALUES(1,1,'NY, 120 Boulevard Av'); -- succeeds
INSERT INTO tester(cat_id,sub_id,information)VALUES(2,2,'555 77 88 99'); -- succeeds
INSERT INTO tester(cat_id,sub_id,information)VALUES(1,2,'Blablabla'); -- fails
INSERT INTO tester(cat_id,sub_id,information)VALUES(2,1,'More blah'); -- fails
前两条语句成功,因为外键存在于contact\u style
中允许的联系人样式中。最后两个失败是因为外键不存在于contact\u style
中
这种工作方式的好处:
- 无需每次重复联系人类别+子类别描述
- 将这些表缓存在内存中时,可以节省磁盘空间和内存;表尽可能缓存在SQL Server中,以加快查询响应
- 当需要新类别或子类别时,不必重写任何约束(参见其他答案)。只需在适当的表中为新的cat/SUBACT添加行,将行添加到
以反映新的组合和prestocontact_style