Почему я получаю сообщение об ошибке с моим PowerShell Invoke-SQLCMD InputFile? - PullRequest
0 голосов
/ 17 января 2020

Я пытаюсь вызвать SQLCMD из скрипта PowerShell, но Powershell, похоже, не нравится, как я передаю -InputFile Invoke-Sqlcmd. Мой код выглядит примерно так:

$files = Get-ChildItem -Path $PSScriptRoot -Recurse | Where-Object { $_.Name -match $regex};
Invoke-Sqlcmd -InputFile $files[0].FullName

$ files никогда не бывает пустым, так как при печати $ files [0] .FullName выводит строку типа «D: \ foo \ foo. sql». Когда мое приложение достигает этой строки, оно выдает ошибку, указывающую на ту же строку, в которой я использую Invoke-Sqlcmd и символ «$» в «$ files».

Я получаю эти два сообщения об ошибке:

Invoke-Sqlcmd : The pipeline has been stopped.
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], PipelineStoppedException
    + FullyQualifiedErrorId : SqlExectionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Invoke-Sqlcmd : An expression of non-boolean type specified in a context where a condition is expected
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Есть ли проблема с тем, как я передаю путь к файлу сценария, который я хочу запустить? Какой будет правильный формат. Я также попытался использовать .PSPath вместо .FullName, но получаю сообщение об ошибке, говорящее о том, что путь к файлу не поддерживается.

1 Ответ

0 голосов
/ 17 января 2020

Это сообщение довольно точно указывает c и говорит, что Invoke-SqlCmd не нравится то, что вы передаете. Используемые типы вариантов, которые передаются, важны.

This ...

$files = Get-ChildItem -Path $PSScriptRoot -Recurse 

... конечно, заселяется раньше, чем что-либо еще происходит. Независимо от того, что вы делаете потом.

К вашему сведению, что касается этого ...

Where-Object { $_.Name -match $regex};

... вам действительно не нужна эта точка с запятой, в PowerShell, за исключением случаев, указанных в c случаев. Точка с запятой - это терминатор кода, обычно используемый в окне consolehost, чтобы держать вещи в одной строке, но в большинстве случаев это не то, что действительно нужно для скриптов или модулей.

Вы увидите, что его используют люди, пришедшие с других языков, из-за своих привычек, а также из-за людей, пытающихся втиснуть все в одну строку и назвавших это одной строкой, чего на самом деле нет.

Попробуйте это вместо этого.

(Get-ChildItem -Path $PSScriptRoot -Filter $RegEx).FullName[0]

Итак, вы получите что-то более прямое, как это ...

$regex = '*.sql'
(Get-ChildItem -Path $PSScriptRoot -Filter $RegEx).FullName[0] | 
Invoke-Sqlcmd -InputFile $PSItem

Таким образом, нет причина дополнительной переменной и добавление Where-Object и точечной нотации в вызове Invoke-Sqlcmd.

Вы также могли бы сделать это ...

Invoke-Sqlcmd -InputFile $files[0].FullName

... this путь

Invoke-Sqlcmd -InputFile ($files.FullName)[0]
...