SQLCMD。如何传入包含冒号和空格的变量?

时间:2014-12-05 19:51:28

标签: powershell sqlcmd

我现在已经挣扎了一段时间了。我试图调用一个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变量。

4 个答案:

答案 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脚本或批处理脚本中并没有真正看到它。