Windows PowerShell для SQL server
От: RusDady  
Дата: 02.10.13 19:46
Оценка:
Если кто-нибудь знаком с Powershell script, нужна помощь...
Только начал разбираться с "этим"...
Написал функцию. Функция обращается к бд, выполняет процедуру и должна возвращать код 0 если успешно или код ошибки.
НО.... когда нет ошибок, она возвращает аж два значения "-1 0", а когда ошибка, то только код ошибки...
В чем тут фишка?

Вот код функции:

if ( (Get-PSSnapin -Name SqlServerCmdletSnapin100 -ErrorAction SilentlyContinue) -eq $null ) {Add-PsSnapin SqlServerCmdletSnapin100}
if ( (Get-PSSnapin -Name SqlServerProviderSnapin100 -ErrorAction SilentlyContinue) -eq $null ) {Add-PsSnapin SqlServerProviderSnapin100}
$sql_server = "..."
$sql_db = "..."



$r = 0
$r = (CommitQuery "al_ps_error_test" "test" 1)
write-host $r
if($r -ne 0)
{
write-host "out of function msg: $error"
}

function global:CommitQuery($query, $trans_name, $cmd_type)
{
#set return variable to 0, in case of error it'll be set to error number
$res = 0

#reset all previous errors
$error.Clear()
[System.Data.SqlClient.SqlConnection]$connection = new-object System.Data.SqlClient.SqlConnection("Data Source=$sql_server;Integrated Security=SSPI;Initial Catalog=$sql_db")

try
{
if (-not ($connection.State -like "Open")) { $connection.Open() }

#Start a local transaction.
[System.Data.SqlClient.SqlTransaction]$transaction = $connection.BeginTransaction($trans_name)

$command = new-object System.Data.SqlClient.SqlCommand
$command.CommandText = $query
$command.Connection = $connection

if($cmd_type -eq 1) {$command.CommandType = [System.Data.CommandType]::StoredProcedure}
else {$command.CommandType = [System.Data.CommandType]::Text}

$command.CommandTimeout = 0
$command.Transaction = $transaction

#execute stored procedure
$command.ExecuteNonQuery()

#Attempt to commit the transaction.
$transaction.Commit()
}
catch
{
$transaction.Rollback()
if (($connection.State -like "Open")) { $connection.Close() }

if(([string]$error[0]).IndexOf("severity") -gt 0)
{
#parse sql error number from error message
if($error -eq $null) { $res = -1 } #this is unspecified error
else { $res = [int]((([System.String]($error)).Split(":")[1]).Split(",")[0]).Split(" ")[2] }
}
else { $res = -1 } #this is unspecified error
}

if (($connection.State -like "Open")) { $connection.Close() }

return $res
}



код sql процедуры:

CREATE PROCEDURE [dbo].[al_ps_error_test]
AS
BEGIN
Select null
RAISERROR (15700,0,0, 'mysp_CreateCustomer');
END
GO
Re: Windows PowerShell для SQL server
От: ZAMUNDA Земля для жалоб и предложений
Дата: 21.10.13 14:46
Оценка: 6 (1)
Здравствуйте, RusDady, Вы писали:

RD>Если кто-нибудь знаком с Powershell script, нужна помощь...

RD>Только начал разбираться с "этим"...
Ты прости, конечно. Я не троллю, но IMHO с SQLServer ты тоже недавно начал разбираться. Не запутайся во всём, смотри.

RD>Написал функцию. Функция обращается к бд, выполняет процедуру и должна возвращать код 0 если успешно или код ошибки.

RD>НО.... когда нет ошибок, она возвращает аж два значения "-1 0", а когда ошибка, то только код ошибки...

RD>В чем тут фишка?

$command.ExecuteNonQuery() суёт -1 в конвеер.
return $res суёт $res в конвеер, и прерывает выполнение функции.

# он бросит ошибку, если нет такой оснастки, иначе подключит и SqlServerCmdletSnapin100, и SqlServerProviderSnapin100 
Add-PsSnapin SqlServer*;
# если боишся dllhell то
Add-PsSnapin SqlServer*Snapin100;

Плюс в SQLPS эти оснастки подключены по умолчанию.

Если уж ты используешь оснастку, то прощще сделать объект сервера:
# по мощьнооболочовски
$Srv = gi "SQLSERVER:\SQL\$sql_server";
# по точкосетковски
$Srv = New-Object Microsoft.SqlServer.Management.Smo.Server($sql_server);

У него есть ConnectionContext, а у него есть много всего... gm тебе в помощь.


Почитай
Get-Help about_Try_Catch_Finally;
Get-Help Invoke-SQLCommand;
Get-Help Get-Member;


"global:" не стоит пока использовать. Затрёшь важную переменную или функцию, ухрюкаесся разбираться.
Точки с запятой не забывай ставить.
Применяй литерную строку (в '' а не в ""), если тебе ненужно распарсивать имена переменных.

RD>код sql процедуры:


RD>CREATE PROCEDURE [dbo].[al_ps_error_test]

RD>AS
RD>BEGIN
RD> Select null
RD> RAISERROR (15700,0,0, 'mysp_CreateCustomer');
RD>END
RD>GO
Всё правильно процедура вернёт 0.
RAISERROR с severity меньше 11, не меняет @@ERROR, а прощще никакой ошибки фактически не генерит. И ещё... Если было сообщение с severity больше 10, то при отсутствии последующего RETURN со значением, возвращаемый параметр процедуры будет отрицательное число; если RETURN со значением небыло и небыло сообщения с severity больше 10 (т.е. ошибки небыло), то возвращаемый параметр процедуры будет ноль.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.