Browse Source

* fix for leaking handles in parameter buffers, Mantis #17260, patch by Ludo Brands.

git-svn-id: trunk@19484 -
marco 14 years ago
parent
commit
98ac246990
1 changed files with 21 additions and 16 deletions
  1. 21 16
      packages/fcl-db/src/sqldb/odbc/odbcconn.pas

+ 21 - 16
packages/fcl-db/src/sqldb/odbc/odbcconn.pas

@@ -333,6 +333,8 @@ begin
       raise EODBCException.CreateFmt('The query has parameter markers in it, but no actual parameters were passed',[]);
 
   SetLength(ODBCCursor.FParamBuf, Length(ODBCCursor.FParamIndex));
+  for i:=0 to High(ODBCCursor.FParamIndex) do
+    ODBCCursor.FParamBuf[i]:=nil;
   for i:=0 to High(ODBCCursor.FParamIndex) do
   begin
     ParamIndex:=ODBCCursor.FParamIndex[i];
@@ -496,7 +498,8 @@ var
   i:integer;
 begin
   for i:=0 to High(ODBCCursor.FParamBuf) do
-    FreeMem(ODBCCursor.FParamBuf[i]);
+    if assigned(ODBCCursor.FParamBuf[i]) then
+      FreeMem(ODBCCursor.FParamBuf[i]);
   SetLength(ODBCCursor.FParamBuf,0);
 end;
 
@@ -694,23 +697,25 @@ var
 begin
   ODBCCursor:=cursor as TODBCCursor;
 
-  // set parameters
+  try
+    // set parameters
     if Assigned(APArams) and (AParams.count > 0) then SetParameters(ODBCCursor, AParams);
+    // execute the statement
+    case ODBCCursor.FSchemaType of
+      stNoSchema  : Res:=SQLExecute(ODBCCursor.FSTMTHandle); //SQL_NO_DATA returns searched update or delete statement that does not affect any rows
+      stTables    : Res:=SQLTables (ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0, TABLE_TYPE_USER, length(TABLE_TYPE_USER) );
+      stSysTables : Res:=SQLTables (ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0, TABLE_TYPE_SYSTEM, length(TABLE_TYPE_SYSTEM) );
+      stColumns   : Res:=SQLColumns(ODBCCursor.FSTMTHandle, nil, 0, nil, 0, @ODBCCursor.FQuery[1], length(ODBCCursor.FQuery), nil, 0 );
+      stProcedures: Res:=SQLProcedures(ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0 );
+      else          Res:=SQL_NO_DATA;
+    end; {case}
+
+    if (Res<>SQL_NO_DATA) then ODBCCheckResult( Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' );
 
-  // execute the statement
-  case ODBCCursor.FSchemaType of
-    stNoSchema  : Res:=SQLExecute(ODBCCursor.FSTMTHandle); //SQL_NO_DATA returns searched update or delete statement that does not affect any rows
-    stTables    : Res:=SQLTables (ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0, TABLE_TYPE_USER, length(TABLE_TYPE_USER) );
-    stSysTables : Res:=SQLTables (ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0, TABLE_TYPE_SYSTEM, length(TABLE_TYPE_SYSTEM) );
-    stColumns   : Res:=SQLColumns(ODBCCursor.FSTMTHandle, nil, 0, nil, 0, @ODBCCursor.FQuery[1], length(ODBCCursor.FQuery), nil, 0 );
-    stProcedures: Res:=SQLProcedures(ODBCCursor.FSTMTHandle, nil, 0, nil, 0, nil, 0 );
-    else          Res:=SQL_NO_DATA;
-  end; {case}
-
-  if (Res<>SQL_NO_DATA) then ODBCCheckResult( Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' );
-
-  // free parameter buffers
-  FreeParamBuffers(ODBCCursor);
+  finally
+    // free parameter buffers
+    FreeParamBuffers(ODBCCursor);
+  end;
 end;
 
 function TODBCConnection.RowsAffected(cursor: TSQLCursor): TRowsCount;