执行 xp_cmdshell 以生成 CSV -- 不喜欢查询中的 'WHERE' 子句
Executing xp_cmdshell to Generate a CSV -- Doesn't Like 'WHERE' Clause in Query
我有以下代码:
USE MyFakeDB
GO
DECLARE @month VARCHAR(16)
SET @month = 'October2021'
;
DECLARE @cmd VARCHAR(8000)
, @sql NVARCHAR(max)
, @return INT
, @filepath VARCHAR(512)
, @servername VARCHAR(255) = @@ServerName
, @username VARCHAR(255) = 'me'
, @password VARCHAR(255) = 'password1234'
, @dbname VARCHAR(255) = 'MyFakeDB'
, @tablename VARCHAR(255) = 'Monthly_Insert'
, @folderpath VARCHAR(255) = 'E:\SomeData\Monthly'
, @filename VARCHAR(255) = '' +@month+ '_Inserts.csv'
, @datadate NVARCHAR(255) = 'WHERE DataMonth = ''' +@month+ ''''
;
SET @cmd = 'Invoke-Sqlcmd -Query ''SELECT Medium, RunDate, RunTime, UTCDate, UTCTime FROM '+@dbname+'.dbo.'+@tablename+' '+@datadate+ ';'' -Database '+@dbname+' -Server "'+@servername+'" -Username '+@username+' -Password '+@password+
' | ConvertTo-Csv -NoTypeInformation | Set-Content -Path '+@folderpath+'\'+@filename+' -Encoding UTF8'
SET @cmd = 'powershell.exe -noprofile -command "'+@cmd+'"'
EXEC @return = xp_cmdshell @cmd, no_output
IF @return <> 0
BEGIN
PRINT 'ERROR: '+@cmd
END
;
GO
当我尝试 运行 时,我得到一个
ERROR: powershell.exe -noprofile -command blah blah blah
错误。如果我删除 @datadate
变量(实际上只是 WHERE
子句),它工作得很好。
我也试过在 WHERE
子句没有变量的情况下做到这一点,只是写了文字字符串但它仍然不起作用,这让我相信它不喜欢有一个 WHERE
子句。
知道为什么吗?
谢谢,
通过 -command
参数传递 powershell 脚本是出了名的棘手。
而是使用 -command -
,它指示 Powershell 从标准输入读取脚本,您可以在 cmd.exe 中使用 <
重定向运算符提供该脚本。
EG
SET @cmd = 'powershell.exe -noprofile -command - < '+@cmd
并且这还允许您发送多行 powershell 脚本,更易于阅读,例如
SET @cmd = 'Invoke-Sqlcmd -Query ''SELECT Medium, RunDate, RunTime, UTCDate, UTCTime FROM '+@dbname+'.dbo.'+@tablename+' '+@datadate+ ';'' -Database '+@dbname+' -Server "'+@servername+'" -Username '+@username+' -Password '+@password+ '
| ConvertTo-Csv -NoTypeInformation
| Set-Content -Path '+@folderpath+'\'+@filename+' -Encoding UTF8'
调试时总是在 运行 之前打印你的 cmd,不要抑制输出。
SET @cmd = 'powershell.exe -noprofile -command - < '+@cmd
print @cmd
EXEC @return = xp_cmdshell @cmd
IF @return <> 0
BEGIN
PRINT 'ERROR: '+@cmd
END
;
我有以下代码:
USE MyFakeDB
GO
DECLARE @month VARCHAR(16)
SET @month = 'October2021'
;
DECLARE @cmd VARCHAR(8000)
, @sql NVARCHAR(max)
, @return INT
, @filepath VARCHAR(512)
, @servername VARCHAR(255) = @@ServerName
, @username VARCHAR(255) = 'me'
, @password VARCHAR(255) = 'password1234'
, @dbname VARCHAR(255) = 'MyFakeDB'
, @tablename VARCHAR(255) = 'Monthly_Insert'
, @folderpath VARCHAR(255) = 'E:\SomeData\Monthly'
, @filename VARCHAR(255) = '' +@month+ '_Inserts.csv'
, @datadate NVARCHAR(255) = 'WHERE DataMonth = ''' +@month+ ''''
;
SET @cmd = 'Invoke-Sqlcmd -Query ''SELECT Medium, RunDate, RunTime, UTCDate, UTCTime FROM '+@dbname+'.dbo.'+@tablename+' '+@datadate+ ';'' -Database '+@dbname+' -Server "'+@servername+'" -Username '+@username+' -Password '+@password+
' | ConvertTo-Csv -NoTypeInformation | Set-Content -Path '+@folderpath+'\'+@filename+' -Encoding UTF8'
SET @cmd = 'powershell.exe -noprofile -command "'+@cmd+'"'
EXEC @return = xp_cmdshell @cmd, no_output
IF @return <> 0
BEGIN
PRINT 'ERROR: '+@cmd
END
;
GO
当我尝试 运行 时,我得到一个
ERROR: powershell.exe -noprofile -command blah blah blah
错误。如果我删除 @datadate
变量(实际上只是 WHERE
子句),它工作得很好。
我也试过在 WHERE
子句没有变量的情况下做到这一点,只是写了文字字符串但它仍然不起作用,这让我相信它不喜欢有一个 WHERE
子句。
知道为什么吗?
谢谢,
通过 -command
参数传递 powershell 脚本是出了名的棘手。
而是使用 -command -
,它指示 Powershell 从标准输入读取脚本,您可以在 cmd.exe 中使用 <
重定向运算符提供该脚本。
EG
SET @cmd = 'powershell.exe -noprofile -command - < '+@cmd
并且这还允许您发送多行 powershell 脚本,更易于阅读,例如
SET @cmd = 'Invoke-Sqlcmd -Query ''SELECT Medium, RunDate, RunTime, UTCDate, UTCTime FROM '+@dbname+'.dbo.'+@tablename+' '+@datadate+ ';'' -Database '+@dbname+' -Server "'+@servername+'" -Username '+@username+' -Password '+@password+ '
| ConvertTo-Csv -NoTypeInformation
| Set-Content -Path '+@folderpath+'\'+@filename+' -Encoding UTF8'
调试时总是在 运行 之前打印你的 cmd,不要抑制输出。
SET @cmd = 'powershell.exe -noprofile -command - < '+@cmd
print @cmd
EXEC @return = xp_cmdshell @cmd
IF @return <> 0
BEGIN
PRINT 'ERROR: '+@cmd
END
;