如果sysname不能为null,如何在此SQL Server系统存储过程中sysname = null?

时间:2018-09-11 22:41:25

标签: sql-server stored-procedures sqldatatypes

我读到sysname cannot be null,但是在系统过程sp_grantdbaccess的定义中,我看到将空值分配给过程的一个参数(如果我读懂了这一点)。怎么会这样?

ALTER PROCEDURE [sys].[sp_grantdbaccess]
    @loginame   sysname,
    @name_in_db sysname = NULL OUT

1 个答案:

答案 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

在几乎所有使用类型的其他上下文中(变量,存储过程参数),我们都不能指定NULLNOT NULL且始终允许使用NULL值,因此,此{{ 1}}元数据很少相关。上面的代码使用常规表并非偶然:如果使用表变量尝试相同的操作,则会发现NOT NULL被忽略,而ANSI_NULL_DFLT_ON始终是列的默认值,否则指定,因此唯一相关的情况是:

NULL