【问题标题】:xp_cmdshell and echo in sql server triggersql server 触发器中的 xp_cmdshell 和 echo
【发布时间】:2017-03-21 18:15:12
【问题描述】:

我正在尝试将一些数据和固定字符从 SQL Server 表导出到文本文件。我需要将大量此类行导出到文本文件中,因此我试图通过将它们放在一行中来减少 DECLARing 和 SETting 大量命令变量(这将极大地减少代码大小)。这是我想要做的:

这很好用:

DECLARE @ClientID varchar(50)
SET @ClientID = (select ClientID from inserted)

DECLARE @CommandL1 varchar(512)
SET @CommandL1 = 'echo U1 '+@ClientID+'> c:\temp\file.txt'
exec master..xp_cmdshell @CommandL1

与上面完全相同的命令,但写成一行(没有 DECLARE 和 SET,减少代码的首选方法)失败(我收到错误 - (first) '+' 附近的语法不正确):

exec master..xp_cmdshell 'echo U1 '+@ClientID+'> c:\temp\file.txt' --ERROR

我有很多类似上面的代码,所以想省钱。此外,我想知道如何解决这个问题。提前感谢您的帮助(我尝试使用 ^ 作为转义字符,但没有成功)。如何更改第二行(如上所示 --ERROR 所示)使其正常工作?

jd

【问题讨论】:

  • ClientID 设置为什么?另外,我认为您的第一个语句中有一个额外的 ',即 @CommandL1 的设置
  • 我将 ClientID 设置为 SET @ClientID = (从插入中选择 ClientID);这部分工作正常,在表插入/更新后,使用第一种方法将正确的 ClientID 导出到文本文件。你对额外的'是绝对正确的 - 我现在已经编辑了它。感谢您的回复。
  • 所以ClientIDINTEGER 还是VARCHAR?您确定在您的子选择(select ClientID from inserted) 中只返回 1 行(记录/值)吗?
  • 我将其声明为 varchar - DECLARE @ClientID varchar(50) - 是的,只返回一条记录。由于第一组 3 行正在工作,我认为问题在于 xp_cmdshell 如何解释第二行代码 - 当我在 SQL 查询窗口中运行它时,它显示“+ 附近的语法不正确”。
  • 基于 xp_cmdshell 的 SSIS 示例,看起来它根本不接受动态生成的字符串。您可以尝试将其放在 CAST 或 CONVERT 语句中,看看是否可以解决此问题 - exec xp_cmdshell CONVERT(varchar(max), 'echo U1 '+@ClientID+'> c:\temp\file.txt')

标签: sql-server triggers escaping echo xp-cmdshell


【解决方案1】:

根据MSDN,您将不得不将该语句保留在动态 SQL 中,以便命令 shell 不会读取

exec master..xp_cmdshell 'echo U1 '+@ClientID+'> c:\temp\file.txt'

作为

echo U1 + @ClientID + '> c:\temp\file.txt'

xp_cmdshell 接受一个字符串参数,因此您需要首先显式构建字符串,就像您在开始时所做的那样。该参数在 + 之前的结束引号之后终止,因此 + 是一个语法错误,因为 xp_cmdshell 不期望字符串参数之后的任何内容,NO_OUTPUT 作为可选参数。因此,它将您的 + 解释为不正确的参数。

【讨论】:

  • 非常感谢。更多的工作,但至少它会完成这项工作。感谢您的帮助。
  • 没问题。我添加了更多关于参数终止的信息。 SQL 中的最后一个 ' 将读取为字符串参数的结尾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
相关资源
最近更新 更多