Sql 在CREATETABLE语句中使用用户定义的函数

Sql 在CREATETABLE语句中使用用户定义的函数,sql,sql-server,tsql,ssms,Sql,Sql Server,Tsql,Ssms,我正在尝试创建下表 CREATE TABLE Ingredient.Ingredient ( GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL, Name NVARCHAR(MAX) NOT NULL UNIQUE ) 但我逐渐意识到,NVARCHAR UNIQUE列的最大大小是450(至少在当前版本的SQL Server中是这样)。为了不使用魔法文字,我创建了一个用户定义的函数,返回NVARCHAR UNIQUE列的当前最大大小 CREAT

我正在尝试创建下表

CREATE TABLE Ingredient.Ingredient 
(
    GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
    Name NVARCHAR(MAX) NOT NULL UNIQUE
)
但我逐渐意识到,
NVARCHAR UNIQUE
列的最大大小是450(至少在当前版本的SQL Server中是这样)。为了不使用魔法文字,我创建了一个用户定义的函数,返回
NVARCHAR UNIQUE
列的当前最大大小

CREATE FUNCTION [Max NVARCHAR Index Size]()
RETURNS INTEGER
BEGIN
    RETURN(450)
END
此函数在作为调用时正确运行

SELECT dbo.[Max NVARCHAR Index Size]()
我希望在
createtable
语句中使用此函数,但它会出现如下所示的错误

CREATE TABLE Ingredient.Ingredient 
(
    GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
    Name NVARCHAR(dbo.[Max NVARCHAR Index Size]()) NOT NULL UNIQUE
)
错误:

味精102,第15级,状态1,第13行
“(”附近的语法不正确

为了避免这种情况,我创建了一个带有函数值的变量,然后使用该变量,但这也不起作用

DECLARE
    @NVARCHARIndexSize INTEGER = dbo.[MAX NVARCHAR Index Size]()

CREATE TABLE Ingredient.Ingredient 
(
    GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
    Name NVARCHAR(@NVARCHARIndexSize) NOT NULL UNIQUE
)
错误:

味精102,第15级,状态1,第13行
“@NVARCHARIndexSize”附近的语法不正确

其中第13行为
名称NVARCHAR(@NVARCHARIndexSize)非空唯一

CREATE TABLE
语句中是否有方法使用变量/函数而不是文字


提前感谢。

DDL不能参数化。您必须使用动态SQL进行参数化。例如

DECLARE
@NVARCHARIndexSize INTEGER = dbo.[MAX NVARCHAR Index Size]()

declare @sql nvarchar(max) = concat('
CREATE TABLE Ingredient.Ingredient 
(
    GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
    Name NVARCHAR(',@NVARCHARIndexSize,') NOT NULL UNIQUE
)'
)

exec (@sql)

可以使用以下语法在SQL Server中创建自定义类型

CREATE TYPE MyCustomType  
FROM NVARCHAR(420); 
以后可以在创建表时使用自定义类型

CREATE TABLE Ingredient 
(
    GUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL,
    [Name] MyCustomType NOT NULL UNIQUE
)

在SQL Server 2016之前,最大密钥长度为900字节

索引键大小 索引键的最大大小对于聚集索引为900字节,对于非聚集索引为1700字节。(之前 SQL数据库和SQL Server 2016(13.x)的限制始终为900 超过字节限制的varchar列上的索引可以 如果列中的现有数据未超过 创建索引的时间;但是,后续插入或更新 导致总大小大于的列上的操作 限制将失败。聚集索引的索引键不能包含 在行\u溢出\u数据中包含现有数据的varchar列 分配单元。如果在varchar列上创建聚集索引 并且现有数据位于行内数据分配单元中, 对列执行的后续插入或更新操作将推送 行外数据将失败

非聚集索引可以在 索引。数据库引擎不考虑这些列 计算索引键大小时


您可以定义NVARCHAR(450)带有检查约束的列,以确保您的数据不超过450个字符。我建议您使用DATALENGTH来确保列长度是您尝试使用动态SQL执行操作的唯一方法。您不能使用参数作为大小定义
nvarchar
。感谢您的响应。您知道这是否正确吗SQL作为DDL是一个预期的设计决策还是一个副作用?您是否必须删除自定义类型的所有实例才能在将来对其进行修改?使用自定义类型是否需要在将来进行任何考虑?例如,
MyCustomType
是否被认为与
NVARCHAR(420)相同
在所有情况下?只是确保我以后不会使用自定义类型来欺骗自己。我认为你会欺骗自己,因为你无法更改它。使用自定义类型和使用临时表可能会导致问题,因为临时表中不会出现自定义类型。此外,正如@DaleK所建议的那样,鉴于这个场景和标准化的意图,我想说自定义类型的不变性是合适的,不太可能是一个问题。从tempdb不可访问性可能会在某个时候出现,所以这很烦人,但自定义类型的优雅仍然为我赢得了胜利。
CONSTRAINT ak_是唯一的(a)
as performant是否将字段键入unique?两者仅相同。当您键入unique时,唯一约束名称将是系统生成的名称。当您自己键入名称时,将选择您的名称