传递路径参数时从ruby运行Invoke Sqlcmd时出错
错误 调用Sqlcmd:找不到接受参数“Static”的位置参数 当我在ruby之外的powershell中运行相同的命令时,它会正常执行。我做错了什么 更新 我发现用硬编码路径传递路径参数时从ruby运行Invoke Sqlcmd时出错,ruby,powershell,rake,sql-server-2014,Ruby,Powershell,Rake,Sql Server 2014,错误 调用Sqlcmd:找不到接受参数“Static”的位置参数 当我在ruby之外的powershell中运行相同的命令时,它会正常执行。我做错了什么 更新 我发现用硬编码路径C:\\test\\test.sql替换{sqlFile}可以纠正这个问题。我尝试了sqlFile.gsub!'/,“\\\\”,这没有明显的区别(仍然是标准的\windows路径) 我也试过了 def executeSql(sqlFile) #exec("powershell $env:git
C:\\test\\test.sql
替换{sqlFile}
可以纠正这个问题。我尝试了sqlFile.gsub!'/,“\\\\”代码>,这没有明显的区别(仍然是标准的\
windows路径)
我也试过了
def executeSql(sqlFile)
#exec("powershell $env:gitroot");
puts "executing file: #{sqlFile}"
command="powershell Invoke-Sqlcmd -InputFile #{sqlFile} -ServerInstance \"localhost\" -Database \"dbName\" -Verbose"
command.gsub! '/','\\'
puts "command: #{command}"
if($firstRun)
puts 'inside first run'
importCommand = `powershell Import-Module \"sqlps\" -DisableNameChecking`
printf importCommand
$firstRun=false
end
puts 'made it past first run'
printf `#{command}`
puts 'command execution complete'
end
这创造了
command="powershell Invoke-Sqlcmd -InputFile #{Shellwords.escape(sqlFile)} -ServerInstance \"localhost\" -Database \"dbName\" -Verbose"
如果不是文件路径中的01\-\Static\
部分,我认为这会起作用
更新2
我发现了一些有用的东西,并将其作为答案发布@塔德曼建议使用多个参数来系统
。我试过这个,但它对我不起作用。我肯定我做错了什么:
Invoke-Sqlcmd -InputFile C:\\Git\\project\\sql\\db\\01\ -\ Static\ Data\\file.name.here.sql -ServerInstance "localhost" -Database "dbName" -Verbose
诀窍是用反勾号避开空格,以使powershell正常工作
testLocation=File.join("C:/test 1", "test.sql")
executeSql(testLocation)
def executeSql(sqlFile)
system("powershell", "Invoke-Sqlcmd", "-InputFile", "#{sqlFile}", "-ServerInstance", "localhost", "-Database", "dbName", "-Verbose")
end
使用system
并分别将参数分解为:system('powershell','Import Module','sqlps',…),而不是编写一个shell字符串(即使你千方百计地加上反斜杠,也很容易出错),而不是编写一个shell字符串
这避免了绝大多数解析和转义问题。Ruby style还强烈建议不使用任何大写字母的命名方法,如execute\u sql
。Case在Ruby中有着重要的意义,ClassName
和CONSTANT\u NAME
就是这样的例子。@tadman-我想你在这方面是对的。如何转义#{sqlFile}
中的字符?我认为,作为指挥途径的一部分,我们需要逃离他们。也许吧?如果你把它们作为单独的论据来讨论,你不应该这样做。这绕过了shell插值,避免了很多麻烦,比如带有空格的文件名、注入恶意shell命令等等。backtick shell运行约定是一种非常懒惰的方式,适用于快速脚本,但完全不适用于生产代码。@tadman-如果您可以提供一个基于带有空格的路径的工作示例,那么我很乐意使用它。我试着这么做,但没有成功。
def executeSql(sqlFile)
sqlFile.gsub! ' ','` '#escape whitespace in path
command="powershell Invoke-Sqlcmd -InputFile #{sqlFile} -ServerInstance \"localhost\" -Database \"dbName\" -Verbose"
puts "command: #{command}"
if($firstRun)
system("powershell Import-Module sqlps -DisableNameChecking;exit")
$firstRun=false
end
system("#{command}")
end