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



>我读到sysname不能为空,但是在系统过程sp_grantdbaccess的定义中,我看到将null分配给过程的一个参数(如果我没看错的话(。这怎么可能?

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

SYSNAME不能NULL"是不正确的。当链接问题的答案说它等效于默认NVARCHAR(128) NOT NULL是正确的 - 然后仅在列定义中有效。比较:

-- 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值,因此此NOT NULL元数据很少相关。上面的代码使用常规表并非偶然:如果您尝试使用表变量进行相同的操作,您会发现ANSI_NULL_DFLT_ON被忽略,如果未指定,NULL始终是列的默认值,因此唯一相关的情况是:

-- Can't insert NULL
DECLARE @T TABLE (N SYSNAME); INSERT @T DEFAULT VALUES; SELECT * FROM T@
GO
-- OK
DECLARE @T TABLE (N SYSNAME NULL); INSERT @T DEFAULT VALUES; SELECT * FROM @T
GO

最新更新