Ошибка при передаче невербальных переменных сценария для вызова-Sqlcmd в PowerShell

#powershell #invoke-sqlcmd

Вопрос:

Я пытаюсь передать некоторые переменные сценария для вызова-Sqlcmd в PowerShell следующим образом:

 $hello = "hello"
$params = "greeting="   $hello, "audience=world"
Invoke-Sqlcmd -Query "select '`$(greeting) `$(audience)'" -Variable $params
 

Я получаю следующую ошибку:

Формат, используемый для определения новой переменной для командлета Invoke-Sqlcmd, недопустим. Пожалуйста, используйте формат ‘var = value’ для определения новой переменной.

Но я добьюсь успеха, если удалю $hello и использую литерал:

 $params = "greeting=hello", "audience=world"
 

.GetType() возвращает одно и то же для обеих версий $params , поэтому я не уверен, в чем проблема.

Комментарии:

1. Не назначайте $args , поскольку это автоматическая переменная . Я никогда раньше не использовал этот командлет, но я уверен, что вы не должны так использовать -Variable . Кроме того, каковы ваши намерения, потому что в вашей строке нет фактической переменной, поэтому нет необходимости использовать подвыражение или экранировать его с помощью обратного тика .

2. Вы имели в виду: $argument = "greeting=" $hello, "audience=world"; Invoke-Sqlcmd -Query "select '$argumemt'" ?

3. Все в сообщении правильно; вторая версия работает просто отлично. Проверьте документы Invoke-Sqlcmd ; Я делаю то же самое, что и в примере 3.

4. Не используйте $args в качестве имени переменной, как указал Абрахам, это автоматическая переменная PS. См. $args

5. А, понял. Хорошая идея, хотя то же самое с другим именем переменной. Я обновлю вопрос, чтобы избежать путаницы.

Ответ №1:

В вашем первом примере переменная $params устанавливается в string :

 $hello = "hello"
$params = "greeting="   $hello, "audience=world"
$params.GetType()

IsPublic IsSerial Name          BaseType
-------- -------- ----          --------
True     True     String        System.Object

PS /> $params
greeting=hello audience=world
 

Если вы не сообщите PowerShell, что хотите object[] получить результат своей операции. т.е. окружение операции конкатенации с ( ) :

 $params = ("greeting="   $hello), "audience=world"
$params.GetType()

IsPublic IsSerial Name            BaseType
-------- -------- ----            --------
True     True     Object[]        System.Array

PS /> $params
greeting=hello
audience=world
 

Или с помощью array sub-expression operator , например:

 $params = @(
    "greeting="   $hello
    "audience=world"
)
 

Официальную документацию по этому вопросу см. в разделе about_Operator_Precedence .

 $string = 'a'
$array = 'b','c'

PS /> ($string   $array).GetType()

IsPublic IsSerial Name          BaseType
-------- -------- ----          --------
True     True     String        System.Object

PS /> $string   $array
ab c

PS /> ($array   $string).GetType()

IsPublic IsSerial Name            BaseType
-------- -------- ----            --------
True     True     Object[]        System.Array

PS /> $array   $string
b
c
a
 

Комментарии:

1. Я мог бы поклясться, что типы были одинаковыми, когда я проверял. Ну и ладно. Спасибо, что разъяснили мне!