Q&A

  • mysql 연결했는데요,, dataset 으로 넘기려면 어떻게 해요?
안녕하세요,,,

언제나 헤매는 초보입니다.

libmySQL로
Mysql을 연결했는데, 결과를 stringgrid로 보여 주는건 알겠는데요..

인쇄를 하려니깐, 이건 어떻게 할지 갑갑하네요,


검색 결과를 datasource로 넘겨서 dbgrid 등으로 넘기는 경우는
Qreport 같은경우는 디비자료를 쫙 뿌려주는데
해당 데이타set 을 Qreport의 데이타set에 설정해주면
자동으로 레코드들을 뿌려주던데,

dataset 이나 datasource로 연결되도록 해서 dbgrid나  Qreport 로 뿌려주려면
어떻게 해야 하나요?

1  COMMENTS
  • Profile
    이충효 2004.06.23 19:09
    찾다보니 이런 자료가 있더군요,,
    태스트 해보니 딱 찾던 자료라서 비슷한 문제로 고생하시는 분을 위해 올립니다.

    (*
    [배포시 필요한 파일]
    dbclient.dll
    midas.dll
    libmySQL.dll

    _libmySQL.pas 와 libmySQL.dll 은 이곳 강좌란을 찾아보면 있을겁니다.
    *)

    unit MysqlToCDS;

    interface
    uses Classes, Messages, Sysutils, windows, Controls, Forms, _libmySQL, Db, DBClient;

    type

    TFieldBuffer = record
       _TableName   : String;
       _ResultField : String;
    end;

    TMysqlToCDS = class
    private
       MysqlRec   : Mysql;
       pResults   : Pmysql_res;
       FConnected : Boolean;

    public

       constructor Create;
       destructor Destroy; override;

       //database
       function   Connect(host, user, passwd, DBname: string): Boolean;
       procedure  DisConnect;
       function   Exec_Qry(ASql : string): Boolean;
       function   DataSet_Qry(ASql : string; ADataSet : TClientDataSet): Boolean;

       //backup restore
       procedure  Backup(APath : string);
       procedure  Restore(APath : string);

       property   Connected : Boolean read FConnected;
    end;


    implementation

    const Query_Err = '쿼리실행중 오류가 발생했습니다.' + #13#10 + '%d : %s ';

    function MessageTouser(sMsg : string; iType : Integer): Integer;
    var hWnd : Integer;
    begin
    if Screen.ActiveForm <> nil then hWnd := Screen.ActiveForm.Handle
                                 else hWnd := Application.Handle;

    case iType of
       1 : Result := Windows.MessageBox(hWnd, PChar(sMsg), PChar(Application.Title), MB_OK + MB_ICONINFORMATION); //정보
       2 : Result := Windows.MessageBox(hWnd, PChar(sMsg), PChar(Application.Title), MB_OK + MB_ICONWARNING);     //경고
       3 : Result := Windows.MessageBox(hWnd, PChar(sMsg), PChar(Application.Title), MB_OK + MB_ICONERROR);       //오류
       4 : Result := Windows.MessageBox(hWnd, PChar(sMsg), PChar(Application.Title), MB_YESNO + MB_ICONQUESTION); //질문(Yes, No)
       5 : Result := Windows.MessageBox(hWnd, PChar(sMsg), PChar(Application.Title), MB_YESNOCANCEL + MB_ICONQUESTION);  //질문(Yes, No, Cancle)
       else Result := -1;
    end;

    end;

    constructor TMysqlToCDS.Create;
    begin
    inherited Create;
    fConnected := False;
    end;

    destructor TMysqlToCDS.Destroy;
    begin
    DisConnect;
    inherited Destroy;
    end;


    function TMysqlToCDS.Connect(host, user, passwd, DBname: string): Boolean;
    begin

    Screen.Cursor := crSQLWait;  

    Result := False;

    if not fConnected then begin
       Mysql_connect(@MysqlRec, PChar(host), PChar(user), PChar(passwd));
       Result := MysqlRec._net.last_errno = 0;

       if Result then begin
         Result := Mysql_select_db(@MysqlRec, PChar(DBname)) = 0;
         if Result then fConnected := True
         else begin
           mysql_close(@MysqlRec);
           MessageTouser('데이타베이스명이 올바르지 않습니다.', 2);
         end;

       end else MessageTouser('서버에 연결할 수 없습니다. 다음사항을 확인하십시오.' +#13#10#13#10 +
                              ' 1. 컴퓨터가 네트워크에 연결되어있는가?' + #13#10 +
                              ' 2. 데이타베이스(mySQL)가 실행중인가?' + #13#10 +
                              ' 3. 사용자 ID 또는 패스워드가 올바른가?', 2);       //오류
    end;

    Screen.Cursor := crDefault;   //0
    end;

    procedure TMysqlToCDS.DisConnect;
    begin
    Screen.Cursor := crSQLWait;
    if fConnected then mysql_close(@mysqlrec);
    Screen.Cursor := crDefault;
    end;

    function   TMysqlToCDS.Exec_Qry(ASql : string): Boolean;
    begin
    if not FConnected then Exit;

    Screen.Cursor := crSQLWait;
    try
        Result := mysql_query(@MysqlRec, PChar(ASql)) = 0;
        pResults := Mysql_store_result(@MysqlRec);
        if not Result then MessageTouser(Format(Query_Err, [MysqlRec._net.last_errno, StrPas(@mysqlrec._net.last_error[1])]), 3);
    finally
        mysql_free_result(presults);
    end;
    Screen.Cursor := crDefault;
    end;

    function   TMysqlToCDS.DataSet_Qry(ASql : string; ADataSet : TClientDataSet): Boolean;
    var pRow : pmysql_row;
       Row  : mysql_row;
       pfield : pmysql_field;
       I, J : Integer;
    begin
    if not FConnected then Exit;

    Screen.Cursor := crSQLWait;

    try
        Result := mysql_query(@MysqlRec, PChar(ASql)) = 0;
        pResults := Mysql_store_result(@MysqlRec);

        if Result then begin

          ADataSet.Close;
          ADataSet.FieldDefs.Clear;


          for I := 0 to pResults^.field_count - 1 do begin
             pfield := mysql_fetch_field(pResults);
             case pfield^._type of
               field_type_decimal     : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, pfield^.length);
               field_type_longlong    : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, pfield^.length);
               field_type_null        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, pfield^.length);
               field_type_enum        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, pfield^.length);
               field_type_set         : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, pfield^.length);

               field_type_tiny        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftSmallint, 0);   //(부호 있는 정수 -128 ∼ 127, 부호 없는 정수 0 ∼ 255, 1 Byte)
               field_type_short       : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftSmallint, 0);   //ftWord (부호 있는 정수 -32768 ∼ 32767, 부호 없는 정수 0 ∼ 65535, 2 Byte)
               field_type_long        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftInteger, 0);    //(부호 있는 정수 -2147483648 ∼ 2147483647, 부호 없는 정수 0 ∼ 4294967295, 4 Byte)
               field_type_int24       : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, 0);    //(부호 있는 정수 -9223372036854775808 ∼ -9223372036854775807, 부호 없는 정수 0 ∼ 18446744073709551615, 8 Byte)

               field_type_float       : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftFloat, 0);      //(단일 정밀도를 가진 부동 소수점, -3.402823466E+38 ∼ 3.402823466E+38)
               field_type_double      : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftFloat, 0);      //(2 배 정밀도를 가진 부동 소수점, -1.79769313486231517E+308 ∼ 1.79769313486231517E+308)

               field_type_date        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftDate, 0);       //
               field_type_time        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftTime, 0);       //
               field_type_datetime    : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftDateTime, 0);   //
               field_type_timestamp   : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftUnknown, 0);    //

               field_type_tiny_blob   : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftBlob, pfield^.length);       //(255개의 문자를 저장)
               field_type_blob        : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftBlob, pfield^.length);       //(63535개의 문자를 저장)
               field_type_medium_blob : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftBlob, pfield^.length);       //(16777215개의 문자를 저장)
               field_type_long_blob   : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftBlob, pfield^.length);       //(4294967295(4Giga)개의 문자를 저장)

               field_type_string      : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftString, pfield^.length);     //(고정길이 문자열을 표현하는 유형, M = 1 ∼ 255)
               field_type_var_string  : ADataSet.FieldDefs.Add(StrPas(pfield^.name), ftString, pfield^.length);     //(가변길이 문자열을 표현하는 유형, M = 1 ∼ 255)
             end;
          end;

          ADataSet.CreateDataSet;
          for I := 0 to pResults^.row_count - 1 do begin //레코드
            pRow:= mysql_fetch_row(pResults);
            Row:= pRow^;
            ADataSet.Append;
            for J := 0 to pResults^.field_count -1 do ADataSet.Fields[J].AsString := StrPas(Row[J]);
            ADataSet.Post;
          end;

        end else MessageTouser(Format(Query_Err, [MysqlRec._net.last_errno, StrPas(@mysqlrec._net.last_error[1])]), 3);  //오류

    finally
        mysql_free_result(pResults);
    end;

    Screen.Cursor := crDefault;

    end;

    procedure TMysqlToCDS.Backup(APath : string);
    var tmpDataSet : TClientDataSet;
       tmpTables : TStringList;
       pRow : pmysql_row;
       Row  : mysql_row;
       I : Integer;
    begin//데이타베이스에서 모든 테이블을 가져다 로컬에 저장한다.

    if not FConnected then Exit;

    Screen.Cursor := crSQLWait;

    tmpTables := TStringList.Create;

    try
       if mysql_query(@MysqlRec, PChar('show tables')) = 0 then begin
         pResults := Mysql_store_result(@MysqlRec);
         for I := 0 to pResults^.row_count - 1 do begin //레코드
           pRow:= mysql_fetch_row(pResults);
           Row:= pRow^;
           tmpTables.Add(StrPas(Row[0]));
         end;
       end;
    finally
        mysql_free_result(pResults);
    end;

    tmpDataSet := TClientDataSet.Create(nil);
    for I := 0 to tmpTables.Count - 1 do begin
       tmpDataSet.FileName := APath + tmpTables[I];
       DataSet_Qry('select * from ' + tmpTables[I], tmpDataSet);
       tmpDataSet.SaveToFile;
    end;

    tmpDataSet.Free;
    tmpTables.Free;
    Screen.Cursor := crDefault;

    end;

    procedure TMysqlToCDS.Restore(APath : string);
    var  SR : TSearchRec;
        FindResult : Integer;
        tmpDataSet : TClientDataSet;
        I : Integer;
        tmpS : string;
    begin

    if not FConnected then Exit;

    Screen.Cursor := crSQLWait;
    tmpDataSet := TClientDataSet.Create(nil);

    FindResult := Sysutils.FindFirst(APath +'*', faAnyFile, SR);
    while FindResult = 0 do  begin

       if (SR.Name <> '.') and (SR.Name <> '..') then begin
         Exec_Qry('delete from ' + SR.Name);
         tmpDataSet.LoadFromFile(APath + SR.Name);

         while not tmpDataSet.Eof do begin
           tmpS := 'insert into ' + SR.Name + ' Values(';

           for I := 0 to tmpDataSet.FieldCount - 1 do begin
             case tmpDataSet.FieldDefs[I].DataType of
               ftString, ftBlob, ftUnknown : tmpS := tmpS + QuotedStr(tmpDataSet.Fields[I].AsString);
               else tmpS := tmpS + tmpDataSet.Fields[I].AsString; //ftAutoInc, ftSmallint, ftInteger, ftFloat, ftDate, ftTime, ftDateTime
             end;
             if I < tmpDataSet.FieldCount - 1 then tmpS := tmpS + ',' else tmpS := tmpS + ')';
           end;

           Exec_Qry(tmpS);
           tmpDataSet.Next;
         end;

       end;
       FindResult := Sysutils.FindNext(SR);
    end;
    Sysutils.FindClose(SR);

    tmpDataSet.Free;
    Screen.Cursor := crDefault;
    end;

    end.