我正在尝试弄清楚数据类型sysname
的使用以及解析器如何隐式转换和/或识别 none-quoted-literals 。使用着名的函数object_id来测试存在,请考虑这一点。
--Sanity test
begin
if object_id('NotExistingProcedure','P') is not null print N'Exists.';
else print N'Not exists.';
end
go
--This works.
begin
declare @ObjectName sysname = 'NotExistingProcedure',
@ObjectType sysname = 'P';
if object_id(@ObjectName,@ObjectType) is not null print N'Exists.';
else print N'Not exists.';
end
go
--This does not.
begin
declare @ObjectName sysname = NotExistingProcedure,
@ObjectType sysname = P;
if object_id(@ObjectName,@ObjectType) is not null print N'Exists.';
else print N'Not exists.';
end
go
--But this works.
create procedure TestExists
@ObjectName sysname,
@ObjectType sysname
as
if object_id(@Objectname,@ObjectType) is not null print N'Exists.';
else print N'Not exists.';
go
exec TestExists NotExistingProcedure,P;
任何人都可以解释为什么使用非引用文字来分配类型SYSNAME
的变量在将参数传递给过程但不在外部时有效。
答案 0 :(得分:0)
sysname数据类型用于表列,变量和存储 存储对象名称的过程参数。。的确切定义 sysname与标识符规则相关。因此,它可以 因SQL Server实例而异。 sysname在功能上是相同的 as nvarchar(128),但默认情况下,sysname为NOT NULL。在 在早期版本的SQL Server中,sysname被定义为varchar(30)。
现在在您的示例中不起作用:
begin
declare @ObjectName sysname = NotExistingProcedure,
@ObjectType sysname = P;
if object_id(@ObjectName,@ObjectType) is not null print N'Exists.';
else print N'Not exists.';
end
go
错误:
无效的列名称' NotExistingProcedure'。
列名无效' P'。
基于DECLARE
文档
DECLARE
{
{ @local_variable [AS] data_type | [ = value ] }
| { @cursor_variable_name CURSOR }
} [,...n]
所以你可以将value
分配到:
=值
为变量分配一个值。值可以是常量或表达式,但它必须与变量匹配 声明类型或可隐式转换为该类型。
然后Expressions
:
因此解析器需要列名,但没有列名(因为它不是SELECT
语句)。
这就是你收到错误的原因:
列名称无效' NotExistingProcedure'。
现在让我们继续讨论最后一个有效的例子:
create procedure TestExists
@ObjectName sysname,
@ObjectType sysname
as
if object_id(@Objectname,@ObjectType) is not null print N'Exists.';
else print N'Not exists.';
go
exec TestExists NotExistingProcedure,P;
go
基于EXECUTE
:
所以当你看到你可以通过value
:
值
是要传递给模块或传递命令的参数值。如果未指定参数名称,则参数 必须按照模块中定义的顺序提供值。
如果参数的值是对象名,字符串或由数据库名称或模式名称限定,则必须将整个名称括在单引号中。如果值为a parameter是关键字,关键字必须用双引号括起来。
这表示应该使用'
关闭。
如果您尝试传递架构:
exec TestExists dbo.NotExistingProcedure, P;
go
-- Incorrect syntax near '.'.
你需要用
括起来exec TestExists 'dbo.NotExistingProcedure', P;
go
当它是关键字时,您可以使用[]
引用它:
exec TestExists [from], P;
go
总结一下:
SYSNAME
类型的变量时,您无法传递不带引号的名称。EXEC
为关键字或包含架构名称int