У меня есть функция PowerShell, которая выполняет хранимые процедуры в базе данных SQL Server 2016. Он отлично работает с любыми параметрами любого типа варианта char, но не работает при обнаружении параметров таких типов, как int, цифра c или дата / время.
Я получаю такие ошибки, как
Ошибка преобразования типа данных varchar в int, число c, дата и время
Я могу заставить его работать, вставив значения непосредственно в строку exe c, но, очевидно, я хочу избежать этого.
Другая проблема состоит в том, что, хотя функция обрабатывает размер параметров, я не знаю, как обращаться с точностью числовых значений. Другие решения и примеры, которые я нашел, не решают эту конкретную проблему c.
Вот функция; он принимает оператор запроса в виде строки вместе с массивом массивов, которые могут содержать данные для параметров в форме @((name,value,type,size),etc)
function ExecQuery( $sql,$parameters=@()) {
<#debug#>write-host "query: "$sql
#create command obj
$cmd=new-object system.Data.SqlClient.SqlCommand($sql,$Connection)
$cmd.CommandTimeout=$timeout
#create and add parameters
foreach($item in $parameters) {
#if several params, $item is array
if($item -is [System.Array]) {
<#debug#>write-host "key = "$item[0] " ,`tvalue = "$item[1]"`t"$item[1].gettype()
if($item[3] -eq $null) { #if no size limit
$cmd.Parameters.Add($item[0], $item[2]).value = $item[1]
} else { #if size limit
$cmd.Parameters.Add($item[0], $item[2], $item[3]).Value = $item[1]
}
}
else { #if single param, $item is string
<#debug#>write-host "key = "$parameters[0] " , value = "$parameters[1]" "$parameters[1].gettype()
if($parameters[3] -eq $null) { #if no size limit
$cmd.Parameters.Add($parameters[0], $parameters[2]).Value = $parameters[1]
} else {
$cmd.Parameters.Add($parameters[0], $parameters[2], $parameters[3]).Value = $parameters[1]
}
break
}
}
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
$da.fill($ds) | Out-Null
<#debug#>foreach($Row in $ds.Tables[0].Rows){if($($Row[0])){write-host "return: $($Row[0])"}}write-host "" #line space after function output
return $ds
}
Вызывающий оператор будет выглядеть следующим образом:
$result = ExecQuery -sql (
"exec procedure_name " +
"@param1='%@param1%'," +
"@param2='%@param2%'," +
"@param3='%@param3%',"
) -parameters (
('param1','foo',[System.Data.SqlDbType]::varchar,3),
('param2',3,[System.Data.SqlDbType]::int,$null), #fail
('param3','2020-02-10 11:30:00',[System.Data.SqlDbType]::datetime,$null) #fail
)
Это проблема синтаксиса? Есть ли лучший способ, которым я мог бы сделать это? Какие-нибудь очевидные оптимизации, которые могли бы помочь? Любые хорошие подробные учебники, которые решают такие проблемы?