Gostaria de uma ajuda. Preciso montar uma função VB genérica para executar Stored Procedures (SPs) e retornar um valor destas. No caso, essas SPs irão retornar a ID do registro que acabou de ser incluído. Como o projeto usa Selects com o comando "WITH (NOLOCK)", está ocorrendo a perda da ID correta caso seja usado o comando Select Max().
O sistema está em uso por uma empresa e vários usuários realizam cadastros quase simultaneamente. Normalmente, ao inserir uma informação, é dado um Select Max para atribuir a ID do registro recém inserido à uma variável no VB. Porém, devido ao explicado acima, está ocorrendo a troca de IDs.
Ai veio a idéia de testar o retorno de informação das SPs com SCOPE IDENTITY, para ter maior segurança com os dados inseridos e ter a confiança que trará a ID correta. Porém, cada SP tem uma quantidade de parâmetros que são passados. Então teria que montar uma função genérica para, de acordo com a SP, inserir os parâmetros. É a primeira vez que uso o ADODB.Parameters e estou meio perdido.
Segue abaixo o código:
Public Function gfcnExecutarIDAtual(ByVal lstrProcedure As String, _
ByRef lstrParametros() As String) As Variant
Dim llngContador As Long 'Usado para o laço dos parâmetros
Dim lstrSQL As String 'Usado para retornar os nomes dos parâmetros da SP
Dim lcmmExecute As New ADODB.Command
Dim ladoParametro As New ADODB.Parameter
Dim lrsDados As ADODB.Recordset
Dim ladoTipo As ADODB.DataTypeEnum
Dim ladoEntradaSaida As ADODB.ParameterDirectionEnum
gfcnExecutarIDAtual = 0
With lcmmExecute
.ActiveConnection = gconConexao
.CommandType = adCmdText
If UBound(lstrParametros) >= 0 Then
'# Retorna o nome das colunas/parâmetros da SP
lstrSQL = "sp_sproc_columns " & lstrProcedure
Set lrsDados = New ADODB.Recordset
lrsDados.CursorType = adOpenForwardOnly
lrsDados.CursorLocation = adUseClient
lrsDados.LockType = adLockReadOnly
lrsDados.Open lstrSQL, gconConexao, , , adCmdText
'# O primeiro parâmetro sempre é RETURN_VALUE. Não iremos trabalhar com ele.
If lrsDados(eParametrosSP.eNomeParametro).Value = "@RETURN_VALUE" Then lrsDados.MoveNext
.CommandType = CommandTypeEnum.adCmdStoredProc
'# É adicionado mais um ao índice máximo do vetor para que seja incluído
'# o parâmetro que retorna a IDAtual (@O_IDATUAL)
For llngContador = 0 To (UBound(lstrParametros) + 1)
'# Verifica o tipo do parâmetro - Coluna 6
Select Case UCase(CStr(lrsDados.Fields.Item(eParametrosSP.eTipoParametro)))
Case "INT"
ladoTipo = ADODB.DataTypeEnum.adInteger
Case "NUMERIC"
ladoTipo = ADODB.DataTypeEnum.adNumeric
Case "VARCHAR"
ladoTipo = ADODB.DataTypeEnum.adVarChar
End Select
'# Verifica se é um parâmetro de Entrada ou Saída
If Mid(CStr(lrsDados(eParametrosSP.eNomeParametro).Value), 1, 2) = "@I" Then
ladoEntradaSaida = ADODB.ParameterDirectionEnum.adParamInput
Else
ladoEntradaSaida = ADODB.ParameterDirectionEnum.adParamOutput
End If
'# O parâmetro de saída (retorno) não passa valores
If llngContador <= UBound(lstrParametros) Then
.Parameters.Append .CreateParameter(lrsDados(eParametrosSP.eNomeParametro).Value, ladoTipo, ladoEntradaSaida, , lstrParametros(llngContador))
Else
.Parameters.Append .CreateParameter(lrsDados(eParametrosSP.eNomeParametro).Value, ladoTipo, ladoEntradaSaida)
End If
lrsDados.MoveNext
Next
End If
.CommandText = lstrProcedure
.Execute
gfcnExecutarIDAtual = .Execute("@O_IDATUAL")
End With
Set lrsDados = Nothing
Set lcmmExecute = Nothing
End Function
Como pode ser visto, os parâmetros são portanto criados dinamicamente. Neste laço que estou testando, com 3 parâmetros, a primeira execução ocorre corretamente (passando pelo primeiro Parameter.Append). Logo após isso, ao tentar passar novamente pelo primeiro Append, ocorre um erro. Como os valores mudaram e não entendo muito desse objeto, não entendi o motivo do erro. Em vários lugares que pesquisei não achei nada anormal com o código.
O erro é o seguinte: "Objeto Parameter definido incorretamente. As informações são inconsistentes ou incompletas."
Pergunta
Xistyle
Pessoal, boa tarde!
Gostaria de uma ajuda. Preciso montar uma função VB genérica para executar Stored Procedures (SPs) e retornar um valor destas. No caso, essas SPs irão retornar a ID do registro que acabou de ser incluído. Como o projeto usa Selects com o comando "WITH (NOLOCK)", está ocorrendo a perda da ID correta caso seja usado o comando Select Max().
O sistema está em uso por uma empresa e vários usuários realizam cadastros quase simultaneamente. Normalmente, ao inserir uma informação, é dado um Select Max para atribuir a ID do registro recém inserido à uma variável no VB. Porém, devido ao explicado acima, está ocorrendo a troca de IDs.
Ai veio a idéia de testar o retorno de informação das SPs com SCOPE IDENTITY, para ter maior segurança com os dados inseridos e ter a confiança que trará a ID correta. Porém, cada SP tem uma quantidade de parâmetros que são passados. Então teria que montar uma função genérica para, de acordo com a SP, inserir os parâmetros. É a primeira vez que uso o ADODB.Parameters e estou meio perdido.
Segue abaixo o código:
Como pode ser visto, os parâmetros são portanto criados dinamicamente. Neste laço que estou testando, com 3 parâmetros, a primeira execução ocorre corretamente (passando pelo primeiro Parameter.Append). Logo após isso, ao tentar passar novamente pelo primeiro Append, ocorre um erro. Como os valores mudaram e não entendo muito desse objeto, não entendi o motivo do erro. Em vários lugares que pesquisei não achei nada anormal com o código.
O erro é o seguinte: "Objeto Parameter definido incorretamente. As informações são inconsistentes ou incompletas."
Poderiam me ajudar?
Editado por XistyleLink para o comentário
Compartilhar em outros sites
6 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.