我正在使用一个列,我希望保留SQL Server 2008 R2中USER_NAME()
函数的值。在BOL中,该函数被记录为返回类型为NVARCHAR(256)
。
然而,在其中一个例子中,他们这样做:
SELECT name FROM sysusers WHERE name = USER_NAME(1)
并且sysusers.name
列的类型为sysname
,这是(据我所知)有效的NVARCHAR(128) NOT NULL
。这种不一致性在CURRENT_USER
的文档中得到进一步巩固,该文档说“此函数等同于USER_NAME()
”,但表明其类型为sysname
(当然,它继续有一个示例,它使用CURRENT_USER作为VARCHAR(30)
列的默认值...)
是什么给出的? BOL是否错误USER_NAME()
的类型?我使用NVARCHAR(128)
安全吗?
答案 0 :(得分:10)
好吧,我们来看看:
SELECT name, system_type_id, user_type_id, max_length
FROM sys.types WHERE name IN (N'sysname', N'nvarchar');
结果:
name system_type_id user_type_id max_length
-------- -------------- ------------ ----------
nvarchar 231 231 8000
sysname 231 256 256
sysname
只是nvarchar
的别名类型,其中 字符数 为128(不是256)。 sys.types
表示256的原因是nvarchar
每个字符有2个字节 - 所以128个字符x 2个字节= 256个字节。它们与我们通常所做的“长度”并不意味着相同的事情。
没有人回答“为什么”BOL说的原因 - 联机丛书是错误的,就是这样。证明:
SELECT x = USER_NAME() INTO #foo;
EXEC tempdb..sp_help '#foo';
部分结果:
Column_name Type Length
----------- -------- ------
x nvarchar 256
-----------------------^^^
---- again, this is 128 characters
是的,您应该使用NVARCHAR(128)
安全,但为了以防万一,它是否会花费您额外的费用来匹配文档?另请停止查看已弃用的系统表(如sysusers
),以获取有关数据类型选择的指导并确认文档。虽然sys.database_principals
和sys.server_principals
在这种情况下也使用sysname
,但它们是检查SQL Server当前工作方式的更可靠的地方,除非您真正在研究SQL Server如何工作13+几年前。