2011-04-28 32 views
3

用Delphi 7,BDE和OracleORA-01000:最大打開的遊標超出

我執行SQL SELECT語句,然後通過各自的返回set的記錄步驟,並執行以下更新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; 

它的工作原理爲福斯特500分+的記錄,但後來我得到一個:ORA-01000:最大打開的遊標超出消息

有什麼我需要在BDE側做,Oracle方面,或在我的代碼(使用標準TQuery和TDatabase組件的Im)

+1

你看過http://mail.dir.bg/~radoslav.rusinov/Blog/How.to.Cope.with.an.ORA-01000.Error-v.2.1。 pdf? – SimaWB 2011-04-28 12:26:29

+1

你至少應該把Close()和Free()放在try/finally塊中。但我不認爲這會解決問題。 – 2011-04-28 12:28:15

+0

ParamByName('AMasterId')。AsString:= IntToStr(AId);可以簡單地寫成ParamByName('AMasterId')。AsInteger:= AId;也許你可以在日期上做同樣的事情。爲什麼獲取日期,將其轉換爲字符串,然後獲取該字符串並將其轉換爲日期?如果您只需要獲得日/月/年的部分,則有更好的方法(即Trunc())。 – 2011-04-28 15:00:51

回答

2

您關閉查詢的地方不正確,這意味着您對每行都是孤兒遊標。試試這個:

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; 
+0

不正確。我上面發佈的代碼是一個例程。我通過select sql返回集循環,調用每條記錄的例程。所以,如果你看看我上面發佈的代碼,對於select中的每個記錄,上面的代碼被調用(或者調用該例程)。查詢被創建,執行,關閉和釋放,循環轉到select語句中的下一條記錄並執行例程(上面的代碼)。 – IElite 2011-04-28 13:05:50

+1

Shane,在發表評論之前,你有沒有試過Ken的答案?我相信這是解決您的問題的方法。順便說一下,Except之後的代碼將不會執行。 – RBA 2011-04-28 13:12:37

+1

然後,您未能發佈顯示它是函數/過程的代碼部分。 (你的問題也沒有提及這一點。)「遍歷返回集合的每條記錄並執行下面的更新sql」 - 這看起來像是一個循環給我,並且沒有任何其他方式知道我的答案是基於。 – 2011-04-28 13:13:24

相關問題