단위 BdeclientDataset;
인터페이스
Windows, Sysutils, 변형, 클래스, DB, DBCommon, Midas를 사용합니다.
sqltimst, dbclient, dblocal, 제공자, dbtables;
유형
{tbdequery}
tbdequery = 클래스 (tquery)
사적인
fkeyfields : 문자열;
보호
함수 psgetDefaultorder : TindexDef; 보수;
끝;
{tbdeclientDataset}
tbdeclientDataset = class (tcustomCachedDataset)
사적인
fcommandText : 문자열;
fcurrentCommand : 문자열;
fdataset : tbdequery;
fdatabase : tdatabase;
flocalparams : Tparams;
fstreamedActive : 부울;
절차 CheckmasterSourceactive (Mastersource : Tdatasource);
절차 setDetailSactive (값 : 부울);
함수 getConnection : tdatabase;
함수 getDataset : tdataset;
기능 getmastersource : tdatasource;
함수 getmasterFields : String;
절차 setConnection (값 : tdatabase);
절차 setDatasource (값 : tdatasource);
절차 setlocalparams;
절차 setMasterFields (const value : String);
절차 setparamsfromsql (const 값 : String);
절차 setsql (const value : String);
보호
함수 getCommandText : String; 보수;
절차로드; 보수;
프로 시저 알림 (ACOMPONTER : TCOMPONTE; OUNTURE : TOPERATION); 보수;
절차 setActive (값 : 부울); 보수;
절차 setCommandText (값 : 문자열); 보수;
공공의
생성자 생성 (aowner : tcomponent); 보수;
소멸자 파괴; 보수;
프로 시저 클로 쿠 커서 (출처 : tcustomclientDataset; 재설정 : 부울;
hepeSettings : boolean = false); 보수;
절차 getfieldNames (목록 : tstrings); 보수;
함수 getquotechar : 문자열;
속성 데이터 세트 : tdataset read getDataset;
게시
속성 활성;
Property CommandText : String read getCommandText write setCommandText;
속성 DBConnection : tdatabase read getConnection write setConnection;
Property Masterfields 읽기 GetMasterFields는 SetMasterFields를 작성합니다.
Property MasterSource : Tdatasource 읽기 GetMasterSource 쓰기 SetDatasource;
끝;
절차 레지스터;
구현
Bdeconst, MidConst를 사용합니다.
유형
{tbdecdsparams}
tbdecdsparams = class (tparams)
사적인
ffieldname : tstrings;
보호
프로 시저 PARSESELECT (SQL : String);
공공의
생성자 생성 (소유자 : tpersistent);
소멸자 파괴; 보수;
끝;
생성자 tbdecdsparams.create (소유자 : tpersistent);
시작하다
상속;
ffieldname : = tstringlist.create;
끝;
소멸자 tbdecdsparams.destroy;
시작하다
FreeAndnil (ffieldname);
상속;
끝;
절차 tbdecdsparams.parseselect (sql : string);
Const
sselect = 'select';
var
fwherefound : 부울;
시작 : pchar;
fname, 값 : 문자열;
sqltoken, cursection, lasttoken : tsqltoken;
매개 변수 : 정수;
시작하다
pos ( '' + sselect + ''인 경우 소문자 (문자열 (pchar (sql) +8)))> 1 후에 종료; // 하위 쿼리를 구문 분석 할 수 없습니다
시작 : = pchar (parsesql (pchar (sql), true);
Cursection : = Stunknown;
마지막으로 : = Stunknown;
fwherefound : = 거짓;
매개 변수 : = 0;
반복하다
반복하다
sqltoken : = nextsqltoken (start, fname, cursection);
[stwhere]에서 sqltoken 인 경우
시작하다
fwherefound : = 참;
마지막으로 : = stwhere;
[sttablename]에서 sqltoken이면 다른 끝을 종료하십시오
시작하다
{소유자 자격을 갖춘 테이블 이름 확인}
시작하면^ = '.' 그 다음에
nextsqltoken (start, fname, cursection);
다른 끝
if (sqltoken = stvalue) 및 (lasttoken = stwhere)
sqltoken : = stfieldname;
sqlsections에서 sqltoken이면 Cursection : = sqltoken;
[stfieldname, stend]에서 sqltoken까지;
fwherefound이고 (sqltoken in [stfieldname])
반복하다
sqltoken : = nextsqltoken (시작, 값, 커서);
sqlsections에서 sqltoken이면 Cursection : = sqltoken;
[stend, stvalue, stisnull, stisnotnull, stfieldname]에서 sqltoken이 될 때까지;
value = '?' 그 다음에
시작하다
ffieldname.add (fname);
INC (Params);
끝;
(params = count) 또는 ([stend]의 sqltoken)까지;
끝;
{tbdequery}
함수 tbdequery.psgetDefaultorder : TindexDef;
시작하다
fkeyfields = ''라면
결과 : = 상속 된 psgetDefaultorder
또 다른
시작 // 세부 테이블 기본 순서를 시작합니다
결과 : = TindexDef.create (nil);
result.options : = [ixunique]; // 키 필드는 독특합니다
result.name : = StringReplace (fkeyfields, ';', '_', [rfreplaceall]);
result.fields : = fkeyfields;
끝;
끝;
{tbdeclientDataset}
생성자 TBDECLIENTDATASET.CREATE (AOWNER : TCOMPONTE);
시작하다
상속 된 Create (Aowner);
fdataset : = tbdequery.create (nil);
fdataset.name : = self.name + 'dataSet1';
Provider.dataset : = fdataset;
sqldbtype : = typebde;
flocalparams : = tparams.create;
끝;
소멸자 tbdeclientDataset.destroy;
시작하다
FreeAndnil (flocalparams);
fdataset.close;
FreeAndnil (fdataset);
상속 된 파괴;
끝;
절차 tbdeclientDataset.getFieldNames (list : tstrings);
var
개방 : 부울;
시작하다
열린 : = (active = false);
노력하다
열면
열려 있는;
상속 된 getfieldnames (list);
마지막으로
열면 닫으십시오.
끝;
끝;
함수 tbdeclientDataset.getCommandText : String;
시작하다
결과 : = fcommandText;
끝;
함수 TBDECLIENTDATASET.GETDATASET : TDATASET;
시작하다
결과 : = tdataset으로 fdataset;
끝;
절차 tbdeclientDataset.checkmasterSourceactive (Mastersource : tdatasource);
시작하다
할당 된 (MasterSource) 및 할당 된 경우 (Mastersource.dataset)
MasterSource.dataset.active가 아닌 경우
DatabaseError (SmasterNotopen);
끝;
절차 tbdeclientDataset.setparamsfromsql (const value : String);
var
데이터 세트 : tquery;
tablemename, tempquery, q : 문자열;
목록 : tbdecdsparams;
I : 정수;
필드 : Tfield;
시작하다
tableName : = getTablenamefromsql (value);
TableName <> ''인 경우
시작하다
온도 : = 값;
목록 : = tbdecdsparams.create (self);
노력하다
list.parseselect (tempquery);
List.AssignValues (Params);
i : = 0 to list.count -1 do
목록 [i] .paramtype : = ptinput;
데이터 세트 : = tquery.create (nil);
노력하다
DataSet.databaseName : = fdataset.databaseName;
Q : = getquotechar;
DataSet.sql.add ( 'select * from' + q + tablemename + q + '여기서 0 = 1'); {현지화하지 마십시오}
노력하다
dataset.open;
i : = 0 to list.count -1 do
시작하다
if list.ffieldname.count> i that
시작하다
노력하다
필드 : = dataset.fieldByName (list.ffieldName [i]);
제외하고
필드 : = nil;
끝;
다른 끝
필드 : = nil;
할당 된 경우 (필드)
시작하다
field.datatype <> ftstring이면
[i] .datatype : = field.datatype를 나열하십시오
그렇지 않으면 tstringfield (필드) .fixedchar
[i] .datatype : = ftfixedchar
또 다른
목록 [i] .datatype : = ftstring;
끝;
끝;
제외하고
// 모든 예외를 무시합니다
끝;
마지막으로
dataset.free;
끝;
마지막으로
list.count> 0 인 경우
params.assign (목록);
list.free;
끝;
끝;
끝;
절차 tbdeclientDataset.setSql (const value : String);
시작하다
할당 된 경우 (Provider.Dataset)
시작하다
tquery (provider.dataset) .sql.clear;
value <> ''라면
tquery (provider.dataset) .sql.add (value);
상속 된 setCommandText (값);
다른 끝
DatabaseError (snodataprovider);
끝;
절차 tbdeclientDataset.loaded;
시작하다
상속 된로드;
그렇다면 fstreamedActive
시작하다
setActive (true);
fstreamedActive : = false;
끝;
끝;
함수 TBDECLIENTDATASET.GETMASTERFIELDS : String;
시작하다
결과 : = 상속 된 마스터 필드;
끝;
절차 tbdeclientDataset.setmasterFields (const value : String);
시작하다
상속 된 마스터 필드 : = 값;
value <> ''라면
indexfieldNames : = value;
fdataset.fkeyfields : = '';
끝;
절차 tbdeclientDataset.setCommandText (값 : 문자열);
시작하다
상속 된 setCommandText (값);
fcommandText : = value;
그렇지 않은 경우 (ComponentState에서 CSLODING)
시작하다
fdataset.fkeyfields : = '';
indexfieldNames : = '';
마스터 필드 : = '';
indexname : = '';
indexdefs.clear;
params.clear;
if (componentState에서 csdesigning) 및 (value <> '')
setparamsfromsql (값);
끝;
끝;
함수 tbdeclientDataset.getConnection : tdatabase;
시작하다
결과 : = fdatabase;
끝;
절차 tbdeclientDataSet.SetConnection (값 : tdatabase);
시작하다
값 = fdatabase 인 경우 종료;
검사 활동;
(값) 할당 된 경우
시작하다
그렇지 않은 경우 (ComponentState에서 CSLODING) 및 (Value.DatabasEname = '')
DatabaseError (sdatabasenammissing);
fdataset.databaseName : = value.databaseName;
다른 끝
fdataset.databaseName : = '';
fdatabase : = 값;
끝;
함수 TBDECLIENTDATASET.GETQUOTECHAR : String;
시작하다
결과 : = '';
할당 된 경우 (fdataset)
결과 : = fdataset.psgetquotechar;
끝;
절차 tbdeclientDataset.clonecursor (출처 : tcustomclientDataset; Reset : Boolean;
hepeSettings : boolean = false);
시작하다
그렇지 않은 경우 (소스는 tbdeclientDataset입니다) 그런 다음
DatabaseError (sinvalidclone);
Provider.dataset : = tbdeclientDataset (source) .provider.dataset;
dbConnection : = tbdeclientDataset (source) .dbConnection;
CommandText : = TBDECLIENDDATASET (source) .CommandText;
상속 된 Clonecursor (소스, 재설정, 유지);
끝;
절차 tbdeclientDataSet. notification (Acomponent : tcomponent; Operation : Toperation);
시작하다
상속 알림 (Acomponent, Operation);
If Operation = Opremove라면
acomponent = fdatabase라면
시작하다
fdatabase : = nil;
setActive (false);
끝;
끝;
절차 tbdeclientDataset.setlocalparams;
절차 CreateParamsFrommasterFields (Create : Boolean);
var
I : 정수;
목록 : tstrings;
시작하다
목록 : = tstringlist.create;
노력하다
그런 다음 생성하는 경우
flocalparams.clear;
fdataset.fkeyfields : = 마스터 필드;
list.commatext : = 마스터 필드;
i : = 0 to list.count -1 do
시작하다
그런 다음 생성하는 경우
flocalparams.createparam (ftunknown, mas
ptinput);
flocalparams [i] .assignfield (Mas
끝;
마지막으로
list.free;
끝;
끝;
시작하다
if (masterfields <> '') 및 할당 (Mas
시작하다
CreateParamsfrommasterFields (True);
fcurrentcommand : = addparamsqlfordetail (flocalparams, commandText, true, getquotechar);
끝;
끝;
절차 tbdeclientDataset.SetDatasource (값 : tdatasource);
시작하다
상속 된 마스터 소스 : = 값;
(값) 할당 된 경우
시작하다
packetrecords = -1 인 경우 packetrecords : = 0;
다른 끝
시작하다
packetrecords = 0이면 packetrecords : = -1;
끝;
끝;
함수 tbdeclientDataset.getmasterSource : tdatasource;
시작하다
결과 : = 상속 된 마스터 소스;
끝;
절차 tbdeclientDataset.SetDetailSactive (값 : 부울);
var
DetaIllist : tlist;
I : 정수;
시작하다
DetaIllist : = tlist.create;
노력하다
getDetailDatasets (DetaIllist);
i : = 0에서 detaillist.count -1 do
TDATASET (DetaIllist [i])가 tbdeclientDataset이면
tbdeclientDataset (tdataset (detaillist [i])). Active : = value;
마지막으로
Detaillist.free;
끝;
끝;
절차 tbdeclientDataset.setActive (값 : 부울);
시작하다
그렇다면 가치가 있다면
시작하다
ComponentState에서 CSLOAD가있는 경우
시작하다
fstreamedActive : = true;
출구;
끝;
Masterfields <> ''라면
시작하다
그렇지 않은 경우 (ComponentState에서 CSLODING)
CheckmasterSourceactive (Mastersource);
setlocalparams;
setsql (fcurrentcommand);
매개 변수 : = flocalparams;
페치 파람;
다른 끝
시작하다
setsql (fcommandtext);
params.count> 0 인 경우
시작하다
fdataset.params : = Params;
페치 파람;
끝;
끝;
끝;
값과 (fdataset.objectView <> ObjectView)
fdataset.objectView : = ObjectView;
상속 된 setActive (값);
setDetailSactive (값);
끝;
절차 레지스터;
시작하다
registercomponents ( 'bde', [tbdeclientDataset]);
끝;
끝.
// dblocalb.pas 改装而成, 可存为任意文件名, 当然扩展名是 pas
// 然后安装此控件即可