[转]数据库的触发器trigger中如何执行socket操作

用户在执行insert,update,   delete操作后,用触发器可以捕获到。我把想变化的数据用socket传到另一台机器上去,数据库的触发器中如何执行socket操作? 
  编一dll,这个dll负责把变化的数据用socket传到另一台机器上去,然后在触发器中调用这个dll,调用的方法和dll的范例在这里:  
  在存储过程中调用外部的动态连接库(ms   sql   server7.0/2000环境)  
  作者:ac952_z_cn   
   问题的提出:  
  一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而master的存储过程中最好能调用外部的动态连接库,我们在触发器中调用master的存储过程即可。  
   
  下载源代码   大小:14k  
   
  说明:vc6需要安装较新的platform   sdk才能顺利编译本代码,vc.net可以直接编译本代码。另外还需要连接opends60.lib  
  为了使没有较新platform   sdk的朋友也能编译本例子,已经将vc.net中的srv.h和opends60.lib放到压缩包中  
   
  程序实现:  
  我们来实现一个存储过程中调用外部的dll(storeproc.dll)的函数setfilename和addline。  
   
  存储过程如下(需放到master库中):   create   procedure   sp_testdll   as  
   
  exec   sp_addextendedproc   setfilename,   storeproc.dll --声明函数  
  exec   sp_addextendedproc   addline,   storeproc.dll  
   
  declare   @szfilename   varchar(200)  
  declare   @sztext   varchar(200)  
  declare   @rt   int  
   
  select   @szfilename   =   c:\welcome.txt  
   
  exec   @rt   =   setfilename   @szfilename --调用setfilename函数,参数为--szfilename;  
  if   @rt   =   0  
  begin  
  select   @sztext   =   welcome   01  
  exec   @rt   =   addline   @sztext --调用addline  
  select   @sztext   =   welcome   02  
  exec   @rt   =   addline   @sztext  
   
  end  
  exec   sp_dropextendedproc   setfilename  
  exec   sp_dropextendedproc   addline  
   
  dbcc   setfilename(free)  
  dbcc   addline(free)  
   
  动态连接库的实现:这种动态连接库和普通的有所不同。该动态连接库要放入sql的执行目录下,或直接放到window的system32目录下,并重起sql-server   #include   <windows.h>  
  #include   <srv.h> //要加入这个.h文件  
   
  #define   xp_noerror             0  
  #define   xp_error                 1  
   
  #ifndef   _debug  
  #define   _debug  
  #endif  
   
  char   szfilename[max_path+1];  
   
  void   writeinfo(const   char   *   str);  
   
  extern   "c"   srvretcode   winapi   setfilename(srv_proc*   psrvproc)  
  {  
  writeinfo("setfilename   start");  
  int   paramcount   =   srv_rpcparams(psrvproc);  
  if   (paramcount   !=   1){  
  writeinfo("param   err   start");  
  return   xp_error;  
  }  
   
  byte btype;  
  unsigned   long cbmaxlen;  
  unsigned   long cbactuallen;  
  bool fnull;  
   
  int   ret   =   srv_paraminfo(psrvproc,   1,   &btype,   &cbmaxlen,   &cbactuallen,  
                  null,   &fnull);  
  if   (cbactuallen){  
  zeromemory(szfilename,   max_path+1);  
  memcpy(szfilename,   srv_paramdata(psrvproc,   1),   cbactuallen);  
  writeinfo("set   filename   ok");  
  return   (xp_noerror);  
  }  
  else   {  
  writeinfo("set   filename   param   failed");  
  return   xp_error;  
  }  
  }  
   
  extern   "c"   srvretcode   winapi   addline(srv_proc*   psrvproc)  
  {  
  writeinfo("addline   start");  
  int   paramcount   =   srv_rpcparams(psrvproc);  
  if   (paramcount   !=   1){  
  writeinfo("addline   param   err");  
  return   xp_error;  
  }  
   
  byte                 btype;  
  unsigned   long cbmaxlen;  
  unsigned   long cbactuallen;  
  bool fnull;  
  bool rt   =   false;  
   
  int   ret   =   srv_paraminfo(psrvproc,   1,   &btype,   &cbmaxlen,   &cbactuallen,  
                  null,   &fnull);  
   
  if   (cbactuallen){  
  int   n;  
  char   srt[3]   =   {0x0d,   0x0a,   0};  
   
  char   *   c   =   new   char[cbactuallen   +   3];  
  if   (!c)return   xp_error;  
   
  zeromemory(c,   cbactuallen   +   3);  
  memcpy(c,   srv_paramdata(psrvproc,   1),   cbactuallen);  
  memcpy(c+cbactuallen,   srt,   3);  
   
  handle   hf   =   createfile(szfilename,   generic_write,   file_share_write|file_share_read,   null,    
                      open_always,   0,   null);  
  if   (hf   ==   invalid_handle_value){  
  writeinfo("addline   create   file   err   ");  
  delete   []c;  
  return   xp_error;  
  }  
   
  writeinfo("addline   create   file   ok   ");  
  dword   dwwt;  
  n   =   strlen(c);  
  setfilepointer(hf,   0,   null,   file_end);  
  if   (writefile(hf,   c,   n,   &dwwt,   null)   &&   dwwt   ==   n)  
  {  
  writeinfo("addline   write   file   ok   ");  
  rt   =   true;  
  }  
  delete   []c;  
  closehandle(hf);  
  }  
  return   rt   ?   xp_noerror:xp_error;  
  }  
   
  inline   void   writeinfo(const   char   *   str){  
          #ifdef   _debug  
  char   srt[3]   =   {0x0d,   0x0a,   0};  
  handle   hf   =   createfile("c:\\storeproc.log",   generic_write,   file_share_write|file_share_read,   null,    
                      open_always,   0,   null);  
  if   (hf   !=   invalid_handle_value){  
  setfilepointer(hf,   0,   null,   file_end);  
  dword   dwwt;  
  writefile(hf,   str,   strlen(str),   &dwwt,   null);  
  writefile(hf,   srt,   strlen(srt),   &dwwt,   null);  
  closehandle(hf);  
  }  
  else   {  
  messagebox(null,   "write   info   err",   "message",   mb_ok|mb_iconinformation);  
  }  
  #endif  
  }  
   
  bool   winapi   dllmain(hinstance   hinstdll,dword   fdwreason,lpvoid   lpreserved)  
  {  
  return   true;  
  }  
   
  编译完成后,把动态链接库放到winnt/system32目录下,启动sql   server。我们可以打开sql   server   query   analyzer调用存储过程sp_testdll以测试其运行是否正确。  
   
  具体可参考sql-server的在线帮助。  
  笔者环境:win2000   professional   +   sql-server7.0(2000也可)  
  vc6.0+sp5+platform   sdk   20001.8  
   
  vc知识库测试环境:win2000   professional   +   sql-server   7.0   +   vc.net  

posted on 2012-09-28 14:49  和轩僮  阅读(1018)  评论(0编辑  收藏  举报

导航