Возвращаемое значение, указывающее на успешное обновление / сбой хранимой процедуры SQL Server через ADO / VBA. - PullRequest
2 голосов
/ 17 июля 2010

У меня есть хранимая процедура SQL Server 2008, которая обновляет значения в таблице.Я хотел бы, чтобы хранимая процедура возвращала целочисленное значение, указывающее, что обновление прошло успешно (возвращает 0) или нет (возвращает номер ошибки).Каков наилучший способ сделать это через ADO и VBA?Вот часть моего кода в упрощенном виде, который выполняет обновление ... Я просто не уверен, как вернуть возвращаемое значение хранимой процедуры

Public Function DoUpdate(employeeID as integer, firstName as string, lastname as string) as integer

  Dim cnn As ADODB.Connection
  Dim cmd As ADODB.Command
  Dim activeConnectionString As String

  activeConnectionString = GetActiveConnectionString()

  Set cnn = New ADODB.Connection
  cnn.ConnectionString = activeConnectionString
  cnn.CursorLocation = adUseClient
  cnn.Open

  Set cmd = New ADODB.Command
  cmd.ActiveConnection = cnn
  cmd.CommandType = adCmdStoredProc
  cmd.CommandText = "uspUpdateEmployeeName"
  cmd.NamedParameters = True

  cmd.Parameters("@EmployeeID").Value = employeeID 
  cmd.Parameters("@FirstName").Value = firstName
  cmd.Parameters("@LastName").Value = lastName

  cmd.Execute

  'Unsure of how to get back return value here
  'DoUpdate = returnValue

  Set cnn = Nothing

End Function

Ответы [ 4 ]

4 голосов
/ 27 августа 2014

Примечание: return_value должен быть первым параметром!

Заказ имеет значение.

Я получал ошибки, утверждая, что мой запрос"had too many arguments" когда я указывал свой параметр return_value последним, а не первым.

Причиной моей ошибки было упорядочение параметров.

2 голосов
/ 17 июля 2010

Кажется, я помню, что вам нужно предоставить дополнительный параметр типа adParamReturnValue, например:

Dim lRetVal as Long

Set cmd = New ADODB.Command
cmd.Parameters.Append .CreateParameter("returnvalue", adInteger, adParamReturnValue)

cmd.Execute

'Now check the return value of the procedure
lRetVal = cmd.Parameters("returnvalue")

If lRetVal > 0 then
2 голосов
/ 17 июля 2010

Если вы используете

Dim lngRecs As Long

cmd.Execute lngRecs

lngRecs должен содержать затронутые записи.

1 голос
/ 31 июля 2015

Существует несколько способов получения значений с помощью VBA:

  1. Recordset
  2. Количество затронутых записей (только для вставки / обновления / удаления -1)
  3. Выходной параметр
  4. Возвращаемое значение

Мой код демонстрирует все четыре. Вот хранимая процедура, которая возвращает значение:

Create PROCEDURE CheckExpedite
    @InputX  varchar(10),
    @InputY int,
    @HasExpedite int out
AS
BEGIN
    Select @HasExpedite = 9 from <Table>
    where Column2 = @InputX and Column3 = @InputY

    If @HasExpedite = 9
        Return 2
    Else
        Return 3
End

Вот подпункт, который я использую в Excel VBA. Вам понадобится ссылка на библиотеку Microsoft ActiveX Data Objects 2.8.

Sub CheckValue()

    Dim InputX As String: InputX = "6000"
    Dim InputY As Integer: InputY = 2014

    'open connnection
    Dim ACon As New Connection
    'ACon.Open ("Provider=SQLOLEDB;Data Source=<SqlServer>;" & _
    '    "Initial Catalog=<Table>;Integrated Security=SSPI")

    'set command
    Dim ACmd As New Command
    Set ACmd.ActiveConnection = ACon
    ACmd.CommandText = "CheckExpedite"
    ACmd.CommandType = adCmdStoredProc

    'Return value must be first parameter else you'll get error from too many parameters
    'Procedure or function "Name" has too many arguments specified.
    ACmd.Parameters.Append ACmd.CreateParameter("ReturnValue", adInteger, adParamReturnValue)
    ACmd.Parameters.Append ACmd.CreateParameter("InputX", adVarChar, adParamInput, 10, InputX)
    ACmd.Parameters.Append ACmd.CreateParameter("InputY", adInteger, adParamInput, 6, InputY)
    ACmd.Parameters.Append ACmd.CreateParameter("HasExpedite", adInteger, adParamOutput)

    Dim RS As Recordset
    Dim RecordsAffected As Long

    'execute query that returns value
    Call ACmd.Execute(RecordsAffected:=RecordsAffected, Options:=adExecuteNoRecords)

    'execute query that returns recordset
    'Set RS = ACmd.Execute(RecordsAffected:=RecordsAffected)

    'get records affected, return value and output parameter
    Debug.Print "Records affected: " & RecordsAffected
    Debug.Print "Return value: " & ACmd.Parameters("ReturnValue")
    Debug.Print "Output param: " & ACmd.Parameters("HasExpedite")

    'use record set here
    '...

    'close
    If Not RS Is Nothing Then RS.Close
    ACon.Close

End Sub
...