我的程序要监视几个数据库(sql server、sybase等)中一些表的变化情况,然后根据这些变化来更新另外一个数据库中与之关联的表(维护数据的一致性)。如何实现?
    最好要监视的表数据更新后能够自动发送消息给我的程序,然后我的程序的程序再根据数据更新的类别再作处理。
   现在我用的方法是:给这些表做触发器:当表有变化时,往特定的一张表my_systable写入一条新记录,我的程序定时扫描表my_systable,查看这个表my_systable中有没有新记录,然后再作处理。但这样开销太大。
   有没有更好的方法?
   欢迎参加讨论!谈谈你的想法,或者谈谈如何实现下面的想法。下面是csdn的朋友们的见解,供参考:
——————————
grey_whp(小跑) : 
  先写一个触发器,在ORACLE中,调用外部C++程序,将windows常用的3个DLL联编到自己的程序里,这用就可以通知窗口了。——————————
发送者 grey_whp 发送时间 2002-6-3 22:40:11 
前几天和我的同事遇到了类似的问题,她是用一个触发器去触发ORALCE一个外部调用,有外部调用去向一个指定的窗口发消息,然后就实现了数据库更新时的自动通知功能。
你可用到的windows中的几个动态连接库,是KERNEL32.dll,user32.dll另一个我忘记了,他们在winnt\system32下。 ————————————————————————-
回复人: tpProgramer(tp编程者)   
数据库是不会相你报告的,你要自己去获取变化的通知,这需要一个线程来监视,但是这个线程不用每次都把数据表中的内容读出来和原来的比较,这样效率也太低了,再编写一个响应Updat操作的触发器,在触发器中向上一级的监视线程发送改变通知。
——————————————————————
alexzhou(你的明天会怎样) 
你总是要反复监视的
SQL不会主动向你的程序响应的吧
开个线程做啊 CreateThread 
——————————————————————
回复人: jackygan(一剑飘香) ★如果是SQLSERVER的话,他本身看带的profile里有一个自动监视,很多用的。——————————————————————
回复人: SOFTFUN_CSDN(不知所云~) ( ★ ) 
 
1、这是DBMS的范畴,通用的实现做起来比较复杂,因为不同的DBMS差异较大;
2、一般DBMS都提供有此功能;
3、用触发器是很不现实且笨的方法;——————————————————————
回复人: jinfeng_wang(G-G-S,D-D-U) 我的想法:
1、触发器监视是否有数据改变!
2、调用扩展存储过程(SQL SERVER) ,启动本地某个COM服务器
3、COM服务器程序通知远程的你的机器程序!
4、你自己的程序只需要在那里等待即可!

