안녕하세요,,,
언제나 헤매는 초보입니다.
libmySQL로
Mysql을 연결했는데, 결과를 stringgrid로 보여 주는건 알겠는데요..
인쇄를 하려니깐, 이건 어떻게 할지 갑갑하네요,
검색 결과를 datasource로 넘겨서 dbgrid 등으로 넘기는 경우는
Qreport 같은경우는 디비자료를 쫙 뿌려주는데
해당 데이타set 을 Qreport의 데이타set에 설정해주면
자동으로 레코드들을 뿌려주던데,
dataset 이나 datasource로 연결되도록 해서 dbgrid나 Qreport 로 뿌려주려면
어떻게 해야 하나요?
태스트 해보니 딱 찾던 자료라서 비슷한 문제로 고생하시는 분을 위해 올립니다.
(*
[배포시 필요한 파일]
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.