加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

在存储过程中调用外部的动态连接库

发布时间:2020-12-12 15:09:06 所属栏目:MsSql教程 来源:网络整理
导读:问题的提出: 一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就
问题的提出:
一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而master的存储过程中最好能调用外部的动态连接库,我们在触发器中调用master的存储过程即可。


下载源代码?http://www.vckbase.com/document/journal/vckbase12/src/StoreProc.zip


说明: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,?&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,?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,?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,?0};
HANDLE?hf?=?CreateFile("c://storeproc.log",?NULL);
if?(hf?!=?INVALID_HANDLE_VALUE){
SetFilePointer(hf,?FILE_END);
DWORD?dwWt;
WriteFile(hf,?str,?strlen(str),?NULL);
WriteFile(hf,?strlen(srt),?NULL);
CloseHandle(hf);
}
else?{
MessageBox(NULL,?"Write?info?err",?"Message",?MB_OK|MB_ICONINFORMATION);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读