📄 fradssqledit.pas
字号:
unit fraDSSQLEdit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
fraSQLEdit, ComCtrls, ExtCtrls, StdCtrls,DB,pFIBDataSet,FIBDatabase,pFIBProps,
FIBDataSet;
{$I FIBPlus.inc}
type
TOnCanUseFields=procedure(const FieldName:string; Allow:boolean) of object;
TfDSSQLEdit = class(TFrame)
pgCtrl: TPageControl;
shSelect: TTabSheet;
SelectSQLEdit: TfSQLEdit;
shGenOptions: TTabSheet;
Panel2: TPanel;
Label3: TLabel;
cmbTables: TComboBox;
btnGetFields: TButton;
btnGenSql: TButton;
btnClearSQLs: TButton;
GroupBox1: TGroupBox;
chFieldOrigin: TCheckBox;
GroupBox2: TGroupBox;
chByPrimary: TCheckBox;
chNonUpdPrKey: TCheckBox;
Label2: TLabel;
cmbParamSymbol: TComboBox;
Panel3: TPanel;
Label1: TLabel;
LstKeyFields: TListBox;
Splitter1: TSplitter;
Panel5: TPanel;
Label4: TLabel;
LstUpdFields: TListBox;
shModifySQLs: TTabSheet;
grSQLKind: TRadioGroup;
ModifySQLEdit: TfSQLEdit;
vShablonDS: TpFIBDataSet;
cmbGenerateKind: TComboBox;
procedure pgCtrlChange(Sender: TObject);
procedure btnGetFieldsClick(Sender: TObject);
procedure grSQLKindClick(Sender: TObject);
procedure btnGenSqlClick(Sender: TObject);
procedure cmbTablesChange(Sender: TObject);
procedure SelectSQLEditSpeedButton1Click(Sender: TObject);
procedure btnClearSQLsClick(Sender: TObject);
procedure SelectSQLEditbtnGenSQLClick(Sender: TObject);
procedure Panel2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
function GetDialect: integer;
procedure viewSQLOnExit(Sender: TObject);
private
FDatabase:TFIBDatabase;
FOnCanUseFields:TOnCanUseFields;
FAllFields :TStrings;
FUpdTableSynonym:string;
FPreparedSelect:string;
procedure FillCmbTables;
procedure ShowModifySQL;
procedure GenerateInsertSQL;
procedure GenerateUpdateSQL;
procedure GenerateDeleteSQL;
procedure GenerateRefreshSQL;
function WhereClause(withSyn:boolean):string;
property Dialect :integer read GetDialect;
public
vDataSet:TFIBDataSet;
FInsertSQL,FUpdateSQL, FDeleteSQL,FRefreshSQL:string;
procedure ReadOptions;
procedure SaveOptions;
public
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
procedure PrepareFrame(Database:TFIBDatabase; const aSelectSQLText,aInsertSQL,aUpdateSQL,
aDeleteSQL,aRefreshSQL:string);
property OnCanUseFields:TOnCanUseFields read FOnCanUseFields write FOnCanUseFields;
end;
const
RegFIBSQLEdOptions='SQLEditor';
implementation
uses
{$IFNDEF NO_REGISTRY} RegUtils, {$ENDIF}
{$IFDEF D6+ } Variants, {$ENDIF}
StrUtil,SqlTxtRtns,pFIBDataInfo;
{$R *.dfm}
{ TfDSSQLEdit }
constructor TfDSSQLEdit.Create(AOwner: TComponent);
begin
inherited;
FAllFields :=TStringList.Create;
cmbGenerateKind.ItemIndex:=0;
end;
destructor TfDSSQLEdit.Destroy;
begin
// SaveOptions;
FAllFields.Free;
inherited;
end;
procedure TfDSSQLEdit.FillCmbTables;
{var
i:integer;}
begin
with cmbTables do
begin
AllTables(SelectSQLEdit.SQLText,Items,False,True);
{ for i:=0 to Pred(Items.Count) do
begin
if Pos('"',Items[i])>0 then
begin
Items[i]:=Copy(Items[i],2,MaxInt);
Items[i]:=Copy(Items[i],1,Pos('"',Items[i])-1);
end
else
Items[i]:=FastUpperCase(ExtractWord(1, Items[i],[' ']));
end;}
if Items.Count>0 then
begin
ItemIndex:=0;
cmbTablesChange(cmbTables)
end;
FPreparedSelect:=SelectSQLEdit.SQLText;
end;
end;
procedure TfDSSQLEdit.pgCtrlChange(Sender: TObject);
begin
if (pgCtrl.ActivePage=shGenOptions) and
((cmbTables.Items.Count=0)or (FPreparedSelect<>SelectSQLEdit.SQLText))then
FillCmbTables
end;
procedure TfDSSQLEdit.btnGetFieldsClick(Sender: TObject);
var
i,j:integer;
tfd:TFieldDef;
NeedField:boolean;
PrimaryKey:string;
tn:string;
begin
with vShablonDS do
begin
Database:=FDatabase;
PrepareOptions:=[];
Options:=[poNoForceIsNull];
Transaction :=SelectSQLEdit.trTransaction;
SelectSQL.Text:=SelectSQLEdit.SQLText;
Prepare;
FAllFields.Clear;
for j:=0 to FieldDefs.Count-1 do
begin
tfd:=FieldDefs[j];
NeedField:=True;
if Assigned(FOnCanUseFields) then
FOnCanUseFields(tfd.Name,NeedField);
if NeedField then
if FUpdTableSynonym<>'' then
begin
tn:=TableAliasForField(tfd.Name);
NeedField:=(FUpdTableSynonym=tn)
end
else
NeedField:=(cmbTables.Text=GetRelationTableName(tfd));
if NeedField then
begin
FAllFields.AddObject(tfd.Name,tfd);
end;
end;
tn:=ExtractWord(1,cmbTables.Text,[' ']);
LstKeyFields.Items.BeginUpdate;
LstUpdFields.Items.BeginUpdate;
try
LstKeyFields.Items.Assign(FAllFields);
LstUpdFields.Items.Assign(FAllFields);
if chByPrimary.Checked then
PrimaryKey:=
';'+DBPrimaryKeyFields( tn,SelectSQLEdit.trTransaction)+';'
else
PrimaryKey:='';
with LstKeyFields,LstKeyFields.Items do
begin
i:=0;
while i<Count do
begin
tfd:=TFieldDef(Objects[i]);
if
(tfd.DataType=ftBlob) or (tfd.DataType=ftMemo) or (tfd.DataType=ftBytes)
then
begin
Delete(i);
Continue;
end;
Selected[i]:=not chByPrimary.Checked or
(Pos(';'+Items[i]+';',PrimaryKey)>0);
Inc(i)
end;
end;
for i:=0 to Pred(LstUpdFields.Items.Count) do
LstUpdFields.Selected[i]:=True;
finally
LstKeyFields.Items.EndUpdate;
LstUpdFields.Items.EndUpdate;
end;
end
end;
procedure TfDSSQLEdit.PrepareFrame(Database: TFIBDatabase; const aSelectSQLText,
aInsertSQL,aUpdateSQL, aDeleteSQL,aRefreshSQL:string
);
begin
with SelectSQLEdit do
begin
FDatabase:=Database;
vEdComponent:=vDataSet.QSelect;
PrepareFrame(Database);
SQLText:=aSelectSQLText;
cmbKindSQL.Enabled:=False;
end;
with ModifySQLEdit do
begin
PrepareFrame(Database);
ModifySQLEdit.viewSQL.OnExit:=viewSQLOnExit;
end;
FInsertSQL:=aInsertSQL;
FUpdateSQL:=aUpdateSQL;
FDeleteSQL:=aDeleteSQL;
FRefreshSQL:=aRefreshSQL;
ModifySQLEdit.btnGenSQL.Visible:=False;
ModifySQLEdit.SpeedButton1.Visible:=False;
ModifySQLEdit.Panel6.Visible:=False;
ModifySQLEdit.Splitter2.Visible:=False;
shGenOptions.TabVisible:= SelectSQLEdit.CanConnect;
ShowModifySQL
end;
procedure TfDSSQLEdit.ShowModifySQL;
begin
with ModifySQLEdit do
case grSQLKind.ItemIndex of
-1,0:
begin
vEdComponent:=vDataSet.QInsert;
SQLText:=FInsertSQL;
end;
1:
begin
vEdComponent:=vDataSet.QUpdate;
SQLText:=FUpdateSQL;
end;
2:
begin
vEdComponent:=vDataSet.QDelete;
SQLText:=FDeleteSQL;
end;
3:
begin
vEdComponent:=vDataSet.QRefresh;
SQLText:=FRefreshSQL;
end;
end;
ModifySQLEdit.ShowEditorStatus
end;
procedure TfDSSQLEdit.grSQLKindClick(Sender: TObject);
begin
ShowModifySQL
end;
procedure TfDSSQLEdit.GenerateInsertSQL;
var j:integer;
pn,rfn,tmpStr,tmpStr1:string;
vpFIBTableInfo:TpFIBTableInfo;
vFi:TpFIBFieldInfo;
tn:string;
begin
with LstUpdFields do
begin
FInsertSQL:='';
tmpStr:='';tmpStr1:='';
ListTableInfo.Clear;
tn:=ExtractWord(1,cmbTables.Text,[' ']);
vpFIBTableInfo:=
ListTableInfo.GetTableInfo(FDatabase, tn ,False);
for j:=0 to Pred(Items.Count) do
if Selected[j] then
begin
rfn:=vShablonDS.GetRelationFieldName(Items.Objects[j]);
vFi:=vpFIBTableInfo.FieldInfo(rfn);
if (vFi=nil) or vFi.IsComputed or vFi.IsTriggered then
Continue;
rfn:=FormatIdentifier(FDatabase.SQLDialect,rfn);
pn :=FormatIdentifier(FDatabase.SQLDialect,Items[j]);
tmpStr :=tmpStr+ForceNewStr+rfn+',';
tmpStr1:=tmpStr1+ForceNewStr+cmbParamSymbol.Text+pn+',';
end;
if (tmpStr<>'') and (tmpStr[Length(tmpStr)]=',') then
SetLength(tmpStr,Length(tmpStr)-1);
if (tmpStr1<>'') and (tmpStr1[Length(tmpStr1)]=',') then
SetLength(tmpStr1,Length(tmpStr1)-1);
FInsertSQL:=
'INSERT INTO '+FormatIdentifier(FDatabase.SQLDialect, tn
)+
'('+tmpStr+#13#10+')'#13#10+'VALUES('+tmpStr1+#13#10+')';
end;
end;
procedure TfDSSQLEdit.btnGenSqlClick(Sender: TObject);
begin
case cmbGenerateKind.ItemIndex of
0:begin
GenerateInsertSQL;
GenerateUpdateSQL;
GenerateDeleteSQL;
GenerateRefreshSQL;
end;
1:GenerateInsertSQL;
2:GenerateUpdateSQL;
3:GenerateDeleteSQL;
4:GenerateRefreshSQL;
end;
ShowModifySQL ;
pgCtrl.ActivePage:=shModifySQLs;
if cmbGenerateKind.ItemIndex>0 then
grSQLKind.ItemIndex:=cmbGenerateKind.ItemIndex-1
else
grSQLKind.ItemIndex:=0;
end;
procedure TfDSSQLEdit.GenerateUpdateSQL;
var j:integer;
pn,rfn,tmpStr:string;
vpFIBTableInfo:TpFIBTableInfo;
vFi:TpFIBFieldInfo;
PrimaryKey:string;
tn:string;
begin
with LstUpdFields do
begin
FUpdateSQL:='';
tmpStr:='';
ListTableInfo.Clear;
tn:=ExtractWord(1,cmbTables.Text,[' ']);
vpFIBTableInfo:=
ListTableInfo.GetTableInfo(FDatabase,tn,False);
for j:=0 to Pred(Items.Count) do
begin
rfn:=vShablonDS.GetRelationFieldName(Items.Objects[j]);
vFi:=vpFIBTableInfo.FieldInfo(rfn);
if (vFi=nil) or vFi.IsComputed or vFi.IsTriggered then
Continue;
rfn:=FormatIdentifier(FDatabase.SQLDialect,rfn);
if (Pos('NEW_',Items[j])=1) or (Pos('OLD_',Items[j])=1)
then
pn :=FormatIdentifier(FDatabase.SQLDialect,'NEW_'+Items[j])
else
pn :=FormatIdentifier(FDatabase.SQLDialect,Items[j]);
if Selected[j] then
begin
if chNonUpdPrKey.Checked then
PrimaryKey:=
';'+ DBPrimaryKeyFields(tn,SelectSQLEdit.trTransaction)+';'
else
PrimaryKey:='';
if Pos(';'+rfn+';',PrimaryKey)=0 then
tmpStr :=tmpStr+ForceNewStr+rfn+' = '+cmbParamSymbol.Text+pn+',';
end;
end;
if tmpStr<>'' then
if tmpStr[Length(tmpStr)]=',' then tmpStr :=Copy(tmpStr,1,Length(tmpStr)-1);
FUpdateSQL:=
'UPDATE '+FormatIdentifier(FDatabase.SQLDialect,tn)+#13#10+'SET '+
tmpStr+#13#10+'WHERE'+#13#10+WhereClause(False)
end;
end;
function TfDSSQLEdit.WhereClause(withSyn: boolean): string;
var i,j:integer;
pn,rfn:string;
begin
with LstKeyFields do
begin
i:=0;
Result:=SpaceStr;
for j:=0 to Pred(Items.Count) do
begin
if Selected[j] then
begin
Inc(i);
if (Items.Objects[j]<>nil) and
(TFieldDef(Items.Objects[j]).DataType=ftBlob) or
(TFieldDef(Items.Objects[j]).DataType=ftMemo) or
(TFieldDef(Items.Objects[j]).DataType=ftBytes)
then
Continue;
rfn:=vShablonDS.GetRelationFieldName(Items.Objects[j]);
rfn:=FormatIdentifier(Dialect,rfn);
pn :=FormatIdentifier(Dialect,'OLD_'+Items[j]);
if withSyn and (FUpdTableSynonym<>'') then
Result:=Result+FUpdTableSynonym+'.'+rfn+' = '+cmbParamSymbol.Text+pn+ForceNewStr
else
Result:=Result+rfn+' = '+cmbParamSymbol.Text+pn+ForceNewStr;
if i<SelCount then Result:=Result+'and '
end;
end;
end;
end;
function TfDSSQLEdit.GetDialect: integer;
begin
Result:=FDatabase.SQLDialect
end;
procedure TfDSSQLEdit.cmbTablesChange(Sender: TObject);
begin
with cmbTables,FDatabase do
if ItemIndex>-1 then
begin
if WordCount(cmbTables.Text,[' '])=1 then
FUpdTableSynonym:=
FormatIdentifier(SQLDialect,AliasForTable(SelectSQLEdit.SQLText,FormatIdentifier(SQLDialect,cmbTables.Text)))
else
FUpdTableSynonym:=
ExtractWord(2, cmbTables.Text,[' '])
;
if FUpdTableSynonym[1]='@' then FUpdTableSynonym:='';
end
else
FUpdTableSynonym:='';
LstKeyFields.Clear; LstUpdFields.Clear;
btnGetFieldsClick(btnGetFields);
end;
procedure TfDSSQLEdit.GenerateDeleteSQL;
begin
with LstKeyFields do
begin
FDeleteSQL:='DELETE FROM'#13#10+SpaceStr+FormatIdentifier(Dialect,ExtractWord(1,cmbTables.Text,[' ']))+#13#10+
'WHERE'#13#10+SpaceStr+WhereClause(False);
end;
end;
procedure TfDSSQLEdit.GenerateRefreshSQL;
var
vParser:TSQLParser;
begin
vParser:= TSQLParser.Create;
try
vParser.SQLText:=SelectSQLEdit.SQLText;
vParser.SQLText:=vParser.SetOrderClause('');
FRefreshSQL:=vParser.AddToMainWhere(WhereClause(True),True);
//FRefreshSQL:=AddToWhereClause(s,WhereClause(True),True)
finally
vParser.Free
end;
end;
procedure TfDSSQLEdit.viewSQLOnExit(Sender: TObject);
begin
case grSQLKind.ItemIndex of
0:FInsertSQL:=ModifySQLEdit.SQLText;
1:FUpdateSQL:=ModifySQLEdit.SQLText;
2:FDeleteSQL:=ModifySQLEdit.SQLText;
3:FRefreshSQL:=ModifySQLEdit.SQLText;
end;
end;
procedure TfDSSQLEdit.ReadOptions;
{$IFNDEF NO_REGISTRY}
var v:Variant;
i:integer;
{$ENDIF}
begin
{$IFNDEF NO_REGISTRY}
v:=
DefReadFromRegistry(['Software',RegFIBRoot,RegFIBSQLEdOptions],
['WhereByPK',
'NotUpdatePK',
'Use?',
'Origins'
]
);
if (VarType(v)<>varBoolean) then
for i:=0 to 3 do
if V[1,i] then
case i of
0: chByPrimary.Checked :=V[0,i];
1: chNonUpdPrKey.Checked :=V[0,i];
2: if V[0,i] then
cmbParamSymbol.ItemIndex:=1
else
cmbParamSymbol.ItemIndex:=0;
3: chFieldOrigin.Checked :=V[0,i];
end;
SelectSQLEdit.ReadOptions;
ModifySQLEdit.ReadOptions;
{$ENDIF}
end;
procedure TfDSSQLEdit.SaveOptions;
begin
{$IFNDEF NO_REGISTRY}
DefWriteToRegistry(['Software',RegFIBRoot,RegFIBSQLEdOptions],
['WhereByPK',
'NotUpdatePK',
'Use?',
'Origins'
],
[chByPrimary.Checked ,
chNonUpdPrKey.Checked,
cmbParamSymbol.ItemIndex=1,
chFieldOrigin.Checked
]
);
SelectSQLEdit.SaveOptions;
{$ENDIF}
end;
procedure TfDSSQLEdit.SelectSQLEditSpeedButton1Click(Sender: TObject);
begin
SelectSQLEdit.SpeedButton1Click(Sender);
ModifySQLEdit.viewSQL.Font:=SelectSQLEdit.viewSQL.Font
end;
procedure TfDSSQLEdit.btnClearSQLsClick(Sender: TObject);
begin
FInsertSQL:='';
FUpdateSQL:='';
FDeleteSQL:='';
FRefreshSQL:='';
ShowModifySQL
end;
procedure TfDSSQLEdit.SelectSQLEditbtnGenSQLClick(Sender: TObject);
begin
SelectSQLEdit.btnGenSQLClick(Sender);
end;
procedure TfDSSQLEdit.Panel2MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
cmbTables.Hint :=cmbTables.Text
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -