执行存储过程期间无效的列名称错误

时间:2014-09-01 14:17:31

标签: sql sql-server-2008 stored-procedures

我无法执行存储过程。这是一个错误

  

无效的列名称'DW201401'

用于执行存储过程的命令:

exec RM_UTIL_MODE server,'DW201401'

存储过程代码:

ALTER Procedure [dbo].[RM_UTIL_MODE]
    @ServerName varchar(50),
    @Value varchar(50) 
As
Begin
   declare @query nvarchar(max) 

   set @query = N'SELECT mode FROM ' + @ServerName + 
                N'.master.dbo.sysdatabases WHERE name =' + @Value

   exec sp_executesql @query
End

但是当我尝试单独运行查询时,如下所示,它给了我结果。

select mode, name 
from server.master.dbo.sysdatabases 
where name = 'DW201401'

2 个答案:

答案 0 :(得分:4)

据推测,问题是引用@Value

declare @query nvarchar(max) 
set @query = N'SELECT mode FROM ' 
+ @ServerName
+ N'.master.dbo.sysdatabases
WHERE name = '''+@Value+'''';

但是,我会使用参数替换:

declare @query nvarchar(max) ;

set @query = N'SELECT mode
FROM ' + @ServerName + N'.master.dbo.sysdatabases
WHERE name = @value';

exec sp_executesql @query, N'@value varchar(50)', @value = @value;

您已使用sp_executesql,因此您也可以正确使用它。注意:您无法替换服务器名称。

编辑:

要详细说明评论,我会用这种方式编写代码:

    declare @sql nvarchar(max) ;

    set @sql = N'
SELECT mode
FROM @ServerName.master.dbo.sysdatabases
WHERE name = @value';

    set @sql = replace(@sql, '@ServerName', quotename(@ServerName));

    exec sp_executesql @sql, N'@value varchar(50)', @value = @value;

使用动态SQL时,我不再使用字符串连接将查询拼凑在一起。相反,我放置了持有者并使用replace()。我发现连接很难维护,并且经常模糊SQL正在做的事情。虽然使用replace()会有更多的开销(而且我经常多次这样做),但是为了防止错误和维护代码是值得的(另外,我的查询往往会运行一段时间,所以与查询时间相比,开销很小。

答案 1 :(得分:0)

您的选择如下:

select mode, name from server.master.dbo.sysdatabases where name = DW201401

因此您需要在动态查询中添加转义引号:

exec RM_UTIL_MODE cefmtqcfindv3,'DW201401'

ALTER Procedure [dbo].[RM_UTIL_MODE]
@ServerName varchar(50),@Value varchar(50) 
As

Begin

declare @query nvarchar(max) 
set @query = N'SELECT mode FROM ' 
+ @ServerName
+ N'.master.dbo.sysdatabases
WHERE name ='''+@Value+''''

exec sp_executesql @query

End

正如建议一样,当您构建动态sql时,请尝试使用PRINT而不是EXEC,然后获取打印内容并进行尝试。大多数时候你会知道出了什么问题。

仅作为一个例子:

ALTER Procedure [dbo].[RM_UTIL_MODE]
@ServerName varchar(50),@Value varchar(50) 
As

Begin

declare @query nvarchar(max) 
set @query = N'SELECT mode FROM ' 
+ @ServerName
+ N'.master.dbo.sysdatabases
WHERE name ='''+@Value+''''

PRINT @query

--exec sp_executesql @query

End