简体   繁体   English

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

[英]sqlcmd. How to pass in a variable that includes a colon and a space?

I've been struggling with this for a while now. 我一直在努力解决这个问题。 I'm trying to invoke a sql script and pass two variables into it using sqlcmd. 我正在尝试调用sql脚本并使用sqlcmd将两个变量传递给它。 I'm doing all this in PowerShell. 我在PowerShell中做了这一切。

Here's what I've got: 这是我得到的:

$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

This fails with the following error message: 此操作失败,并显示以下错误消息:

sqlcmd : Sqlcmd: 'time=12:00 AM': Invalid argument. Enter -? for help.

After some experimentation, I've discovered that the problem is the colon and the space in $time. 经过一些实验,我发现问题是冒号和时间空间。 If I remove the colon and the space $time = '1200AM' , the command executes without any error. 如果我删除冒号和空格$time = '1200AM' ,该命令将执行而不会出现任何错误。

Unfortunately, the script that I'm executing wants the exact format "12:00 AM". 不幸的是,我正在执行的脚本需要确切的格式“12:00 AM”。

Things that I've tried that didn't work: 我尝试过的东西不起作用:

$time="12\:00\ AM"
$time="12\\:00\\ AM"
$time="12"+":00"+" AM"
$time="12"+":00"
$time="12"+":"+"00"

These all respond with similar Invalid argument failures. 这些都响应类似的Invalid argument失败。 The last few attempts were the solution from this similar post . 最后几次尝试是这个类似帖子的解决方案。 They don't work. 它们不起作用。

I have also tried placing the string values directly in the sqlcmd invocation, like so: 我也尝试将字符串值直接放在sqlcmd调用中,如下所示:

$result = sqlcmd -U username -P password -i "c:\path\to\script.sql" -v date=$date -v time="12\:00\ AM". 

No dice, and anyways, I need to read the time in from somewhere else, so I need the $time variable. 没有骰子,无论如何,我需要从其他地方读取时间,所以我需要$ time变量。

I (finally) found a solution that worked for sqlcmd from a Powershell script. 我(最后)找到了一个适用于Powershell脚本的sqlcmd的解决方案。 (Using invoke-sqlcmd was not an option for me) (使用invoke-sqlcmd不是我的选择)

I needed to pass an absolute path containing a colon in a variable (eg, C:\\rootdir\\subdir). 我需要在变量中传递包含冒号的绝对路径(例如,C:\\ rootdir \\ subdir)。 This worked from a regular command prompt, but I couldn't get it to work from a Powershell script. 这可以从常规的命令提示符开始,但我无法通过Powershell脚本使用它。 I came up with an ugly kludge, passing the parts before and after the colon in two variables, then reassembling it in the SQL script. 我想出了一个丑陋的kludge,在冒号之前和之后传递两个变量中的部分,然后在SQL脚本中重新组装它。

But then it failed when the path contained a space (eg, C:\\root dir\\subdir). 但是当路径包含空格(例如,C:\\ root dir \\ subdir)时失败。

So I finally found a solution that fixed both colons and spaces. 所以我终于找到了解决冒号和空格的解决方案。 It involved enclosing the path text in double quotes, then enclosing the double-quoted path text in an outer set of single quotes. 它包含用双引号括起路径文本,然后将双引号路径文本括在外部单引号集中。 After building the full sqlcmd in a variable, it looked something like this: 在变量中构建完整的sqlcmd后,它看起来像这样:

SQLCMD <other args>  -v RootPath='"C:\root dir\subdir"'

(That's an outer set of single quotes (') and an inner set of double quotes (")). (这是一组外部单引号(')和一组内部双引号(“))。

This also worked if the path didn't have a colon, eg, \\\\nodename\\root dir\\subdir. 如果路径没有冒号,例如\\\\ nodename \\ root dir \\ subdir,这也有效。 This had been a problem when I tried to split the path around an assumed colon. 当我试图在假定的冒号周围分割路径时,这是一个问题。 I'm still not sure why both outer single quotes and inner double quotes are necessary, but that was the only version that worked for me. 我仍然不确定为什么外部单引号和内部双引号都是必要的,但这是唯一适用于我的版本。

ADDENDUM: This only worked for Powershell 5, and broke when my script was run from Powershell 4. To make it work on both, I found I needed to enclose internal spaces in single quotes, eg, ADDENDUM:这只适用于Powershell 5,当我的脚本从Powershell 4运行时就崩溃了。为了使它在两者上运行,我发现我需要用单引号括起内部空格,例如,

SQLCMD <other args>  -v RootPath='"C:\root' 'dir\subdir"'

Alright, I figured a solution out. 好吧,我想出了一个解决方案。 Hopefully it will be useful to other people somewhere down the road. 希望它对将来的其他人有用。

I switched from sqlcmd to Powershell's Invoke-Sqlcmd. 我从sqlcmd切换到Powershell的Invoke-Sqlcmd。 This STILL gave me problems, so I had to fiddle around with it a little. 这个STILL给了我一些问题,所以我不得不用它来捣乱。 Here's my end result. 这是我的最终结果。

# 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

Note that the following DOES NOT WORK: 请注意以下内容不起作用:

$datetime = "time='"+$time+"'", "date='"+$date+"'"

This was the first thing I tried, and it resulted in an invalid argument exception. 这是我尝试的第一件事,它导致了无效的参数异常。

I slightly modified your PowerShell script by adding spaces before and after each variable assignment operator like this: 我通过在每个变量赋值运算符之前和之后添加空格来稍微修改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

It works for me (tested on PowerShell 2.0). 它适用于我(在PowerShell 2.0上测试)。

First, I would try -v "date=$date" -v "time=$time" . 首先,我会尝试-v "date=$date" -v "time=$time"

If that didn't work, I'd try this: 如果那不起作用,我试试这个:

$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

When PowerShell executes a program, it parses the line, resolves any PowerShell in it, and then tries to execute the string. 当PowerShell执行程序时,它会解析该行,解析其中的任何PowerShell,然后尝试执行该字符串。 It ends up feeling like you need an extra layer of abstraction that you don't really see in traditional shell scripts or batch scripts. 它最终感觉你需要一个额外的抽象层,你在传统的shell脚本或批处理脚本中并没有真正看到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM