Bug #19056 stored procedures throws exception datreader already open
Submitted: 12 Apr 2006 16:55 Modified: 18 May 2006 12:06
Reporter: Nir Amber Email Updates:
Status: No Feedback Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:5.0.18 OS:Windows (winxp)
Assigned to: CPU Architecture:Any

[12 Apr 2006 16:55] Nir Amber
Description:
I get the following error when trying to execute stored procedures:

MySql.Data.MySqlClient.MySqlException was caught
  Message="There is already an open DataReader associated with this Connection which must be closed first."
  Source="Microsoft.VisualBasic"
  StackTrace:
       at Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(Method TargetProcedure, Object[] Arguments, Boolean[] CopyBack, BindingFlags Flags)
       at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)
       at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)
       at DButils.executeSp(String pstrSpName, String[][] pstrarrParamInfo) in c:\inetpub\wwwroot\Motonew\App_Code\DbUtils.vb:line 78

How to repeat:
The following vb.net code is used:

  Const CONNECTION_STRING As String = "Database=thedb;Data Source=localhost;User Id=root;Password=xxxx"

Public Sub insertRepairPart(ByVal updatedBy As String, ByVal jobId As String, ByVal partCode As String, ByVal prtQuantity As String, ByVal typeId As String, ByVal designatorCode As String)
        Dim lstrParamInfo(5)() As String
        lstrParamInfo(0) = New String() {"iUpdatedBy", "Int", updatedBy, "11", "in"}
        lstrParamInfo(1) = New String() {"iJOB_ID", "Int", jobId, "11", "in"}
        lstrParamInfo(2) = New String() {"vPRT_Code", "varchar", partCode, "20","in"}
        lstrParamInfo(3) = New String() {"iPrtQuantity", "Int", prtQuantity, "11", "in"}
        lstrParamInfo(4) = New String() {"iTYP_ID", "Int", typeId, "11", "in"}
        lstrParamInfo(5) = New String() {"vDesignatorCode", "varchar", designatorCode, "20", "in"}
        executeSp("MotoDB.SP_iRepairPart", lstrParamInfo)
 End Sub

 Private Function executeSp(ByVal pstrSpName As String, ByVal pstrarrParamInfo As String()()) As DataTable

  Dim lsqlconDBConnection As MySqlConnection = New MySqlConnection(CONNECTION_STRING)
        Dim lsqldapDataAdapter = New MySqlDataAdapter
        Dim lsqlprmSqlParameter As MySqlParameter
        Dim lsqldbtSqlParamType As MySqlDbType = MySqlDbType.VarChar
        Dim lrsSpResults As DataSet = New DataSet()
        Dim lrsReturnResults As DataTable = New DataTable()
        Dim lintOuputParamCount As Integer = 0
        Dim lobjarrOuputParameterReuslts As Object()
        Dim lblnNoResults As Boolean = False
        Dim i As Integer
        Try

            lsqldapDataAdapter.SelectCommand = New MySqlCommand(pstrSpName, lsqlconDBConnection)
            lsqldapDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure
            If Not (pstrarrParamInfo Is Nothing) Then
                For i = 0 To (pstrarrParamInfo.Length - 1)
                    Select Case (pstrarrParamInfo(i)(1).ToLower())
                        Case "int"
                            lsqldbtSqlParamType = MySqlDbType.Int64
                        Case "varchar"
                            lsqldbtSqlParamType = MySqlDbType.VarChar
                        Case "datetime"
                            lsqldbtSqlParamType = MySqlDbType.Datetime
                        Case "decimal"
                            lsqldbtSqlParamType = MySqlDbType.Double
                    End Select

                    lsqlprmSqlParameter = lsqldapDataAdapter.SelectCommand.Parameters.Add(pstrarrParamInfo(i)(0), lsqldbtSqlParamType)
                    If (isNumber(pstrarrParamInfo(i)(3))) Then
                        lsqlprmSqlParameter.Size = Integer.Parse(pstrarrParamInfo(i)(3))
                    End If
                    If Not (pstrarrParamInfo(i)(1).ToLower() = "datetime" And pstrarrParamInfo(i)(2) = "") Then
                        lsqlprmSqlParameter.Value = pstrarrParamInfo(i)(2)
                    End If

                    If (pstrarrParamInfo(i)(4).ToLower().Equals("out")) Then
                        lintOuputParamCount += 1
                        lsqlprmSqlParameter.Direction = ParameterDirection.InputOutput
                    Else
                        lsqlprmSqlParameter.Direction = ParameterDirection.Input
                    End If
                Next
            End If

            Try
                lsqldapDataAdapter.Fill(lrsSpResults)
            Catch ex As Exception
                'If (lrsSpResults.Tables.Count = 0) Then
                'Thread.Sleep(40)
                lsqldapDataAdapter.Fill(lrsSpResults)
                'End If
            End Try
 End Sub

the stored procedure is:

DROP PROCEDURE IF EXISTS `MotoDB`.`SP_iPart`;
CREATE PROCEDURE `MotoDB`.`SP_iPart`
(          INOUT iID           INT,
           IN iUpdatedBy       INT ,
	       IN vPart_Code      VARCHAR(5),
	       IN vDesignator_Code VARCHAR(5),
	       IN cCost		   DECIMAL(9,2),
	   IN iRecordStatus     INT
)
BEGIN
DECLARE iExists INT;
DECLARE bInsertNew Boolean;

     SET bInsertNew := TRUE ;
     IF (iID is not null) THEN
       SELECT COUNT(1)
              INTO iExists
       FROM   PRT_Parts
       WHERE  ID=iID
       AND    MasterID=ID;
       IF (iExists>0) THEN
          SET bInsertNew := FALSE ;
       END IF;
     END IF;

     IF (bInsertNew = TRUE) THEN
        INSERT INTO PRT_Parts
        (
         Recordstatus,
         ValidFrom,
         ValidTo,
         UpdatedBy,
	     Part_Code ,
	     Designator_Code,
	     Cost	
        )
        VALUES
        (
          1,
          CURRENT_TIMESTAMP,
          NULL,
          iUpdatedBy,
	      vPart_Code ,
	      vDesignator_Code,
	      cCost	
        );

        UPDATE PRT_Parts
        SET MasterID = LAST_INSERT_ID()
        WHERE ID = LAST_INSERT_ID();
        SET iID:=LAST_INSERT_ID();
     ELSE

         INSERT INTO PRT_Parts
         (
         Recordstatus,
         ValidFrom,
         ValidTo,
         MasterID,
         UpdatedBy,
         Part_Code ,
	     Designator_Code,
	     Cost
         )
         SELECT
         2,
         ValidFrom,
         CURRENT_TIMESTAMP,
         MasterID,
         UpdatedBy,
         Part_Code ,
	     Designator_Code,
	     Cost
         FROM   PRT_Parts
         WHERE  ID=iID;

         UPDATE PRT_Parts
         SET
         Recordstatus = iRecordStatus ,
         ValidFrom = CURRENT_TIMESTAMP,
         ValidTo = NULL,
         MasterID = iID,
         UpdatedBy = iUpdatedBy,
         Part_Code = vPart_Code,
	     Designator_Code = vDesignator_Code,
	     Cost = cCost
         WHERE  ID=iID;

     END IF;

END;

table creation script:

CREATE TABLE `prt_parts` (
  `ID` int(11) NOT NULL auto_increment,
  `MasterID` int(11) default NULL,
  `Recordstatus` int(11) default NULL,
  `ValidFrom` datetime default NULL,
  `ValidTo` datetime default NULL,
  `UpdatedBy` int(11) default NULL,
  `Part_Code` int(11) default NULL,
  `Cost` decimal(9,2) default NULL,
  `TYP_ID` int(11) default NULL,
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
[18 Apr 2006 12:06] Tonci Grgin
Hi. Thanks for your detailed problem report. Can you please check 
http://bugs.mysql.com/bug.php?id=7248 and see if it answers your question.
[18 May 2006 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".