invoke-sqlcmd через функцию, вызывающую ошибку позиционного параметра - PullRequest
0 голосов
/ 05 мая 2019

Я пытаюсь использовать функцию для запуска запроса, но она не принимает мой экземпляр сервера и выдает ошибку: «Run-SqlCommand: не найден позиционный параметр, который принимает аргумент« mydbservername ».»

Когда я выполняю тот же invoke-sqlcmd вне функции, он работает нормально.

Функция:

    function Run-SqlCommand
{
    [CmdletBinding()]
    Param
    (
        [parameter(Position=0, Mandatory=$True, ParameterSetName="Query")]
        [string]$Query,
        [parameter(Position=1, Mandatory=$True, ParameterSetName="DatabaseServerName")]
        [string]$DatabaseServerName,
        [parameter(Position=2, Mandatory=$True, ParameterSetName="Database")]
        [string]$Database,
        [parameter(Position=3, Mandatory=$True, ParameterSetName="Username")]
        [string]$Username,
        [parameter(Position=4, Mandatory=$True, ParameterSetName="Password")]
        [string]$Password
    )

    try {
        $result = Invoke-SqlCmd -query $Query -serverinstance $DatabaseServerName -Database $Database -Username $Username -Password $Password -ErrorAction Stop
        }
    catch {
        Write-Warning $_.Exception.Message
        }

}

В другом скрипте я определяю запрос, сервер, базу данных и пользователя / пароль и вызываю функцию, передающую эти переменные:

$SuperUserQuery =@"
select uid,username,first_name,last_name,ad_username,active
from users
where (superuser = 'Y' AND active = '1')
Order by username Asc
"@

      $DatabaseServerName = "mydbservername"
      $Database = "dbname"
      $Username = "dbuser"
      $Password = "dbpass"


Run-SqlCommand $SuperUserQuery $DatabaseServerName $Database $Username $Password

Когда я это делаю, я получаю ошибку, о которой упоминал выше:

"Run-SqlCommand: не найден позиционный параметр, который принимает аргумент" mydbservername "."

Если я просто запускаю invoke-sqlcmd прямо в скрипте, я пытаюсь вызвать функцию - она ​​работает просто отлично.

$result = Invoke-SqlCmd -query $SuperUserQuery -serverinstance $DatabaseServerName -Database $Database -Username $Username -Password $Password -ErrorAction Stop

Почему это работает при непосредственном вызове, но не работает при вызове через мою функцию?

Ну, я не очень понимаю, почему так все же хотел бы, чтобы кто-то помог мне понять .... но я исправил это, изменив параметры ...

        [parameter(Mandatory=$True)]
        [string]$Query,
        [parameter(Mandatory=$True)]
        [string]$DatabaseServerName,
        [parameter(Mandatory=$True)]
        [string]$Database,
        [parameter(Mandatory=$True)]
        [string]$Username,
        [parameter(Mandatory=$True)]
        [string]$Password

Это сработало, когда я перешел на это. Наверное, я не понимаю слова "position" или "имя_параметра".

1 Ответ

0 голосов
/ 05 мая 2019

Я думаю, что вы пытаетесь сделать то, что называется Splatting . С помощью splatting вы можете создавать легко читаемый / поддерживаемый код, особенно если он использует командлеты, которые принимают много параметров.

Для этого вы создаете объект Hashtable и помещаете туда все параметры, которые вы хотите использовать для командлета Invoke-Sqlcmd, например:

$sqlQuery = @"
SELECT uid,
       username,
       first_name,
       last_name,
       ad_username,
       active
FROM   users
WHERE  ( superuser = 'Y'
         AND active = '1' )
ORDER  BY username ASC 
"@

$sqlParams = @{
    'Query'          = $sqlQuery
    'ServerInstance' = 'mydbservername'
    'Database'       = 'dbname'
    'Username'       = 'dbuser'
    'Password'       = 'dbpass'
    # you can even add common parameters in there like
    'ErrorAction'    = 'Stop'
}

Тогда вы используете это так:

try {
    $result = Invoke-Sqlcmd @sqlParams
}
catch {
    Write-Warning $_.Exception.Message
}
...