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

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

概述问题的提出: 一般我们要根据数据库的纪录变化时,进行某种 *** 作。我们习惯的 *** 作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而master的存储过程中最好能调用外部的动态连接库,我们在触发器中调用master的存储过程即可。 下载源代码 http://www.vckbase. 问题的提出:
一般我们要根据数据库的纪录变化时,进行某种 *** 作。我们习惯的 *** 作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而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);
总结

以上是内存溢出为你收集整理的在存储过程中调用外部的动态连接库全部内容,希望文章能够帮你解决在存储过程中调用外部的动态连接库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1182053.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存