oracle ORA-01000: 超出最大打开游标数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5818494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 23:31:35  来源:igfitidea点击:

ORA-01000: maximum open cursors exceeded

oracledelphidelphi-7

提问by IElite

Using Delphi 7, BDE, and Oracle

使用 Delphi 7、BDE 和 Oracle

I perform a SQL select statement and then step through each of the records of the returned set and perform the following update sql

我执行一个 SQL select 语句,然后单步执行返回集的每个记录并执行以下更新 sql

var
 AQuery: TQuery;
begin
 AQuery:= TQuery.Create(nil);
 AQuery.DatabaseName:= ADatabase.DatabaseName;
 with AQuery do
 begin
  SQL.Text:= 'UPDATE AP_Master SET CMCL_FORECAST_CLEARED=:AClearedDate WHERE ID=:AMasterId';
  ParamByName('AMasterId').AsString:= IntToStr(AId);
  ParamByName('AClearedDate').AsDateTime:= StrToDateTime(FormatDateTime('mm/dd/yyyy', AForeCastClearedDate));
  try
   ExecSql;
  except on E: Exception do
   begin
    raise Exception.create('Error Updating AP_Master Tables Forecast Cleared Date!' + E.Message);
   end;//except
  end; //try
 end; //with
 AQuery.Close;
 AQuery.Free;
end;

It works for the forst 500 + records, but i then get a : ORA-01000: maximum open cursors exceeded message

它适用于前 500 多条记录,但随后我收到一条:ORA-01000:超出最大打开游标数消息

Is there something i need to do on the BDE side, oracle side, or within my code (Im using standard TQuery and TDatabase components)

我需要在 BDE 端、oracle 端或我的代码中做些什么(我使用标准的 TQuery 和 TDatabase 组件)

采纳答案by Ken White

Your close of the query is out of place, meaning you're orphaning cursors for each row. Try this instead:

您关闭查询不合适,这意味着您正在为每一行孤立游标。试试这个:

var
 AQuery: TQuery;
begin
  AQuery:= TQuery.Create(nil);
  try
    AQuery.DatabaseName:= ADatabase.DatabaseName;

    with AQuery do
    begin
      SQL.Text:= 'UPDATE AP_Master'#13 +
                 'SET CMCL_FORECAST_CLEARED = :AClearedDate'#13 +
                 'WHERE ID= :AMasterId';
      ParamByName('AMasterId').AsInteger := AId;
      // Note the date->string->date is not necessary; setting the param
      // AsDateTime with a TDateTime value will format it correctly for you.
      ParamByName('AClearedDate').AsDateTime:= AForeCastClearedDate;

      try // Protect open
        try
          ExecSql;
          except 
           on E: Exception do
             raise Exception.create('Error Updating AP_Master Tables' +
                                    ' Forecast Date Cleared' +
                                    E.Message);   
          end;//except
        end; // except try
      finally
        AQuery.Close;  // finally means it's closed every time always
      end; //finally try for opening
    end; //with
  finally
    AQuery.Free;  // finally here ensures free
  end;
end;