Microsoft SQL 服务器:使用生成的名称检查约束
Microsoft SQL Server : check constraint with generated name
在 T-SQL 中,通常最好命名您创建的所有约束,包括检查约束。
alter table mytable with check
add constraint myconstraint check (mycol > 0)
如果您不提供明确的名称 (myconstraint
),则服务器将为您生成一个唯一的名称,这在错误消息中不是特别可读。
或者每个人都这么说。但是是否有可能获得这个生成的检查约束名称?外键约束和唯一约束我都看过,但是我不知道如何在不指定名称的情况下创建检查约束。
如果我在上面的T-SQL中漏掉了名字myconstraint
,那是语法错误。
我问的原因是在 tempdb 中检查约束。临时 table 的名称是按会话命名的,因此调用您的 table #x
没有问题。您可以在多个不同的程序(或同一程序的多个实例 运行ning 并发)中使用该名称,并且它们不会发生冲突。只有全局临时 tables(如 ##x
)需要具有全局唯一名称。
但是,约束名称在 tempdb 中必须是唯一的,而不是每个会话。因此,如果您给它们起一个可读的名称,您 运行 就有在其他连接中与相同名称发生冲突的风险。您需要做一些事情来使其在全球范围内独一无二,要么在客户端粘贴一些垃圾内容,要么求助于动态 SQL。我非常希望不指定名称并让服务器处理命名约束的工作,就像我在临时 tables.
上创建唯一索引时已经发生的那样
如何在不指定名称的情况下创建检查约束?
Microsoft SQL Server 2016 (SP2-CU15-GDR) (KB4583461) - 13.0.5865.1 (X64)
也许您的语法有误(您没有向我们展示)。简直
ALTER TABLE elbat
WITH CHECK
ADD CHECK (nmuloc = 1);
应该可以正常工作,SQL服务器将生成一个名称。
当您显式创建 CONSTRAINT
时,您 必须 指定一个名称。当您隐式创建一个 CONSTRAINT
时,您会得到一个具有自动名称的
取下面的DDL语句:
CREATE TABLE dbo.MyTable (ID int IDENTITY PRIMARY KEY,
SomeDate date DEFAULT GETDATE(),
SomeInt int DEFAULT 1 CHECK (SomeInt> 0));
上面创建了一个 table,有 3 列,还有 4 CONSTRAINT
s。这些约束是:
ID
上的主键约束
SomeDate
的默认约束
SomeInt
、 上的默认约束
SomeInt
上的检查约束。
我们可以通过查看 sys
个对象来验证这一点:
SELECT N'Key Constraint', [name] AS ConstraintName
FROM sys.key_constraints kc
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable')
UNION ALL
SELECT N'Default Constraint', [name] AS ConstraintName
FROM sys.default_constraints
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable')
UNION ALL
SELECT N'Check Constraint', [name] AS ConstraintName
FROM sys.check_constraints
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable');
当我运行这个时,生成的名字是:
Constraint Type
Constraint Name
Key Constraint
PK__MyTable__3214EC27B4E6D2B3
Default Constraint
DF__MyTable__SomeDat__6A33284E
Check Constraint
CK__MyTable__SomeInt__6B274C87
但这并不意味着您在 table 的 DDL 中创建 CONSTRAINT
时不能显式提供名称。如果您想将它们定义为列的一部分,它将如下所示:
CREATE TABLE dbo.OtherTable (ID int IDENTITY CONSTRAINT PK_OtherTable PRIMARY KEY,
SomeDate date CONSTRAINT DF_OtherTable_SomeDate DEFAULT GETDATE(),
SomeInt int CONSTRAINT DF_OtherTable_SomeInt DEFAULT 1
CONSTRAINT chk_OtherTable_SomeInt CHECK (SomeInt> 0));
在 T-SQL 中,通常最好命名您创建的所有约束,包括检查约束。
alter table mytable with check
add constraint myconstraint check (mycol > 0)
如果您不提供明确的名称 (myconstraint
),则服务器将为您生成一个唯一的名称,这在错误消息中不是特别可读。
或者每个人都这么说。但是是否有可能获得这个生成的检查约束名称?外键约束和唯一约束我都看过,但是我不知道如何在不指定名称的情况下创建检查约束。
如果我在上面的T-SQL中漏掉了名字myconstraint
,那是语法错误。
我问的原因是在 tempdb 中检查约束。临时 table 的名称是按会话命名的,因此调用您的 table #x
没有问题。您可以在多个不同的程序(或同一程序的多个实例 运行ning 并发)中使用该名称,并且它们不会发生冲突。只有全局临时 tables(如 ##x
)需要具有全局唯一名称。
但是,约束名称在 tempdb 中必须是唯一的,而不是每个会话。因此,如果您给它们起一个可读的名称,您 运行 就有在其他连接中与相同名称发生冲突的风险。您需要做一些事情来使其在全球范围内独一无二,要么在客户端粘贴一些垃圾内容,要么求助于动态 SQL。我非常希望不指定名称并让服务器处理命名约束的工作,就像我在临时 tables.
上创建唯一索引时已经发生的那样如何在不指定名称的情况下创建检查约束?
Microsoft SQL Server 2016 (SP2-CU15-GDR) (KB4583461) - 13.0.5865.1 (X64)
也许您的语法有误(您没有向我们展示)。简直
ALTER TABLE elbat
WITH CHECK
ADD CHECK (nmuloc = 1);
应该可以正常工作,SQL服务器将生成一个名称。
当您显式创建 CONSTRAINT
时,您 必须 指定一个名称。当您隐式创建一个 CONSTRAINT
时,您会得到一个具有自动名称的
取下面的DDL语句:
CREATE TABLE dbo.MyTable (ID int IDENTITY PRIMARY KEY,
SomeDate date DEFAULT GETDATE(),
SomeInt int DEFAULT 1 CHECK (SomeInt> 0));
上面创建了一个 table,有 3 列,还有 4 CONSTRAINT
s。这些约束是:
ID
上的主键约束
SomeDate
的默认约束
SomeInt
、 上的默认约束
SomeInt
上的检查约束。
我们可以通过查看 sys
个对象来验证这一点:
SELECT N'Key Constraint', [name] AS ConstraintName
FROM sys.key_constraints kc
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable')
UNION ALL
SELECT N'Default Constraint', [name] AS ConstraintName
FROM sys.default_constraints
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable')
UNION ALL
SELECT N'Check Constraint', [name] AS ConstraintName
FROM sys.check_constraints
WHERE parent_object_id = OBJECT_ID(N'dbo.MyTable');
当我运行这个时,生成的名字是:
Constraint Type | Constraint Name |
---|---|
Key Constraint | PK__MyTable__3214EC27B4E6D2B3 |
Default Constraint | DF__MyTable__SomeDat__6A33284E |
Check Constraint | CK__MyTable__SomeInt__6B274C87 |
但这并不意味着您在 table 的 DDL 中创建 CONSTRAINT
时不能显式提供名称。如果您想将它们定义为列的一部分,它将如下所示:
CREATE TABLE dbo.OtherTable (ID int IDENTITY CONSTRAINT PK_OtherTable PRIMARY KEY,
SomeDate date CONSTRAINT DF_OtherTable_SomeDate DEFAULT GETDATE(),
SomeInt int CONSTRAINT DF_OtherTable_SomeInt DEFAULT 1
CONSTRAINT chk_OtherTable_SomeInt CHECK (SomeInt> 0));