我的程序要监视几个数据库(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、你自己的程序只需要在那里等待即可!
最好要监视的表数据更新后能够自动发送消息给我的程序,然后我的程序的程序再根据数据更新的类别再作处理。
现在我用的方法是:给这些表做触发器:当表有变化时,往特定的一张表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、你自己的程序只需要在那里等待即可!
看看“前几天和我的同事遇到了类似的问题,她是用一个触发器去触发ORALCE一个外部调用,有外部调用去向一个指定的窗口发消息,然后就实现了数据库更新时的自动通知功能。”是你不认识字吗?你还要怎么样?
这样问题我在PB、数据库基础版中问过,提问中引用了其中的一些回答。在这里提出来的目的是:一来,大家共同讨论学习。二来,VC++版人气旺,高手云集,希望能有更好的问题解决方案。三来,本人菜鸟,做dll让触发器调用、外部调用去向一个指定的窗口发消息、COM服务器程序通知远程的程序、线程接收消息……等等不会,希望能找到类似例程。
如果是 sql server
在你需要知道变化的表后加一个触发器
exec master..xp_cmdshell 'c:\example.exe' //example.exe' 服务器端程序
调用你的外部程序,在这个程序里你的活动空间就很大了
你这里的example.exe' 服务器端程序可以有图形界面吗?我做了一个小测试,用vc做了一个基于对话框的程序在触发器里调用,但是对话框出不来,但是windows 2000的进程里可以看到它在运行。why?
另外,如果被关联的数据库与原始数据库不在同一台机器上呢?是不是还要加上socket通讯?
还有,可以参考一下oracle 自带的一些系统存储过程,功能很强大的。估计又可以参考的地方和启发的地方。祝顺利!
if (pWndPrev = CWnd::FindWindow("#32770", "WindowName"))
{pWndPrev->PostMessage(WM_COMMAND, REFRESH);
}return FALSE;在刷新函数中进行数据刷新
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通知远端的 客户端程序,并返回
(一定要正常返回,否则存储过程会无限期地等待)
先写一个 C++ 程序 带参数的,
参数中至少有一个是 用来放你程序的HWND
的.
这样你在触发器中就可以调用
yourProg yourHwnd, ..,....
可以传入 Caption Text
当表改变时可以发送自定义消息WM_USERDEFINE...
然后在响应函数中实现数据的同步处理,这样就不用经常扫描临时记录表了
用VC实现应该很简单的
http://expert.csdn.net/Expert/topic/1136/1136115.xml?temp=.9661066
新建一个空的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的大名哈..