解决方案 »

  1.   

    做一个事件触发器是效率最高的。  否则,你必须要自己去监视sql server的事件日志
      

  2.   

    作者wnchg (wnchg) 你真是莫名其妙啊,你自己贴出来的那些帖子不是已经说得很清楚了吗?你还问些什么?
    看看“前几天和我的同事遇到了类似的问题,她是用一个触发器去触发ORALCE一个外部调用,有外部调用去向一个指定的窗口发消息,然后就实现了数据库更新时的自动通知功能。”是你不认识字吗?你还要怎么样?
      

  3.   

    一点说明:
      这样问题我在PB、数据库基础版中问过,提问中引用了其中的一些回答。在这里提出来的目的是:一来,大家共同讨论学习。二来,VC++版人气旺,高手云集,希望能有更好的问题解决方案。三来,本人菜鸟,做dll让触发器调用、外部调用去向一个指定的窗口发消息、COM服务器程序通知远程的程序、线程接收消息……等等不会,希望能找到类似例程。
      

  4.   

    to:wnchg(wnchg)
    如果是 sql server
    在你需要知道变化的表后加一个触发器
    exec master..xp_cmdshell 'c:\example.exe' //example.exe' 服务器端程序
    调用你的外部程序,在这个程序里你的活动空间就很大了
      

  5.   

    TO: renren6250(刀客)
       你这里的example.exe' 服务器端程序可以有图形界面吗?我做了一个小测试,用vc做了一个基于对话框的程序在触发器里调用,但是对话框出不来,但是windows 2000的进程里可以看到它在运行。why?
       另外,如果被关联的数据库与原始数据库不在同一台机器上呢?是不是还要加上socket通讯?
      

  6.   

    Use triger is the best. It is simplest, fastest and most efficient way doing it. I don't know ORACLE OCI or OCCI has C/C++ interface for it.
      

  7.   

    可以肯定的是:触发器比不停的从外部查询,比较要高效的多。所以触发器一定要用到。其次,由触发器来触发什么样的动作来通知应用程序。我考虑,自己编写dll通过触发器来进行外部调用是可以得。
    还有,可以参考一下oracle 自带的一些系统存储过程,功能很强大的。估计又可以参考的地方和启发的地方。祝顺利!
      

  8.   

    我想,sqlserver应该可以提供这个接口吧?我们的程序应该可以利用这个接口来进行处理的。
      

  9.   

    接renren6250(刀客)   CWnd *pWndPrev, *pWndChild;
    if (pWndPrev = CWnd::FindWindow("#32770", "WindowName"))
    {pWndPrev->PostMessage(WM_COMMAND, REFRESH);
    }return FALSE;在刷新函数中进行数据刷新
      

  10.   

    renren6250(刀客)的方法最好
    sql server
    在my_systable加一个触发器
    exec sp_mycallback
    在sp_mycallback中加入
    @psParam1 as char(50),@psParam2 as char(50)........
    select @psCmd="c:\example.exe"
    select @psCmd=STUFF(@psCmd,14,x1,@psParam1)
    ..........................................
    exec master..xp_cmdshell @psCmd
    ------------------@psCmd 是带了命令行参数的字符串的控制台程序,
    注意要控制台程序,否则,存储过程会一直等待到该程序正常结束才返回!!!比如 @psCmd 是"C:\example1.exe  table1, Add, keyName"在example1控制台程序接收参数,并通过COM通知远端的 客户端程序,并返回
    (一定要正常返回,否则存储过程会无限期地等待)
      

  11.   

    你这样,
    先写一个 C++ 程序 带参数的,
    参数中至少有一个是 用来放你程序的HWND
    的.
    这样你在触发器中就可以调用
    yourProg yourHwnd, ..,....
      

  12.   

    如果句柄不方便得到
    可以传入 Caption Text
      

  13.   

    你可以做一个触发器,主要在于响应函数
    当表改变时可以发送自定义消息WM_USERDEFINE...
    然后在响应函数中实现数据的同步处理,这样就不用经常扫描临时记录表了
    用VC实现应该很简单的
      

  14.   

    如果是oracle,不妨看看我的贴子.
    http://expert.csdn.net/Expert/topic/1136/1136115.xml?temp=.9661066
      

  15.   

    哈哈,我帮zheng017贴!!
    新建一个空的win32 dynamic_link library project.取名为testdll.
    加入testdll.cpp.源程序如下:
    #include <windows.h>
    int __stdcall DllMain(HANDLE,DWORD,LPVOID)
    { return 1;
    }
    short test(void)
    {
       return system("dir e: > e:\\mydire.txt"); 
    }
    加入testdll.def:如下:
    LIBRARY "testdll.dll"
    EXPORTS
    test @1
    then click the bulid.get the testdll.dll.copy to e:\
    打开sql plus.登录(最好不要用internal身份登录).
    建立一个包:
    SQL> create or replace library wz_test
      2  as 'e:\testdll.dll';
      3  /
    建一个function:
    SQL> create or replace function wz_funtest
      2  return binary_integer
      3  as
      4  external
      5  library wz_test
      6  name "test"
      7  language c
      8  parameters (return short);
      9  /
    建一个表
    SQL>create table ff(addr varchar2(20));
    建立一个trigger:
    SQL> create or replace trigger my_test_trigger after insert on ff
      2  declare
      3  my_result binary_integer;
      4  begin
      5  my_result :=wz_funtest;
      6  end;
      7  /
    现在
    SQL>insert into ff values('chengdu');
    然后在e盘看看是不是多了一个文件.
    可以把我的dll中test函数改一下:用FindWindowEx,SendMessage跟自己程序通信或者直接用socket通信.
    嘻嘻,如果有转载的话,请署上zheng017的大名哈..