Q&A

  • 조회중 프로그램이 먹통
StringGrid에 오라클DB를 조회하는데 Open명령 후

덩치가 큰 Query를 하게되면 엄청나게 오랜시간이 걸리고

조회가 완료될 때까지 다른작업은 하나도 할 수 가 없습니다.

SQL_PLUS와 같이 User Cancel을 일으킬 수 있는 방법이 없는지요

(예 : Visual C++에서는 Ctl+C를 누르면 DB의 연결을 해제하면서 조회가

중단되는데 델파이도 이와같은 방법이 있는지요)

많은 조언 부탁드립니다.



2  COMMENTS
  • Profile
    류미희 1999.07.31 02:43
    다시 류미희입니다.

    > StringGrid에 오라클DB를 조회하는데 Open명령 후

    > 덩치가 큰 Query를 하게되면 엄청나게 오랜시간이 걸리고

    > 조회가 완료될 때까지 다른작업은 하나도 할 수 가 없습니다.

    > SQL_PLUS와 같이 User Cancel을 일으킬 수 있는 방법이 없는지요

    > (예 : Visual C++에서는 Ctl+C를 누르면 DB의 연결을 해제하면서 조회가

    > 중단되는데 델파이도 이와같은 방법이 있는지요)

    > 많은 조언 부탁드립니다.

    > DBGRID와 DataSet을 사용하지 않고 TQuery와 StringGrid를 사용한 상태

    >



  • Profile
    김영대 1999.07.30 05:16
    류미희 께서 말씀하시기를...

    > StringGrid에 오라클DB를 조회하는데 Open명령 후

    > 덩치가 큰 Query를 하게되면 엄청나게 오랜시간이 걸리고

    > 조회가 완료될 때까지 다른작업은 하나도 할 수 가 없습니다.

    > SQL_PLUS와 같이 User Cancel을 일으킬 수 있는 방법이 없는지요

    > (예 : Visual C++에서는 Ctl+C를 누르면 DB의 연결을 해제하면서 조회가

    > 중단되는데 델파이도 이와같은 방법이 있는지요)

    > 많은 조언 부탁드립니다.

    >



    // 아래 예제는 INPRISE TI 에 있는 내용입니다

    // 예제만 조금 바꾸었습니다



    unit Unit1;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    DBTables, Db, StdCtrls, Grids, DBGrids, ComCtrls;



    type

    TForm1 = class(TForm)

    Database1: TDatabase;

    Query1: TQuery;

    Query2: TQuery;

    Query3: TQuery;

    DataSource1: TDataSource;

    DataSource2: TDataSource;

    DataSource3: TDataSource;

    DBGrid1: TDBGrid;

    DBGrid2: TDBGrid;

    DBGrid3: TDBGrid;

    Button1: TButton;

    ProgressBar1: TProgressBar;

    Session1: TSession;

    procedure Button1Click(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    TQueryThread = class(TThread)

    private

    FDatabase: TDataBase;

    FQuery: TQuery;

    FDatasource: TDatasource;

    FQueryException: Exception;

    procedure ConnectDataSource;

    procedure ShowQryError;

    protected

    procedure Execute; override;

    public

    constructor Create(Session: TSession; DataBase:

    TDatabase; Query: TQuery; DataSource: TDataSource); virtual;

    end;



    var

    Form1: TForm1;



    implementation



    constructor TQueryThread.Create(Session: TSession; DataBase:

    TDatabase; Query: TQuery; Datasource: TDataSource);

    begin

    // thread object의 instance를 생성한다

    // Create의 파라미터가 False이면 thread를 생성한후 즉시 Execute를 호출하여 실행한다

    // " True이면 Resume을 호출하기 전까지 실행하지 않는다(suspended)

    inherited Create(True);



    FDatabase := DataBase;

    FQuery := Query;

    FDataSource := Datasource;



    // thread의 실행이 종료하면 자동으로 free되게 설정

    FreeOnTerminate := True;



    // 실행이 일시 중지된(suspended) thread를 실행한다

    Resume;

    end;



    procedure TQueryThread.Execute;

    begin

    try

    // Query를 open하고 DataSource를 연결한다

    FQuery.Open;



    // thread간의 충돌을 피하여 ConnectDataSource 를 호촐한다

    Synchronize(ConnectDataSource);

    except

    // Handle the exception

    FQueryException := ExceptObject as Exception;

    // thread간의 충돌을 피하여 ShowQryError 를 호촐한다

    Synchronize(ShowQryError);

    end;

    end;



    procedure TQueryThread.ConnectDataSource;

    begin

    // DataSource를 연결한다

    FDataSource.DataSet := FQuery;

    end;



    procedure TQueryThread.ShowQryError;

    begin

    // Handle the exception

    Application.ShowException(FQueryException);

    end;



    procedure RunBackgroundQuery(Session: TSession; DataBase: TDataBase;

    Query: TQuery; DataSource: TDataSource);

    begin

    {thread instance 생성}

    TQueryThread.Create(Session, Database, Query, DataSource);

    end;



    {$R *.DFM}



    procedure TForm1.Button1Click(Sender: TObject);

    var

    i: Integer;

    begin

    {병렬처리: 3개의 Query를 thread를 사용하여 open한다}

    RunBackgroundQuery(Session1, DataBase1, Query1, Datasource1);

    RunBackgroundQuery(Session1, DataBase1, Query2, Datasource2);

    RunBackgroundQuery(Session1, DataBase1, Query3, Datasource3);



    (* 순차처리: 일반적인 Query Open

    Query1.Open;

    Query2.Open;

    Query3.Open;

    *)



    for i := 1 to 100 do

    ProgressBar1.Position := i;

    end;



    end.