ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/design/IBSystemTables.pas
Revision: 19
Committed: Mon Jul 7 13:00:15 2014 UTC (9 years, 9 months ago) by tony
Content type: text/x-pascal
File size: 25263 byte(s)
Log Message:
Committing updates for Release R1-1-0

File Contents

# Content
1 (*
2 * IBX For Lazarus (Firebird Express)
3 *
4 * The contents of this file are subject to the Initial Developer's
5 * Public License Version 1.0 (the "License"); you may not use this
6 * file except in compliance with the License. You may obtain a copy
7 * of the License here:
8 *
9 * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10 *
11 * Software distributed under the License is distributed on an "AS
12 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 * implied. See the License for the specific language governing rights
14 * and limitations under the License.
15 *
16 * The Initial Developer of the Original Code is Tony Whyman.
17 *
18 * The Original Code is (C) 2011 Tony Whyman, MWA Software
19 * (http://www.mwasoftware.co.uk).
20 *
21 * All Rights Reserved.
22 *
23 * Contributor(s): ______________________________________.
24 *
25 *)
26
27 unit IBSystemTables;
28
29 {$mode objfpc}{$H+}
30
31 interface
32
33 uses
34 Classes, SysUtils, IBSQL, IBDatabase, StdCtrls;
35
36 type
37
38 { TIBSystemTables }
39
40 TIBSystemTables = class
41 private
42 FGetTableNames: TIBSQL;
43 FGetFieldNames: TIBSQL;
44 FGetPrimaryKeys: TIBSQL;
45 FTestSQL: TIBSQL;
46 FTableAndColumnSQL: TIBSQL;
47 FGetGeneratorsSQL: TIBSQL;
48 FGetProcedures: TIBSQL;
49 FGetProcedureParams: TIBSQL;
50 FGetProcedureInfo: TIBSQL;
51 function GetSQLType(SQLType: TIBSQLTypes): string;
52 procedure AddWhereClause(TableName: string; QuotedStrings: boolean; SQL: TStrings;
53 UseOldValues: boolean = false);
54 procedure GetProcParams(ProcName: string; ParamList: TStrings; InputParams: boolean); overload;
55 function GetWord(S: string; WordNo: integer): string;
56 public
57 constructor Create;
58 destructor Destroy; override;
59 procedure SelectDatabase(Database: TIBDatabase; Transaction: TIBTransaction);
60 procedure GetTableNames(TableNames: TStrings);
61 procedure GetFieldNames(TableName: string; FieldNames: TStrings;
62 IncludePrimaryKeys:boolean=true; IncludeReadOnlyFields: boolean = true);
63 procedure GetPrimaryKeys(TableName: string; PrimaryKeys: TStrings);
64 procedure GetTableAndColumns(SelectSQL: string; var FirstTableName: string;
65 Columns: TStrings);
66 procedure GetProcedureNames(ProcNames: TStrings; WithOutputParams: boolean=false);
67 procedure GetProcParams(ProcName: string; var ExecuteOnly: boolean;
68 InputParams, OutputParams: TStrings); overload;
69 procedure GetGenerators(GeneratorNames: TStrings);
70 procedure GenerateSelectSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
71 procedure GenerateRefreshSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
72 procedure GenerateInsertSQL(TableName: string; QuotedStrings: boolean; FieldNames, SQL: TStrings);
73 procedure GenerateModifySQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
74 procedure GenerateDeleteSQL(TableName: string; QuotedStrings: boolean; SQL: TStrings);
75 procedure GenerateExecuteSQL(ProcName: string; QuotedStrings: boolean; ExecuteOnly: boolean;
76 InputParams, OutputParams, ExecuteSQL: TStrings);
77 function GetStatementType(SQL: string; var IsStoredProcedure: boolean): TIBSQLTypes;
78 function GetFieldNames(FieldList: TListBox): TStrings;
79 procedure TestSQL(SQL: string; GenerateParamNames: boolean = false);
80 end;
81
82 implementation
83
84 uses IB, Dialogs, IBUtils;
85
86 { TIBSystemTables }
87
88 const
89 sqlGETTABLES = 'Select Trim(RDB$RELATION_NAME) as TableName From RDB$RELATIONS ' +
90 'Where RDB$SYSTEM_FLAG = 0 ' +
91 'Order by 1';
92
93 sqlGETALLFIELDS = 'Select Trim(RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS ' +
94 'Where RDB$RELATION_NAME = :TableName ' +
95 'order by RDB$FIELD_POSITION asc ';
96
97 sqlGETFIELDS = 'Select Trim(RF.RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
98 'JOIN RDB$FIELDS B On B.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE '+
99 'Where RF.RDB$RELATION_NAME = :TableName and B.RDB$COMPUTED_SOURCE is NULL ' +
100 'order by RF.RDB$FIELD_POSITION asc ';
101
102 sqlGETPRIMARYKEYS = 'Select Trim(S.RDB$FIELD_NAME) as ColumnName From '+
103 '(Select RDB$INDEX_NAME,RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS Order by RDB$FIELD_POSITION ASC) S ' +
104 'JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME ' +
105 'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and RDB$RELATION_NAME = :TableName';
106
107 sqlUPDATEFIELDS = 'Select Trim(RF.RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
108 'JOIN RDB$FIELDS B On B.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE '+
109 'Where RF.RDB$RELATION_NAME = :TableName and RF.RDB$FIELD_NAME not in ' +
110 '(Select RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS S JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME '+
111 'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and C.RDB$RELATION_NAME = RF.RDB$RELATION_NAME) and B.RDB$COMPUTED_SOURCE is NULL ' +
112 'order by 1 asc ';
113
114 sqlALLUPDATEFIELDS = 'Select Trim(RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
115 'Where RF.RDB$RELATION_NAME = :TableName and RDB$FIELD_NAME not in ' +
116 '(Select RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS S JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME '+
117 'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and C.RDB$RELATION_NAME = RF.RDB$RELATION_NAME)' +
118 'order by 1 asc ';
119
120 sqlGETGENERATORNAMES = 'Select RDB$GENERATOR_NAME FROM RDB$GENERATORS '+
121 'Where RDB$SYSTEM_FLAG = 0 '+
122 'Order by 1 asc';
123
124 sqlGETPROCEDURES = 'Select Trim(RDB$PROCEDURE_NAME) as ProcName, RDB$PROCEDURE_INPUTS, '+
125 'RDB$PROCEDURE_OUTPUTS From RDB$PROCEDURES '+
126 'Where RDB$SYSTEM_FLAG = 0 and RDB$PROCEDURE_TYPE <= :ProcType Order by 1 asc';
127
128 sqlGETPROCPARAM = 'Select Trim(P.RDB$PARAMETER_NAME) as ParamName '+
129 'From RDB$PROCEDURE_PARAMETERS P '+
130 'JOIN RDB$FIELDS F On F.RDB$FIELD_NAME = P.RDB$FIELD_SOURCE '+
131 'Where P.RDB$SYSTEM_FLAG = 0 and P.RDB$PROCEDURE_NAME = :ProcName and P.RDB$PARAMETER_TYPE = :type '+
132 'Order by P.RDB$PARAMETER_NUMBER asc';
133
134 sqlCheckProcedureNames = 'Select * From RDB$PROCEDURES Where Upper(Trim(RDB$PROCEDURE_NAME)) = Upper(:ProcName)';
135
136 sqlGETPROCEDUREINFO = 'Select RDB$PROCEDURE_TYPE From RDB$PROCEDURES Where Upper(Trim(RDB$PROCEDURE_NAME)) = Upper(:ProcName)';
137
138 function TIBSystemTables.GetSQLType(SQLType: TIBSQLTypes): string;
139 begin
140 case SQLType of
141 SQLUnknown: Result := 'Unknown';
142 SQLSelect: Result := 'Select';
143 SQLInsert: Result := 'Insert';
144 SQLUpdate: Result := 'Update';
145 SQLDelete: Result := 'Delete';
146 SQLDDL: Result := 'DDL';
147 SQLGetSegment: Result := 'GetSegment';
148 SQLPutSegment: Result := 'PutSegment';
149 SQLExecProcedure: Result := 'Execute Procedure';
150 SQLStartTransaction: Result := 'StartTransaction';
151 SQLCommit: Result := 'Commit';
152 SQLRollback: Result := 'Rollback';
153 SQLSelectForUpdate: Result := 'Select for Update';
154 SQLSetGenerator: Result := 'Set Generator';
155 end;
156 end;
157
158 procedure TIBSystemTables.AddWhereClause(TableName: string;
159 QuotedStrings: boolean; SQL: TStrings; UseOldValues: boolean);
160 var WhereClause: string;
161 Separator: string;
162 Count: integer;
163 Prefix: string;
164 begin
165 if not assigned(FGetPrimaryKeys.Database) or not FGetPrimaryKeys.Database.Connected or
166 not assigned(FGetPrimaryKeys.Transaction) then
167 Exit;
168 Count := 0;
169 WhereClause := 'Where';
170 Separator := ' A.';
171 if UseOldValues then
172 Prefix := ':OLD_'
173 else
174 Prefix := ':';
175 FGetPrimaryKeys.Prepare;
176 FGetPrimaryKeys.ParamByName('TableName').AsString := TableName;
177 FGetPrimaryKeys.ExecQuery;
178 try
179 while not FGetPrimaryKeys.EOF do
180 begin
181 Inc(Count);
182 if QuotedStrings then
183 WhereClause := WhereClause + Separator + '"' + FGetPrimaryKeys.FieldByName('ColumnName').AsString +
184 '" = ' + Prefix+ AnsiUpperCase(FGetPrimaryKeys.FieldByName('ColumnName').AsString)
185 else
186 WhereClause := WhereClause + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FGetPrimaryKeys.FieldByName('ColumnName').AsString) +
187 ' = ' + Prefix + AnsiUpperCase(FGetPrimaryKeys.FieldByName('ColumnName').AsString);
188 Separator := ' AND A.';
189 FGetPrimaryKeys.Next
190 end;
191 finally
192 FGetPrimaryKeys.Close
193 end;
194 if Count > 0 then
195 SQL.Add(WhereClause)
196 end;
197
198 procedure TIBSystemTables.GetProcParams(ProcName: string; ParamList: TStrings;
199 InputParams: boolean);
200 begin
201 if not assigned(FGetProcedureParams.Database) or not FGetProcedureParams.Database.Connected or
202 not assigned(FGetProcedureParams.Transaction) then
203 Exit;
204 ParamList.Clear;
205 with FGetProcedureParams do
206 begin
207 with Transaction do
208 if not InTransaction then StartTransaction;
209 Prepare;
210 ParamByName('ProcName').AsString := ProcName;
211 if InputParams then
212 ParamByName('type').AsInteger := 0
213 else
214 ParamByName('type').AsInteger := 1;
215 ExecQuery;
216 try
217 while not EOF do
218 begin
219 ParamList.Add(FieldByName('ParamName').AsString);
220 Next;
221 end;
222 finally
223 Close
224 end;
225 end;
226 end;
227
228 function TIBSystemTables.GetWord(S: string; WordNo: integer): string;
229 const
230 SpaceChars = [' ',#$0a,#$0d,#$09,'('];
231 var I: integer;
232 StartIdx: integer;
233 InWhiteSpace: boolean;
234 begin
235 Result := '';
236 StartIdx := 1;
237 InWhiteSpace := true;
238 for I := 1 to Length(S) do
239 begin
240 if InWhiteSpace then
241 begin
242 if not (S[I] in SpaceChars) then
243 begin
244 StartIdx := I;
245 InWhiteSpace := false
246 end
247 end
248 else
249 begin
250 if S[I] in SpaceChars then
251 begin
252 Dec(WordNo);
253 if WordNo = 0 then
254 begin
255 Result := System.copy(S,StartIdx,I - StartIdx);
256 Exit
257 end;
258 InWhiteSpace := true
259 end
260 end
261 end;
262 end;
263
264 constructor TIBSystemTables.Create;
265 begin
266 FGetTableNames := TIBSQL.Create(nil);
267 FGetFieldNames := TIBSQL.Create(nil);
268 FGetPrimaryKeys := TIBSQL.Create(nil);
269 FGetProcedures := TIBSQL.Create(nil);
270 FTestSQL := TIBSQL.Create(nil);
271 FTableAndColumnSQL := TIBSQL.Create(nil);
272 FTableAndColumnSQL.GenerateParamNames := true; {Permissive}
273 FGetGeneratorsSQL := TIBSQL.Create(nil);
274 FGetProcedureParams := TIBSQL.Create(nil);
275 FGetProcedureInfo := TIBSQL.Create(nil);
276 end;
277
278 destructor TIBSystemTables.Destroy;
279 begin
280 if assigned(FGetFieldNames) then FGetFieldNames.Free;
281 if assigned(FGetTableNames) then FGetTableNames.Free;
282 if assigned(FTestSQL) then FTestSQL.Free;
283 if assigned(FGetPrimaryKeys) then FGetPrimaryKeys.Free;
284 if assigned(FTableAndColumnSQL) then FTableAndColumnSQL.Free;
285 if assigned(FGetGeneratorsSQL) then FGetGeneratorsSQL.Free;
286 if assigned(FGetProcedures) then FGetProcedures.Free;
287 if assigned(FGetProcedureParams) then FGetProcedureParams.Free;
288 if assigned(FGetProcedureInfo) then FGetProcedureInfo.Free;
289 inherited Destroy;
290 end;
291
292 procedure TIBSystemTables.SelectDatabase(Database: TIBDatabase;
293 Transaction: TIBTransaction);
294 begin
295 FGetTableNames.Database := Database;
296 FGetTableNames.Transaction := Transaction;
297 FGetTableNames.SQL.Text := sqlGETTABLES;
298 FGetFieldNames.Database := Database;
299 FGetFieldNames.Transaction := Transaction;
300 FGetFieldNames.SQL.Text := sqlGETFIELDS;
301 FTestSQL.Database := Database;
302 FTestSQL.Transaction := Transaction;
303 FGetPrimaryKeys.Database := Database;
304 FGetPrimaryKeys.Transaction := Transaction;
305 FGetPrimaryKeys.SQL.Text := sqlGETPRIMARYKEYS;
306 FTableAndColumnSQL.Database := Database;
307 FTableAndColumnSQL.Transaction := Transaction;
308 FGetGeneratorsSQL.Database := Database;
309 FGetGeneratorsSQL.Transaction := Transaction;
310 FGetGeneratorsSQL.SQL.Text := sqlGETGENERATORNAMES;
311 FGetProcedureParams.Database := Database;
312 FGetProcedureParams.Transaction := Transaction;
313 FGetProcedureParams.SQL.Text := sqlGETPROCPARAM;
314 FGetProcedureInfo.Database := Database;
315 FGetProcedureInfo.Transaction := Transaction;
316 FGetProcedureInfo.SQL.Text := sqlGETPROCEDUREINFO;
317 FGetProcedures.Database := Database;
318 FGetProcedures.Transaction := Transaction;
319 FGetProcedures.SQL.Text := sqlGETPROCEDURES;
320 end;
321
322 procedure TIBSystemTables.GetTableNames(TableNames: TStrings);
323 begin
324 if not assigned(FGetTableNames.Database) or not FGetTableNames.Database.Connected or
325 not assigned(FGetTableNames.Transaction) then
326 Exit;
327 with FGetTableNames.Transaction do
328 if not InTransaction then StartTransaction;
329 TableNames.Clear;
330 FGetTableNames.ExecQuery;
331 try
332 while not FGetTableNames.EOF do
333 begin
334 TableNames.Add(FGetTableNames.FieldByName('TableName').AsString);
335 FGetTableNames.Next
336 end;
337 finally
338 FGetTableNames.Close
339 end;
340 end;
341
342 procedure TIBSystemTables.GetFieldNames(TableName: string;
343 FieldNames: TStrings; IncludePrimaryKeys: boolean;
344 IncludeReadOnlyFields: boolean);
345 begin
346 if not assigned(FGetFieldNames.Database) or not FGetFieldNames.Database.Connected or
347 not assigned(FGetFieldNames.Transaction) then
348 Exit;
349 with FGetFieldNames.Transaction do
350 if not InTransaction then StartTransaction;
351 FieldNames.Clear;
352 if IncludePrimaryKeys then
353 begin
354 if IncludeReadOnlyFields then
355 FGetFieldNames.SQL.Text := sqlGETALLFIELDS
356 else
357 FGetFieldNames.SQL.Text := sqlGETFIELDS
358 end
359 else
360 if IncludeReadOnlyFields then
361 FGetFieldNames.SQL.Text := sqlALLUPDATEFIELDS
362 else
363 FGetFieldNames.SQL.Text := sqlUPDATEFIELDS;
364 FGetFieldNames.Prepare;
365 FGetFieldNames.ParamByName('TableName').AsString := TableName;
366 FGetFieldNames.ExecQuery;
367 try
368 while not FGetFieldNames.EOF do
369 begin
370 FieldNames.Add(FGetFieldNames.FieldByName('ColumnName').AsString);
371 FGetFieldNames.Next
372 end;
373 finally
374 FGetFieldNames.Close
375 end;
376 end;
377
378 procedure TIBSystemTables.GetPrimaryKeys(TableName: string; PrimaryKeys: TStrings);
379 begin
380 if not assigned(FGetPrimaryKeys.Database) or not FGetPrimaryKeys.Database.Connected or
381 not assigned(FGetPrimaryKeys.Transaction) then
382 Exit;
383 with FGetPrimaryKeys.Transaction do
384 if not InTransaction then StartTransaction;
385 PrimaryKeys.Clear;
386 FGetPrimaryKeys.Prepare;
387 FGetPrimaryKeys.ParamByName('TableName').AsString := TableName;
388 FGetPrimaryKeys.ExecQuery;
389 try
390 while not FGetPrimaryKeys.EOF do
391 begin
392 PrimaryKeys.Add(FGetPrimaryKeys.FieldByName('ColumnName').AsString);
393 FGetPrimaryKeys.Next
394 end;
395 finally
396 FGetPrimaryKeys.Close
397 end;
398 end;
399
400 procedure TIBSystemTables.GetTableAndColumns(SelectSQL: string;
401 var FirstTableName: string; Columns: TStrings);
402 var I: integer;
403 begin
404 FirstTableName := '';
405 if not assigned(FTableAndColumnSQL.Database) or not FTableAndColumnSQL.Database.Connected or
406 not assigned(FTableAndColumnSQL.Transaction) or (Trim(SelectSQL) = '') then
407 Exit;
408 with FTableAndColumnSQL.Transaction do
409 if not InTransaction then StartTransaction;
410 FTableAndColumnSQL.SQL.Text := SelectSQL;
411 try
412 FTableAndColumnSQL.Prepare;
413 case FTableAndColumnSQL.SQLType of
414 SQLSelect:
415 begin
416 if FTableAndColumnSQL.Current.Count > 0 then
417 FirstTableName := strpas(FTableAndColumnSQL.Current.Vars[0].Data^.relname)
418 else
419 FirstTableName := '';
420 if assigned(Columns) then
421 begin
422 Columns.Clear;
423 for I := 0 to FTableAndColumnSQL.Current.Count - 1 do
424 Columns.Add(FTableAndColumnSQL.Current.Vars[I].Name)
425 end;
426 end;
427 { If not a select statement then return table or procedure name
428 as First Table Name }
429 SQLUpdate:
430 FirstTableName := GetWord(SelectSQL,2);
431
432 else
433 FirstTableName := GetWord(SelectSQL,3);
434 end
435 except on E:EIBError do
436 // ShowMessage(E.Message);
437 end;
438 end;
439
440 procedure TIBSystemTables.GetProcedureNames(ProcNames: TStrings; WithOutputParams: boolean);
441 begin
442 if not assigned(FGetProcedures.Database) or not FGetProcedures.Database.Connected or
443 not assigned(FGetProcedures.Transaction) then
444 Exit;
445 ProcNames.Clear;
446 with FGetProcedures do
447 begin
448 with Transaction do
449 if not InTransaction then StartTransaction;
450 Prepare;
451 if WithOutputParams then
452 ParamByName('ProcType').AsInteger := 1
453 else
454 ParamByName('ProcType').AsInteger := 2;
455 ExecQuery;
456 try
457 while not EOF do
458 begin
459 ProcNames.Add(FieldByName('ProcName').AsString);
460 Next;
461 end;
462 finally
463 Close
464 end;
465 end;
466 end;
467
468 procedure TIBSystemTables.GetProcParams(ProcName: string;
469 var ExecuteOnly: boolean; InputParams, OutputParams: TStrings);
470 begin
471 GetProcParams(ProcName,InputParams,true);
472 GetProcParams(ProcName,OutputParams,false);
473 ExecuteOnly := OutputParams.Count = 0;
474 if not ExecuteOnly then
475 with FGetProcedureInfo do
476 begin
477 with Transaction do
478 if not InTransaction then StartTransaction;
479 Prepare;
480 ParamByName('ProcName').AsString := ProcName;
481 ExecQuery;
482 try
483 if not EOF then
484 ExecuteOnly := FieldByName('RDB$PROCEDURE_TYPE').AsInteger = 2
485 finally
486 Close
487 end;
488 end;
489 end;
490
491 procedure TIBSystemTables.GetGenerators(GeneratorNames: TStrings);
492 begin
493 if not assigned(FGetGeneratorsSQL.Database) or not FGetGeneratorsSQL.Database.Connected or
494 not assigned(FGetGeneratorsSQL.Transaction) then
495 Exit;
496 GeneratorNames.Clear;
497 with FGetGeneratorsSQL do
498 begin
499 with Transaction do
500 if not InTransaction then StartTransaction;
501 ExecQuery;
502 try
503 while not EOF do
504 begin
505 GeneratorNames.Add(FieldByName('RDB$GENERATOR_NAME').AsString);
506 Next;
507 end;
508 finally
509 Close
510 end;
511 end;
512
513 end;
514
515 procedure TIBSystemTables.GenerateSelectSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
516 var SelectSQL: string;
517 Separator : string;
518 I: integer;
519 begin
520 SQL.Clear;
521 if not assigned(FGetFieldNames.Database) or not FGetFieldNames.Database.Connected or
522 not assigned(FGetFieldNames.Transaction) then
523 begin
524 Messagedlg('No Database Connected',mtError,[mbOK],0);
525 Exit;
526 end;
527 SelectSQL := 'Select';
528 Separator := ' A.';
529 for I := 0 to FieldNames.Count - 1 do
530 begin
531 if QuotedStrings then
532 SelectSQL := SelectSQL + Separator + '"' + FieldNames[I] + '"'
533 else
534 SelectSQL := SelectSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]);
535 Separator := ', A.';
536 end;
537 SelectSQL := SelectSQL + ' From ' + TableName + ' A';
538 SQL.Add(SelectSQL);
539 end;
540
541 procedure TIBSystemTables.GenerateRefreshSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
542 begin
543 GenerateSelectSQL(TableName,QuotedStrings,FieldNames,SQL);
544 AddWhereClause(TableName,QuotedStrings,SQL)
545 end;
546
547 procedure TIBSystemTables.GenerateInsertSQL(TableName: string;
548 QuotedStrings: boolean; FieldNames,SQL: TStrings);
549 var InsertSQL: string;
550 Separator: string;
551 I: integer;
552 begin
553 SQL.Clear;
554 InsertSQL := 'Insert Into ' + TableName + '(';
555 Separator := '';
556 for I := 0 to FieldNames.Count - 1 do
557 begin
558 if QuotedStrings then
559 InsertSQL := InsertSQL + Separator + '"' + FieldNames[I] + '"'
560 else
561 InsertSQL := InsertSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]) ;
562 Separator := ', ';
563 end;
564 InsertSQL := InsertSQL + ')';
565 SQL.Add(InsertSQL);
566 InsertSQL := 'Values(';
567 Separator := ':';
568 for I := 0 to FieldNames.Count - 1 do
569 begin
570 InsertSQL := InsertSQL + Separator + AnsiUpperCase(FieldNames[I]) ;
571 Separator := ', :';
572 end;
573 InsertSQL := InsertSQL + ')';
574 SQL.Add(InsertSQL);
575 end;
576
577 procedure TIBSystemTables.GenerateModifySQL(TableName: string; QuotedStrings: boolean;
578 FieldNames,SQL: TStrings);
579 var UpdateSQL: string;
580 Separator: string;
581 I: integer;
582 begin
583 SQL.Clear;
584 Separator := #$0d#$0a' A.';
585 UpdateSQL := 'Update ' + TableName + ' A Set ';
586 for I := 0 to FieldNames.Count - 1 do
587 begin
588 if QuotedStrings then
589 UpdateSQL := UpdateSQL + Separator + '"' + FieldNames[I] + '" = :' + AnsiUpperCase(FieldNames[I])
590 else
591 UpdateSQL := UpdateSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]) + ' = :' + AnsiUpperCase(FieldNames[I]);
592 Separator := ','#$0d#$0a' A.';
593 end;
594 SQL.Add(UpdateSQL);
595 AddWhereClause(TableName,QuotedStrings,SQL,true)
596 end;
597
598 procedure TIBSystemTables.GenerateDeleteSQL(TableName: string; QuotedStrings: boolean; SQL: TStrings);
599 begin
600 SQL.Clear;
601 SQL.Add('Delete From ' + TableName + ' A');
602 AddWhereClause(TableName,QuotedStrings,SQL)
603 end;
604
605 procedure TIBSystemTables.GenerateExecuteSQL(ProcName: string;
606 QuotedStrings: boolean; ExecuteOnly: boolean; InputParams, OutputParams,
607 ExecuteSQL: TStrings);
608 var SQL: string;
609 I: integer;
610 Separator: string;
611 begin
612 Separator := '';
613 if not ExecuteOnly and (OutputParams.Count > 0) then //Select Query
614 begin
615 SQL := 'Select ';
616 for I := 0 to OutputParams.Count - 1 do
617 begin
618 if QuotedStrings then
619 SQL := SQL + Separator + '"' + OutputParams[I] + '"'
620 else
621 SQL := SQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,OutputParams[I]);
622 Separator := ', ';
623 end;
624 SQL := SQL + ' From ' + ProcName;
625 if InputParams.Count > 0 then
626 begin
627 Separator := '(:';
628 for I := 0 to InputParams.Count - 1 do
629 begin
630 SQL := SQL + Separator + AnsiUpperCase(InputParams[I]);
631 Separator := ', :';
632 end;
633 SQL := SQL + ')'
634 end
635 end
636 else // Execute Procedure
637 begin
638 if QuotedStrings then
639 SQL := 'Execute Procedure "' + ProcName + '"'
640 else
641 SQL := 'Execute Procedure ' + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,ProcName);
642 if InputParams.Count > 0 then
643 begin
644 Separator := ' :';
645 for I := 0 to InputParams.Count - 1 do
646 begin
647 if QuotedStrings then
648 SQL := SQL + Separator + '"' + InputParams[I] + '"'
649 else
650 SQL := SQL + Separator + AnsiUpperCase(InputParams[I]);
651 Separator := ', :';
652 end;
653 end
654 end;
655 ExecuteSQL.Text := SQL
656 end;
657
658 function TIBSystemTables.GetStatementType(SQL: string; var IsStoredProcedure: boolean): TIBSQLTypes;
659 var TableName: string;
660 begin
661 Result := sqlUnknown;
662 if not assigned(FTestSQL.Database) or not FTestSQL.Database.Connected or
663 not assigned(FTestSQL.Transaction) or (Trim(SQL) = '') then
664 Exit;
665 IsStoredProcedure := false;
666 FTestSQL.SQL.Text := SQL;
667 FTestSQL.GenerateParamNames := true; {permissive}
668 try
669 FTestSQL.Prepare;
670 Result := FTestSQL.SQLType
671 except on E:EIBError do
672 // ShowMessage(E.Message);
673 end;
674 if (Result = SQLSelect) and (FTestSQL.Current.Count > 0) then
675 begin
676 TableName := strpas(FTestSQL.Current.Vars[0].Data^.relname);
677 FTestSQL.SQL.Text := sqlCheckProcedureNames;
678 FTestSQL.Prepare;
679 FTestSQL.ParamByName('ProcName').AsString := TableName;
680 FTestSQL.ExecQuery;
681 try
682 IsStoredProcedure := not FTestSQL.EOF;
683 finally
684 FTestSQL.Close
685 end;
686 end;
687 end;
688
689 function TIBSystemTables.GetFieldNames(FieldList: TListBox): TStrings;
690 var I: integer;
691 begin
692 Result := TStringList.Create;
693 try
694 if FieldList.SelCount = 0 then
695 Result.Assign(FieldList.Items)
696 else
697 for I := 0 to FieldList.Items.Count - 1 do
698 if FieldList.Selected[I] then
699 Result.Add(FieldList.Items[I]);
700 except
701 Result.Free;
702 raise
703 end;
704 end;
705
706 procedure TIBSystemTables.TestSQL(SQL: string;
707 GenerateParamNames: boolean);
708 begin
709 if not assigned(FTestSQL.Database) or not FTestSQL.Database.Connected or
710 not assigned(FTestSQL.Transaction) then
711 begin
712 Messagedlg('No Database Connected',mtError,[mbOK],0);
713 Exit;
714 end;
715 FTestSQL.GenerateParamNames := GenerateParamNames;
716 FTestSQL.SQL.Text := SQL;
717 try
718 FTestSQL.Prepare;
719 ShowMessage('SQL '+ GetSQLType(FTestSQL.SQLType) + ' Statement Looks OK');
720 except on E:EIBError do
721 ShowMessage(E.Message);
722 end;
723 end;
724
725 end.
726