首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何捕获Delphi TDataSetProvider生成的SQL?

如何捕获Delphi TDataSetProvider生成的SQL?
EN

Stack Overflow用户
提问于 2019-10-25 16:22:07
回答 1查看 242关注 0票数 0

我有TClientDataSet,TDataSetProvider和TIBQuery链,在执行CDS.Post时有'unprepared statement‘错误,很明显,TDataSetProvider生成的更新语句是错误的。如何捕获此更新SQL?SQL监控对我的IBX组件不起作用。我尝试使用代码(灵感来自TClientDataset.ApplyUpdates fails with 'SQL not supported' when using SQLDirect components):

代码语言:javascript
复制
procedure TSQLResolver.DoExecSQL(SQL: TWideStringList; Params: TParams);
var
  RowsAffected: Integer;
  TmpList: TStringList;
begin
  TmpList:=TStringList.Create;
  TmpList.LoadFromFile('C:\Test\test.txt');
  RowsAffected := (Provider.DataSet as IProviderSupport).PSExecuteStatement(SQL.Text, Params);
  if not (poAllowMultiRecordUpdates in Provider.Options) and (RowsAffected > 1) then
  begin
    TmpList.Add(SQL.Text);
    TmpList.SaveToFile('C:\Test\test.txt');
    TmpList.Free;
    (Provider.DataSet as IProviderSupport).PSEndTransaction(False);
    Provider.TransactionStarted := False;
    DatabaseError(STooManyRecordsModified);
  end;
  if RowsAffected < 1 then
    DatabaseError(SRecordChanged);
end;

但是Test/test.txt文件中没有写入任何内容。我可以把这样的日志代码放在哪里?

Delphi 2010,但我猜这适用于任何版本的Delphi。

EN

回答 1

Stack Overflow用户

发布于 2019-10-25 20:09:47

没有任何内容写入日志文件的原因是,按照您添加日志的方式,只有在更新影响超过一行时才会执行日志。Imo,你的代码应该是

代码语言:javascript
复制
procedure TSQLResolver.DoExecSQL(SQL: TStringList; Params: TParams);
var
  RowsAffected: Integer;
  TmpList: TStringList;
begin
  TmpList:=TStringList.Create;
  try
    TmpList.LoadFromFile('C:\Test\test.txt');
    RowsAffected := (Provider.DataSet as IProviderSupport).PSExecuteStatement(SQL.Text, Params);
    TmpList.Add(SQL.Text);
    TmpList.SaveToFile('C:\Test\test.txt');
    if not (poAllowMultiRecordUpdates in Provider.Options) and (RowsAffected > 1) then
    begin
      (Provider.DataSet as IProviderSupport).PSEndTransaction(False);
      Provider.TransactionStarted := False;
      DatabaseError(STooManyRecordsModified);
    end;
    if RowsAffected < 1 then
      DatabaseError(SRecordChanged);
  finally
    TmpList.Free;
  end;
end;

无论更新的行数是多少,它都应该起作用。它还通过在只有条件执行的代码中释放TmpList来修复您设置的TmpList泄漏。顺便说一句,您会发现这段代码不会记录由Params中的值提供的值,但是可以很容易地将这些值添加到日志中,甚至将它们合并到记录的SQL.Text中。

希望这能解决您当前的问题,但坦率地说,将时间花在将代码简化为mre上会更好。我这么说有几个原因,第一,我从来没有在使用IBX + DSP/CDS的时候出现过“未准备好的语句”错误,第二,使用IBX组件进行日志记录通常工作得很好,第三,准备一个mre通常会揭示出问题的原因。所以我怀疑你没有向我们展示的代码中有一个错误。

如果您将mre设置为使用其中一个示例IB数据库,并将其作为新的Q发布到此处(请不要作为对此数据库的编辑),您很可能会发现读者准备自己尝试它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58554795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档