4

我正在处理一个我想USER_NAME()在 SQL Server 2008 R2 中保存函数值的列。在BOL中,该函数被记录为返回类型为NVARCHAR(256).

但是,在其中一个示例中,他们这样做:

SELECT name FROM sysusers WHERE name = USER_NAME(1)

并且该sysusers.name列具有 type sysname,它(据我所知)实际上是一个NVARCHAR(128) NOT NULL. 这种不一致在 的文档中得到了进一步巩固CURRENT_USER,其中说“这个函数相当于USER_NAME()”,但表明它的类型是sysname(当然,它接着有一个例子,它使用 CURRENT_USER 作为VARCHAR(30)列的默认值...... )

是什么赋予了?BOL 的类型是否错误USER_NAME()?我使用它安全NVARCHAR(128)吗?

4

1 回答 1

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_principalssys.server_principals也使用sysname它们,但它们是检查 SQL Server 今天如何工作的更可靠的地方,除非您真的在调查 SQL Server 13 多年前的工作方式。

于 2013-04-18T19:03:54.820 回答