Q&A

  • 오라클에 트랜잭션으로 insert 할때 오류발생하면 오류로그를 작성한후 계속진행 안되는군요-_-;;
제목 그대로
오라클 테이블에 트랜잭션걸고 insert 할때 오류발생하면 오류로그를 작성한후 문제가 되는
해당 레코드를 넘어서 계속 insert진행하고 싶습니다.-_-;;
제가 짠 소스는 프로그램이 진행하다가 오류를 만나면 그냥 멈춰버려요..
고수님들의 가르침을 주세요...-_-;;;

procedure TForm1.Button2Click(Sender: TObject);

var
Row,max        : integer;
LogFileName,ErrMsg   : string;
ErrLogFile: TextFile;

begin
try
try
   SendMessage(progressbar1.Handle, PBM_SETBARCOLOR, 0, clGreen);
   if MessageDlg('저장하시겠습니까?', mtwarning,[mbYes, mbNo], 0) = mrYes then   begin
    //트랜잭션 시작
    Database1.StartTransaction;
    For Row := 1 to StringGrid1.RowCount-1  do  begin

       Query3.Close;
       Query3.SQL.Clear;
       Query3.SQL.BeginUpdate;
       Query3.SQL.Add('Insert into upTABLE(no, xxx, yyy)');
       Query3.SQL.Add(' values (:no, :xxx, :yyyy)');
       Query3.SQL.EndUpdate;

       Query3.ParamByName('no').asinteger := max+Row;
       Query3.ParamByName('xxx').asstring := UpperCase(Trim(stringgrid1.Cells[1, Row]));
       Query3.ParamByName('yyy').asstring := Trim(stringgrid1.Cells[2, Row]);
      
      
       Query3.Prepare;
       Query3.ExecSQL;
            
     end;  // For end

     showmessage('업데이트 되었습니다.');
     Database1.Commit;
     Exit;
     end
   else
     showmessage('취소하셨습니다.!!');        // if end
     Exit;
except
   on err:exception do
   begin
      
     LogFileName :=  ExtractFilePath(Application.ExeName)
             + ExtractFileName(Application.ExeName) + '_' +FormatDateTime('yyyy"년"mm"월"dd"일"',Now) + '.log';

      // 민약, 에러로그가 없으면 에러로그 파일을 생성
      if Not FileExists(LogFileName) then  FileClose(FileCreate(LogFileName));

      ErrMsg := '[' +  FormatDateTime('YYYY:MM:DD:HH:NN', Now)   + ']  [' + Format('%-9s',  [Screen.ActiveForm.Name])  +'] ['+  ExtractFileName(label3.Caption) +'] /';

      AssignFile(ErrLogFile, LogFileName);
      Append(ErrLogFile);

      Writeln(ErrLogFile, ErrMsg+' '+inttostr(Row)+' 행 데이타 저장오류 -'+err.message);

      ShowMessage(inttostr(Row)+' 행에서 작업이 중지되었습니다. Data확인요망-'+err.message);
      Database1.Rollback;
      Exit;
   end;
end;
finally

     Query1.Close;

     Query2.Close;

     Query3.Close;

     CloseFile(ErrLogFile);
end;
end;
1  COMMENTS
  • Profile
    권태훈 2006.08.31 19:43
    loop안에 sql문장이 있고 파람을 바꿔가면서 프리페어와 익스큐트를 반복합니다.
    문제 제기하고 싶은것은 sql문장이 전혀 바뀌지 않는다는것과
    프리페어는 sql문장이 바뀌지 않는한 딱 1번만 실행하면 된다는 것입니다.

    그래서 밑의 코드는 바꿔야 합니다.

           Query3.Close;
           Query3.SQL.Clear;
           Query3.SQL.BeginUpdate;
           Query3.SQL.Add('Insert into upTABLE(no, xxx, yyy)');
           Query3.SQL.Add(' values (:no, :xxx, :yyyy)');
           Query3.SQL.EndUpdate;
           Query3.Prepare;

    For Row := 1 to StringGrid1.RowCount-1  do  begin
           Query3.ParamByName('no').asinteger := max+Row;
           Query3.ParamByName('xxx').asstring := UpperCase(Trim(stringgrid1.Cells[1, Row]));
           Query3.ParamByName('yyy').asstring := Trim(stringgrid1.Cells[2, Row]);
           Query3.ExecSQL;
         end;  // For end


    이렇게 하면 sql.. sql도 분명한 랭귀지 입니다. 컴파일 과정과 실행 과정으로 나뉩니다.
    몇번이고 반복하는 문장에서 컴파일을 매번하는것은 꽤 문제가 됩니다.

    두가지를 비교해보면 차이가 많이 나는데 몇몇 db는 속도 측정이 잘 안될수도 있습니다..

    왜냐하면 sql문장이 캐쉬가 되어서 프리페어 할때 실제 컴파일이 안 일어나기도 하기때문입니다.

    이러한 과정으로 본다면 트랜잭션을 시작하고 컴파일, 실행과정을 반복하다가

    트랜잭션을 멈추는데, 트랜잭션 거는 룰에 맞지 않다고 봅니다.

    트랜잭션을 일단의 작업 수행 과정중 멈추고(무슨 이유든간에) 모든 트랜잭션을

    취소하기 위해서 사용하는걸로 알고 있는데, 일부는 수행하고, 일부는 수행하지 않고...

    이건 트랜잭션 사용하는 사상에 반하는걸로 생각되는데요...

    코딩은 항상 FM으로...