从Delphi应用程序中识别Interbase表中已更改的行

时间:2016-02-06 18:25:53

标签: delphi interbase

我知道我可以在应用程序中使用TIBEvents对象来接收发布的事件 由Interbase服务器使用POST_EVENT。

通过在IB数据库上设置触发器,我可以使用此机制来获取通知 何时行更新,插入或删除,但不涉及哪些行。什么阻止它识别行是事件名称需要的事实 由IBEvents对象预先知道。尽管有IBEvents对象的限制(或者更可能是POST_EVENT机制),是否有一种简单的方法来进行此识别?

1 个答案:

答案 0 :(得分:2)

巧合的是,我最近一直在研究这个话题,今天我偶然发现了 一个原生的Interbase解决方案,使用一个称为Change Views的相对较新的功能(参见Stephen Ball的博客在https://delphiaball.co.uk/2015/02/06/interbase-change-views-part-1/上进行了介绍。

基本上,这涉及在服务器上设置一个“订阅”,它定义了哪些表 感兴趣的是各种操作(更新插入和删除),授予用户订阅权限 订阅,然后设置客户端应用程序以利用该信息 来自订阅。

Change Views的一个好处是它们可以与传统的IBX一起使用 只有几行代码的组件 - 请参见下面的示例。我没试过,但看不到任何 之所以只要他们支持,就不能与DBExpress或FireDAC一起使用 将交易类型设置为“快照”。

有几个皱纹:

  • 除非您回滚检索更改的事务(根据代码 在下面),下次您查看订阅时,您将看不到所看到的更改 上次。如果您希望下次仅查看后续更改,请在Select查询上调用Commit而不是Rollback。

  • 订阅实施隐藏了对您的表格所做的更改 自己的登录ID,因此对于设置和测试,您需要使用不同的登录,一个 进行更改,另一方查看。

代码:

procedure TForm1.OpenQuery;
var
  Sql : String;
begin
  //  Note that it is VITAL for the SELECT to return the desired results
  //  that the transaction type is set to "Snapshot", which can be done in the IDE
  //  using the Transaction Editor or in code as follows

  IBTransaction1.Params.Clear;
  IBTransaction1.Params.Add('concurrency');
  IBTransaction1.Params.Add('nowait');

  //  Next, activate the subscription
  Sql := 'SET SUBSCRIPTION "TABLE1CHANGES" ACTIVE;';
  IBQuery1.SQL.Text := Sql;
  IBQuery1.ExecSQL;

  //  Now we can retrieve the changed rows.  Note the "where" clause
  Sql := 'SELECT id, aname, avalue FROM table1 where aname is changed';  // or "is updated", 
  //  inserted, or deleted
  IBQuery1.SQL.Text := Sql;
  IBQuery1.Open;

end;

Delphi应用程序中的动态Sql一样,请注意SQL注入。

更新:显然Interbase Express(IBX)组件库已更新为支持订阅,我假设在西雅图(我有但不使用)。