超级难的问题(数据库某表更新后怎样才能马上通知应用程序?) ( 积分: 300 )

  • 主题发起人 主题发起人 jierxrh
  • 开始时间 开始时间
J

jierxrh

Unregistered / Unconfirmed
GUEST, unregistred user!
数据库某表更新后怎样才能马上通知应用程序?
我的需求是:当A表有新数据后,马上计算,然后产生一个消息(就是字符串),发送给a程序,由a程序去处理这个消息(字符串)。如果用a程序循环不断去提那个消息,太浪费系统资源,而且数据量很大,所以暂时不采用这种方式。
另外那个消息可能是不断产生,所以是不断发送给a程序哦!
已经做过测试有:
1、在触发器中写上exec xp_cmdshell 'b.exe' 来触发b程序,在b程序中用SENDMESSAGE给a程序,a程序接收不到(b程序是执行了,但没界面,来回折腾不知能不能挺住)。
2、扩展存储过程,不知道是写得不对还是怎样,在触发器里调用后,也发送不了消息。
3、COM组件,跟扩展存储过程一个样,SendMessage没有,主要是FindWindow不到那个a程序

function TMyXrhCom.SendMsg(const aCaption: WideString): WideString;
var
hwq:HWND;
begin
Result := '';
hwq := FindWindow(nil, Pchar(aCaption)); //就是这里找不到,不知COM里用什么
if hwq <> 0 then
begin
PostMessage(hwq,WM_CLOSE,0,0);
Result := aCaption;
end;
end;


那位大哥,救救小妹啊!!!!!!![:(][:(][:(][:(][:(][:(]
要我这个COM组件调试的留下QQ,或加我QQ :58413709


一、建一个COM

unit ComFrm;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
ComObj, ActiveX, MYCOM_TLB, StdVcl;

type
TMyXrhCom = class(TAutoObject, IMyXrhCom)
protected
function SendMsg(const aCaption: WideString): WideString; safecall;
{ Protected declarations }
end;

implementation

uses ComServ, Windows, Messages;

function TMyXrhCom.SendMsg(const aCaption: WideString): WideString;
var
hwq:HWND;
begin
Result := '';
hwq := FindWindow(nil, Pchar(aCaption));
FWindowHandle := AllocateHWnd(WndProc);
if hwq <> 0 then
begin
PostMessage(hwq,WM_CLOSE,0,0);//关闭打开的计算器
Result := aCaption;
end;
end;

initialization
TAutoObjectFactory.Create(ComServer, TMyXrhCom, Class_MyXrhCom,
ciMultiInstance, tmApartment);
end.

二、先用 Regsvr32命令注册:
如:Regsvr32 D:/古格软件(家具版)/Client/MYCOM.dll

三、再在查询分析器里SQL执行:

--工程名称: MyCOM
--类名: MyXrhCom

declare @err int,@src varchar(255),@desc varchar(255), @re varchar(255)
declare @obj int

--创建调用实例
exec @err=sp_OACreate 'MyCOM.MyXrhCom', @obj out
if @err<>0 goto lberr --如果创建失败,则进行错误处理

--调用DLL中的函数
exec @err=sp_OAMethod @obj,'SendMsg',@re out,'计算器'
if @err<>0 goto lberr --如果调用错误,则进行错误处理

print '返回的结果是:' + @re -- str(@re)

--完成后释放
exec sp_OADestroy @obj

return

lberr:
exec sp_oageterrorinfo 0,@src out,@desc out
select cast(@err as varbinary(4)) as 错误号, @src as 错误源,@desc as 错误描述
 
沉下去了,我顶我顶我顶我顶
 
变通下不知道能行不

在 数据库可用触发器 在另外一个 event 表 创建记录,即 记录下事件。
a程序增加 事件检查,定时查询这个 event表 若有事件发生,则进行处理。
 
不合理的需求,你的数据库如果频繁访问,这么大的流量非把服务器搞死不可.
 
不会服务器搞死,服务器买的好的[:D][:D]

实在搞不定,也只好用 rebirth 的方法了。
 
在 InterBase 、Firebird 中都可实现楼主的这个功能。
可在触发器中,或存储过程中发送一个消息。
可看 ibdac 控件包中这个列子。
 
TO:maxerp, 大哥,就没有SQL SERVER 2000的吗?
 
理论是可以的!但是很难!
其实这属于“企业信息队列”管理的问题,有专门的软件。
InterBase 、Firebird 是可以实现,但也只是通知本机的其他软件而已,InterBase 、Firebird 目前也主要是本地应用。
要想让网络上其他的计算机知道,涉及的问题很多。我提供一个思路:
1、sqlserver所在机器,放置一个程序,在触发器里可以调用它,而它可以与其他机器通讯
2、各个客户端,必须遵循某个协议或者实现某个接口;
3、可能还需要在数据库中放置全局信息
 
李维的insidevcl中好像提过,当时觉得没什么用就没仔细研究。
 
用个udp吧,post后发个信息过去
 
我顶我顶啊
 
可以的,不过这个方法是个漏洞,不好告诉你
 
1、"1、在触发器中写上exec xp_cmdshell 'b.exe' 来触发b程序,在b程序中用SENDMESSAGE给a程序,a程序接收不到(b程序是执行了,但没界面,来回折腾不知能不能挺住)。"
用这个方案改一下:
在触发器中写上exec xp_cmdshell 'b.exe' 来触发b程序,在b程序中用TCP连接a程序的TCP监听端口发送消息(a程序开TCP端口监听)。

2、在触发器中写上exec xp_cmdshell 'a.exe' 。
 
ding ding ding ding ding [:(][:(][:(]
 
可以问一句吗?

然后产生一个消息(就是字符串),发送给a程序,由a程序去处理这个消息(字符串)。

这里所谓的处理这个消息 是什么意思啊? 如果是只针对数据库里操作的话 可以考虑不用程序了 直接在服务器里执行

如果是要控制外部的东西的话,可能只有实时监听了 如果只是因为数据量大的话,可以做适当调整啊,比如rebirth 兄弟说的那样,再加上索引 处理一条删一条 应该就完全没问题的
 
哇,大散分啊
 
什麽控件啊。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部