76 |
|
{$ELSE} |
77 |
|
baseunix, unix, |
78 |
|
{$ENDIF} |
79 |
< |
SysUtils, Classes, Forms, Controls, IBHeader, |
79 |
> |
SysUtils, Classes, IBHeader, |
80 |
|
IBErrorCodes, IBExternals, DB, IB, IBDatabase, IBUtils, IBXConst; |
81 |
|
|
82 |
|
const |
328 |
|
TIBSQL = class(TComponent) |
329 |
|
private |
330 |
|
FIBLoaded: Boolean; |
331 |
+ |
FOnSQLChanged: TNotifyEvent; |
332 |
|
FUniqueParamNames: Boolean; |
333 |
|
function GetFieldCount: integer; |
334 |
|
procedure SetUniqueParamNames(AValue: Boolean); |
367 |
|
procedure SetSQL(Value: TStrings); |
368 |
|
procedure SetTransaction(Value: TIBTransaction); |
369 |
|
procedure SQLChanging(Sender: TObject); |
370 |
< |
procedure BeforeTransactionEnd(Sender: TObject); |
370 |
> |
procedure SQLChanged(Sender: TObject); |
371 |
> |
procedure BeforeTransactionEnd(Sender: TObject; Action: TTransactionAction); |
372 |
|
public |
373 |
|
constructor Create(AOwner: TComponent); override; |
374 |
|
destructor Destroy; override; |
414 |
|
property SQL: TStrings read FSQL write SetSQL; |
415 |
|
property Transaction: TIBTransaction read GetTransaction write SetTransaction; |
416 |
|
property OnSQLChanging: TNotifyEvent read FOnSQLChanging write FOnSQLChanging; |
417 |
+ |
property OnSQLChanged: TNotifyEvent read FOnSQLChanged write FOnSQLChanged; |
418 |
|
end; |
419 |
|
|
420 |
|
implementation |
2156 |
|
FRecordCount := 0; |
2157 |
|
FSQL := TStringList.Create; |
2158 |
|
TStringList(FSQL).OnChanging := SQLChanging; |
2159 |
+ |
TStringList(FSQL).OnChange := SQLChanged; |
2160 |
|
FProcessedSQL := TStringList.Create; |
2161 |
|
FHandle := nil; |
2162 |
|
FSQLParams := TIBXSQLDA.Create(self,daInput); |
2163 |
|
FSQLRecord := TIBXSQLDA.Create(self,daOutput); |
2164 |
|
FSQLType := SQLUnknown; |
2165 |
|
FParamCheck := True; |
2166 |
< |
FCursor := Name + RandomString(8); |
2166 |
> |
FCursor := HexStr(self); //Name + RandomString(8); |
2167 |
|
if AOwner is TIBDatabase then |
2168 |
|
Database := TIBDatabase(AOwner) |
2169 |
|
else |
2315 |
|
FBOF := True; |
2316 |
|
FEOF := False; |
2317 |
|
FRecordCount := 0; |
2318 |
+ |
if not (csDesigning in ComponentState) then |
2319 |
+ |
MonitorHook.SQLExecute(Self); |
2320 |
|
if FGoToFirstRecordOnExecute then |
2321 |
|
Next; |
2322 |
|
end; |
2327 |
|
Database.SQLDialect, |
2328 |
|
FSQLParams.AsXSQLDA, |
2329 |
|
FSQLRecord.AsXSQLDA), True); |
2330 |
+ |
if not (csDesigning in ComponentState) then |
2331 |
+ |
MonitorHook.SQLExecute(Self); |
2332 |
|
(* if (fetch_res <> 0) and (fetch_res <> isc_deadlock) then |
2333 |
|
begin |
2334 |
|
{ Sometimes a prepared stored procedure appears to get |
2351 |
|
TRHandle, |
2352 |
|
@FHandle, |
2353 |
|
Database.SQLDialect, |
2354 |
< |
FSQLParams.AsXSQLDA), True) |
2354 |
> |
FSQLParams.AsXSQLDA), True); |
2355 |
> |
if not (csDesigning in ComponentState) then |
2356 |
> |
MonitorHook.SQLExecute(Self); |
2357 |
|
end; |
2358 |
< |
if not (csDesigning in ComponentState) then |
2359 |
< |
MonitorHook.SQLExecute(Self); |
2358 |
> |
FBase.DoAfterExecQuery(self); |
2359 |
> |
// writeln('Rows Affected = ',RowsAffected); |
2360 |
|
end; |
2361 |
|
|
2362 |
|
function TIBSQL.GetEOF: Boolean; |
2468 |
|
SQLUpdate, SQLDelete])) then |
2469 |
|
result := '' |
2470 |
|
else begin |
2471 |
< |
info_request := Char(isc_info_sql_get_plan); |
2471 |
> |
info_request := isc_info_sql_get_plan; |
2472 |
|
Call(isc_dsql_sql_info(StatusVector, @FHandle, 2, @info_request, |
2473 |
|
SizeOf(result_buffer), result_buffer), True); |
2474 |
< |
if (result_buffer[0] <> Char(isc_info_sql_get_plan)) then |
2474 |
> |
if (result_buffer[0] <> isc_info_sql_get_plan) then |
2475 |
|
IBError(ibxeUnknownError, [nil]); |
2476 |
|
result_length := isc_vax_integer(@result_buffer[1], 2); |
2477 |
|
SetString(result, nil, result_length); |
2488 |
|
|
2489 |
|
function TIBSQL.GetRowsAffected: Integer; |
2490 |
|
var |
2481 |
– |
result_buffer: array[0..1048] of Char; |
2491 |
|
info_request: Char; |
2492 |
+ |
RB: TResultBuffer; |
2493 |
|
begin |
2494 |
|
if not Prepared then |
2495 |
|
result := -1 |
2496 |
|
else begin |
2497 |
< |
info_request := Char(isc_info_sql_records); |
2498 |
< |
if isc_dsql_sql_info(StatusVector, @FHandle, 1, @info_request, |
2499 |
< |
SizeOf(result_buffer), result_buffer) > 0 then |
2500 |
< |
IBDatabaseError; |
2501 |
< |
if (result_buffer[0] <> Char(isc_info_sql_records)) then |
2502 |
< |
result := -1 |
2503 |
< |
else |
2504 |
< |
case SQLType of |
2505 |
< |
SQLUpdate: Result := isc_vax_integer(@result_buffer[6], 4); |
2506 |
< |
SQLDelete: Result := isc_vax_integer(@result_buffer[13], 4); |
2507 |
< |
SQLInsert: Result := isc_vax_integer(@result_buffer[27], 4); |
2508 |
< |
else Result := -1 ; |
2509 |
< |
end ; |
2497 |
> |
RB := TResultBuffer.Create; |
2498 |
> |
try |
2499 |
> |
info_request := isc_info_sql_records; |
2500 |
> |
if isc_dsql_sql_info(StatusVector, @FHandle, 1, @info_request, |
2501 |
> |
RB.Size, RB.buffer) > 0 then |
2502 |
> |
IBDatabaseError; |
2503 |
> |
case SQLType of |
2504 |
> |
SQLInsert, SQLUpdate: {Covers Insert or Update as well as individual update} |
2505 |
> |
Result := RB.GetValue(isc_info_sql_records, isc_info_req_insert_count)+ |
2506 |
> |
RB.GetValue(isc_info_sql_records, isc_info_req_update_count); |
2507 |
> |
SQLDelete: |
2508 |
> |
Result := RB.GetValue(isc_info_sql_records, isc_info_req_delete_count); |
2509 |
> |
SQLExecProcedure: |
2510 |
> |
Result := RB.GetValue(isc_info_sql_records, isc_info_req_insert_count) + |
2511 |
> |
RB.GetValue(isc_info_sql_records, isc_info_req_update_count) + |
2512 |
> |
RB.GetValue(isc_info_sql_records, isc_info_req_delete_count); |
2513 |
> |
else |
2514 |
> |
Result := 0; |
2515 |
> |
end; |
2516 |
> |
finally |
2517 |
> |
RB.Free; |
2518 |
> |
end; |
2519 |
|
end; |
2520 |
|
end; |
2521 |
|
|
2567 |
|
end; |
2568 |
|
|
2569 |
|
begin |
2570 |
+ |
sParamName := ''; |
2571 |
|
slNames := TStringList.Create; |
2572 |
|
try |
2573 |
|
{ Do some initializations of variables } |
2728 |
|
{ After preparing the statement, query the stmt type and possibly |
2729 |
|
create a FSQLRecord "holder" } |
2730 |
|
{ Get the type of the statement } |
2731 |
< |
type_item := Char(isc_info_sql_stmt_type); |
2731 |
> |
type_item := isc_info_sql_stmt_type; |
2732 |
|
Call(isc_dsql_sql_info(StatusVector, @FHandle, 1, @type_item, |
2733 |
|
SizeOf(res_buffer), res_buffer), True); |
2734 |
< |
if (res_buffer[0] <> Char(isc_info_sql_stmt_type)) then |
2734 |
> |
if (res_buffer[0] <> isc_info_sql_stmt_type) then |
2735 |
|
IBError(ibxeUnknownError, [nil]); |
2736 |
|
stmt_len := isc_vax_integer(@res_buffer[1], 2); |
2737 |
|
FSQLType := TIBSQLTypes(isc_vax_integer(@res_buffer[3], stmt_len)); |
2820 |
|
if FHandle <> nil then FreeHandle; |
2821 |
|
end; |
2822 |
|
|
2823 |
< |
procedure TIBSQL.BeforeTransactionEnd(Sender: TObject); |
2823 |
> |
procedure TIBSQL.SQLChanged(Sender: TObject); |
2824 |
> |
begin |
2825 |
> |
if assigned(OnSQLChanged) then |
2826 |
> |
OnSQLChanged(self); |
2827 |
> |
end; |
2828 |
> |
|
2829 |
> |
procedure TIBSQL.BeforeTransactionEnd(Sender: TObject; |
2830 |
> |
Action: TTransactionAction); |
2831 |
|
begin |
2832 |
|
if (FOpen) then |
2833 |
|
Close; |