尝试使用sp_executesql运行xp_cmdshell但没有成功,数据库是SQL Server 2008R2
这是SQL
DECLARE @sql nvarchar(max) = N'EXEC xp_cmdshell ''BCP "SELECT data FROM TableA WHERE id = @id" queryout C:\Temp\test.dat -T -N'''
EXEC sp_executesql @sql, N'@id numeric(19, 0)', @id = 1234
错误是
Error = [Microsoft][SQL Server Native Client 10.0][SQL Server]Must declare the scalar variable "@id".
请帮助,谢谢!
答案 0 :(得分:2)
问题是变量@id不存在于过程xp_cmdshell的范围内。
换句话说,@ if不会被字符串SELECT data FROM TableA WHERE id = @id
中的实际值替换。最好替换名为@id的变量,然后执行查询。
SET @sql = REPLACE(@sql,'@id',@id);
您的代码已更新:
DECLARE @id NUMERIC(19, 0)
SET @id = 3087
DECLARE @sql nvarchar(max) = N'EXEC xp_cmdshell ''BCP "SELECT data FROM TableA WHERE id = @id" queryout "C:\Temp\test.dat" -T -N '''
SET @sql = REPLACE(@sql,'@id',@id);
EXEC sp_executesql @sql
答案 1 :(得分:1)
错误是由于@sql字符串中的@id变量引用位于转义子字符串中(即由xp_cmdshell执行的BCP字符串)。所以你可以逃脱该子字符串。
DECLARE @id NUMERIC(19, 0)
DECLARE @sql NVARCHAR(MAX)
SET @id = 1234
SET @SQL = N'DECLARE @BCP NVARCHAR(4000);
SET @BCP = ''BCP "SELECT data FROM TableA WHERE id = ''
+ CONVERT(NVARCHAR(30), @id) + N''" queryout C:\Temp\test.dat -T -N'';
PRINT @BCP
EXEC xp_cmdshell @BCP;
'
EXEC sp_executesql @sql, N'@id NUMERIC(19, 0)', @id = 1234
但这仍然比这里需要更多的努力。只需将@id值连接到字符串中,然后使用EXEC()。不需要使用sp_executesql,因为您不需要缓存查询计划的性能优势。
DECLARE @id NUMERIC(19, 0)
DECLARE @sql NVARCHAR(MAX)
SET @id = 1234
SET @SQL = N'EXEC xp_cmdshell ''BCP "SELECT data FROM TableA WHERE id = '
+ CONVERT(NVARCHAR(30), @id) + N'" queryout C:\Temp\test.dat -T -N'''
PRINT @SQL
EXEC(@SQL)