在扩展存储过程-exec master..xp_cmdshell 中传递/使用标量变量
Posted
技术标签:
【中文标题】在扩展存储过程-exec master..xp_cmdshell 中传递/使用标量变量【英文标题】:Passing/Using Scalar variable in extended stored procedure-exec master..xp_cmdshell 【发布时间】:2021-04-25 12:30:38 【问题描述】:我必须在不使用导出向导的情况下将 Student 表中的数据导出为 CSV。如果我们硬编码注册号,下面的脚本可以正常工作,但是当使用变量@registration_no 时会报错:必须声明标量变量。在打印@cmd 时,registration_no 正确替换为 101。似乎 @registration 超出了 exec master..xp_cmdshell 的范围
Begin
Declare @registration_no as int
set @registration_no = 101
Declare @cmd as nvarchar(4000)
set @cmd = 'sqlcmd -s, -W -Q "set nocount on; select * from [Student_Management].[dbo].[Student] where registration_no = @registration_no " | findstr /v /c:"-" /b > "d:\student.csv" '
exec master..xp_cmdshell @cmd
END
【问题讨论】:
SQL 不是脚本语言,文字字符串中的变量不会被批处理中的变量值替换。SELECT '@Variable'
不返回存储在变量中的值,它返回 literal 字符串 '@Variable'
.
@larnu 能否请您提供解决方案,我也尝试过存储过程,但无法成功。我想将许多表的数据导出到 CSV,并且必须提供一个参数(如 registration_no)来过滤数据。但是需要一个相同的脚本并且不能使用向导
您需要将变量中包含的值嵌入到您构建的字符串中。就这么简单。类似 set @cmd = '.... where registration_no = ' + cast(@registration_no as varchar(11)) + ...
@SMor 仍然得到:必须声明标量变量“@registration_no”。将 set 命令更改为: set @ cmd = 'sqlcmd -s, -W -Q "set nocount on; select * from [Student_Management].[dbo].[Student] where registration_no = +cast(@registration_no as int)" | findstr /v /c:"-" /b > "d:\student.csv"' OR set @ cmd = 'sqlcmd -s, -W -Q "set nocount on; select * from [Student_Management].[dbo] .[学生] where registration_no = +cast(@registration_no as varchar(11))" | findstr /v /c:"-" /b > "d:\student.csv"'
@SMor 仍然得到:必须声明标量变量“@registration_no”。
【参考方案1】:
create procedure sp_CSV_Export
@regno int
as
Begin
Declare @registration_no int = @regno
declare @bcp varchar(8000)
set @bcp = 'sqlcmd -s, -W -Q "set nocount on; SELECT * FROM [Student_Management].[dbo].[Student] WHERE registration_no= '+ cast(@registration_no as nvarchar(10))+' " | findstr /v /c:"-" /b > "d:\student.csv"'
EXEC master..xp_cmdshell @bcp
end
成功了!
【讨论】:
以上是关于在扩展存储过程-exec master..xp_cmdshell 中传递/使用标量变量的主要内容,如果未能解决你的问题,请参考以下文章