我读到sysname cannot be null,但是在系统过程sp_grantdbaccess
的定义中,我看到将空值分配给过程的一个参数(如果我读懂了这一点)。怎么会这样?
ALTER PROCEDURE [sys].[sp_grantdbaccess]
@loginame sysname,
@name_in_db sysname = NULL OUT
答案 0 :(得分:2)
“ SYSNAME
不能为NULL
”是不正确的。链接问题的答案是正确的,它说它等于NVARCHAR(128) NOT NULL
作为默认值,然后在列定义中有效地 only 。比较:
-- When not specified, columns are NULL
SET ANSI_NULL_DFLT_ON ON
-- Works
CREATE TABLE T(N NVARCHAR(128)); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
-- When not specified, columns are NOT NULL
SET ANSI_NULL_DFLT_ON OFF
-- Error: can't insert NULL
CREATE TABLE T(N NVARCHAR(128)); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
现在使用SYSNAME
尝试相同的操作:
-- When not specified, columns are NULL
SET ANSI_NULL_DFLT_ON ON
-- Error: SYSNAME is NOT NULL, regardless of defaults
CREATE TABLE T(N SYSNAME); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
但这并不意味着SYSNAME
不能为NULL
,我们要做的只是说可能是:
-- Works
CREATE TABLE T(N SYSNAME NULL); INSERT T DEFAULT VALUES; SELECT * FROM T
GO
DROP TABLE T
GO
在几乎所有使用类型的其他上下文中(变量,存储过程参数),我们都不能指定NULL
或NOT NULL
且始终允许使用NULL
值,因此,此{{ 1}}元数据很少相关。上面的代码使用常规表并非偶然:如果使用表变量尝试相同的操作,则会发现NOT NULL
被忽略,而ANSI_NULL_DFLT_ON
始终是列的默认值,否则指定,因此唯一相关的情况是:
NULL