我现在已经挣扎了一段时间了。我试图调用一个sql脚本并使用sqlcmd将两个变量传递给它。我在PowerShell中做了这一切。
以下是我所拥有的:
$time = '12:00 AM'
$date = '06/20/2014'
$result = sqlcmd -U username -P password -i "c:\path\to\script.sql" -v date=$date -v time=$time
此操作失败,并显示以下错误消息:
sqlcmd : Sqlcmd: 'time=12:00 AM': Invalid argument. Enter -? for help.
经过一些实验,我发现问题是结肠和空间在$ time。如果我删除了冒号和空格$time = '1200AM'
,则执行该命令时没有任何错误。
不幸的是,我执行的脚本需要确切的格式" 12:00 AM"。
我尝试过的不起作用的事情:
$time="12\:00\ AM"
$time="12\\:00\\ AM"
$time="12"+":00"+" AM"
$time="12"+":00"
$time="12"+":"+"00"
这些都以类似的Invalid argument
失败回应。最后几次尝试是来自this similar post的解决方案。他们不工作。
我也尝试将字符串值直接放在sqlcmd调用中,如下所示:
$result = sqlcmd -U username -P password -i "c:\path\to\script.sql" -v date=$date -v time="12\:00\ AM".
没有骰子,无论如何,我需要从其他地方读取时间,所以我需要$ time变量。
答案 0 :(得分:5)
我(最终)找到了一个适用于Powershell脚本的sqlcmd的解决方案。 (使用invoke-sqlcmd对我来说不是一个选项)
我需要在变量中传递包含冒号的绝对路径(例如,C:\ rootdir \ subdir)。这可以从常规的命令提示符开始,但我无法通过Powershell脚本使用它。我想出了一个丑陋的kludge,在冒号之前和之后传递两个变量中的部分,然后在SQL脚本中重新组装它。
但是当路径包含空格(例如,C:\ root dir \ subdir)时失败了。
所以我终于找到了解决冒号和空格的解决方案。它包含用双引号括起路径文本,然后将双引号路径文本括在外部单引号集中。在变量中构建完整的sqlcmd后,它看起来像这样:
SQLCMD <other args> -v RootPath='"C:\root dir\subdir"'
(这是一组外引号(')和一组内引号(“)”。
如果路径没有冒号,例如\\ nodename \ root dir \ subdir,这也有效。当我试图在假定的冒号周围分割路径时,这是一个问题。我仍然不确定为什么外部单引号和内部双引号都是必要的,但那是唯一对我有用的版本。
ADDENDUM:这只适用于Powershell 5,当我的脚本从Powershell 4运行时就崩溃了。为了使它能同时工作,我发现我需要用单引号括起内部空格,例如,
SQLCMD <other args> -v RootPath='"C:\root' 'dir\subdir"'
答案 1 :(得分:2)
好吧,我想出了一个解决方案。希望它对未来某个地方的其他人有用。
我从sqlcmd切换到Powershell的Invoke-Sqlcmd。这个STILL给了我一些问题,所以我不得不用它来捣乱。这是我的最终结果。
# import Invoke-Sqlcmd
Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
$time = "12:01 AM"
$date = "07/22/2014"
$datetime = "time='$time'", "date='$date'" # save to $datetime as an array
$result = Invoke-Sqlcmd -Username username -Password password -InputFile "c:\path\to\sql\script.sql" -Variable $datetime
请注意,以下操作不起作用:
$datetime = "time='"+$time+"'", "date='"+$date+"'"
这是我尝试的第一件事,它导致了无效的参数异常。
答案 2 :(得分:2)
我通过在每个变量赋值运算符之前和之后添加空格来略微修改PowerShell脚本,如下所示:
$time = '12:00 AM'
$date = '06/20/2014'
$result = sqlcmd -U username -P password -i "c:\path\to\script.sql" -v date = $date -v time = $time
它适用于我(在PowerShell 2.0上测试过)。
答案 3 :(得分:0)
首先,我会尝试-v "date=$date" -v "time=$time"
。
如果这不起作用,我试试这个:
$time = '12:00 AM'
$date = '06/20/2014'
$time = 'time=' + $time
$date = 'date=' + $date
$result = sqlcmd -U username -P password -i "c:\path\to\script.sql" -v $date -v $time
当PowerShell执行程序时,它会解析该行,解析其中的任何PowerShell,然后尝试执行该字符串。它最终感觉你需要一个额外的抽象层,而你在传统的shell脚本或批处理脚本中并没有真正看到它。