OUTPUT Params and RecordSet Problem
- From: INTP56 <INTP56@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 2 Oct 2007 09:57:00 -0700
I'm trying to call a procedure that has OUTPUT params and returns a record
set. In Excel 2003 VBA (Microsoft ActiveX Data Objects 2.8 Library), I seem
to only be able to get one or the other.
In SQL Server 2005, I got the expected results running this script:
USE ICEBOX;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
IF EXISTS
(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
WHERE
ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_SCHEMA = 'dbo'
AND ROUTINE_NAME = 'USP_ProcedureTest'
)
DROP PROCEDURE dbo.USP_ProcedureTest;
GO
CREATE PROCEDURE dbo.USP_ProcedureTest
(
@String256 VARCHAR(256)
,@ReverseString256 VARCHAR(256) OUTPUT
,@RStringLength INT OUTPUT
) AS SET NOCOUNT ON;
BEGIN
SET @ReverseString256 = REVERSE(@String256);
SET @RStringLength = LEN(@ReverseString256);
SELECT '@String256' AS Variable, @String256 AS Value
UNION ALL
SELECT '@ReverseString256' AS Variable, @ReverseString256 AS Value
UNION ALL
SELECT 'RETURNS' AS Variable, CAST(@RStringLength AS VARCHAR) AS Value;
END;
GO
DECLARE @Return INT, @Input VARCHAR(256), @OutPut VARCHAR(256), @Len INT;
SET @Input = 'StringToReverse';
EXEC @Return = dbo.USP_ProcedureTest
@String256 = @Input
,@ReverseString256 = @Output OUTPUT
,@RStringLength = @Len OUTPUT;
PRINT '@Return' + CHAR(9) + CAST(@Return AS VARCHAR);
PRINT '@Input' + CHAR(9) + @Input;
PRINT '@Output' + CHAR(9) + @Output;
PRINT '@Len' + CHAR(9) + CAST(@Len AS VARCHAR);
GO
In Excel 2003 VBA, in the following function, I have this section:
With ADODB_Command
.ActiveConnection = ADODB_Connection
.CommandType = adCmdStoredProc
.CommandText = "dbo.USP_ProcedureTest"
.Parameters.Refresh
.Parameters("@String256").Value = "StringToReverse"
.Execute Options:=adExecuteNoRecords
strReverse = .Parameters("@ReverseString256").Value
lngLength = .Parameters("@RStringLength").Value
Set ADODB_RecordSet = .Execute()
End With
Notice I have .Execute in there twice. I did that because it seems I have to
use
..Execute Options:=adExecuteNoRecords
to get the OUTPUT parameters to not be NULL, and I use
Set ADODB_RecordSet = .Execute()
To get the record set back. It seems to me I should be able to do both tasks
without executing the statement twice.
Any Ideas?
Thanks, Bob
Here is the full Function
Option Explicit
'Include Reference to Microsoft ActiveX Data Objects 2.8 Library
Private Function ExecuteTestProcedure(strConnection As String, Optional
blnIncludeFieldNames As Boolean = True, Optional strError As String = "") As
Variant
Dim ADODB_Connection As New ADODB.Connection
Dim ADODB_Command As New ADODB.Command
Dim ADODB_RecordSet As ADODB.Recordset
Dim strReverse As String, lngLength As Long, varReturnSet As Variant
Dim varRecordSet As Variant, strFieldNames() As String
Dim lngRowCount As Long, lngFieldCount As Long
Dim r&, c&
varReturnSet = Empty
On Error GoTo ExitRoutine
'If strConnection is an existing file, assume UDL file, otherwise,
regular string.
If Len(Dir(strConnection, vbNormal)) > 0 Then
ADODB_Connection.ConnectionString = "FILE NAME=" + strConnection
Else
ADODB_Connection.ConnectionString = strConnection
End If
ADODB_Connection.Open
If ADODB_Connection.State <> adStateOpen Then
strError = "Could not open database"
GoTo ExitRoutine
End If
With ADODB_Command
.ActiveConnection = ADODB_Connection
.CommandType = adCmdStoredProc
.CommandText = "dbo.USP_ProcedureTest"
.Parameters.Refresh
.Parameters("@String256").Value = "StringToReverse"
.Execute Options:=adExecuteNoRecords
strReverse = .Parameters("@ReverseString256").Value
lngLength = .Parameters("@RStringLength").Value
Set ADODB_RecordSet = .Execute()
End With
If ADODB_RecordSet Is Nothing Then
strError = "ADODB_RecordSet Is Nothing"
varReturnSet = Empty
GoTo ExitRoutine
End If
With ADODB_RecordSet
lngFieldCount = .Fields.Count
ReDim strFieldNames(1 To lngFieldCount)
For c = 1 To lngFieldCount
strFieldNames(c) = .Fields(c - 1).Name
Next c
If .BOF Or .EOF Then
varRecordSet = Empty
lngRowCount = 0
Else
varRecordSet = .GetRows
lngRowCount = UBound(varRecordSet, 2) - LBound(varRecordSet, 2)
+ 1
End If
End With
If blnIncludeFieldNames And lngRowCount <= 0 Then
ReDim varReturnSet(0 To 0, 1 To lngFieldCount) As Variant
End If
If blnIncludeFieldNames And lngRowCount > 0 Then
ReDim varReturnSet(0 To lngRowCount, 1 To lngFieldCount) As Variant
End If
If Not blnIncludeFieldNames And lngRowCount > 0 Then
ReDim varReturnSet(1 To lngRowCount, 1 To lngFieldCount) As Variant
End If
If LBound(varReturnSet, 1) = 0 Then
For c = 1 To lngFieldCount
varReturnSet(0, c) = strFieldNames(c)
Next c
End If
If lngRowCount > 0 Then
For r = 1 To lngRowCount
For c = 1 To lngFieldCount
varReturnSet(r, c) = varRecordSet(c - 1, r - 1)
Next c
Next r
End If
ExitRoutine:
If Err.Number <> 0 Then
strError = Err.Description + vbCrLf + Err.Source
End If
On Error GoTo 0
ExecuteTestProcedure = varReturnSet
If Not ADODB_RecordSet Is Nothing Then
If ADODB_RecordSet.State = adStateOpen Then
ADODB_RecordSet.Close
End If
Set ADODB_RecordSet = Nothing
End If
Set ADODB_Command = Nothing
If Not ADODB_Connection Is Nothing Then
If ADODB_Connection.State = adStateOpen Then
ADODB_Connection.Close
End If
Set ADODB_Connection = Nothing
End If
End Function
.
- Follow-Ups:
- Re: OUTPUT Params and RecordSet Problem
- From: Bob Barrows [MVP]
- Re: OUTPUT Params and RecordSet Problem
- Prev by Date: Re: Trouble recreating ADO recordset from XML
- Next by Date: Re: OUTPUT Params and RecordSet Problem
- Previous by thread: Re: Retrieving a BigInt out parameter from a Stored Procedure
- Next by thread: Re: OUTPUT Params and RecordSet Problem
- Index(es):