2014-09-01 97 views
0

我无法执行存储过程。它抛出一个错误执行存储过程期间无效的列名错误

无效的列名称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' 

回答

4

据推测,这个问题是引号@Value

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

不过,我会用参数替换,而不是:

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()时有更多的开销(我经常多次使用它),但它对于防止错误和维护代码是值得的(另外,我的查询往往会运行一段时间,所以开销比较少到查询时间)。

+2

我也会写'QUOTENAME(@ServerName)'而不是'@ ServerName' – 2014-09-01 14:25:16

+0

你能告诉我如何在传递多个参数的情况下使用下面的exec行。而不是价值,我需要通过value1,value2,value3 ... – user3859666 2014-09-02 05:52:20

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 ='''[email protected]+'''' 

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 ='''[email protected]+'''' 

PRINT @query 

--exec sp_executesql @query 

End 
+0

谢谢......你能告诉我如何使用打印? – user3859666 2014-09-01 14:36:03

+0

@ user3859666检查编辑。 – 2014-09-01 14:37:34