在存储过程中调用外部的动态连接库(MS SQL Server7.0/2000环境)
来源:互联网 发布:淘宝漏肩装舞蹈服 编辑:程序博客网 时间:2024/04/20 21:50
问题的提出:
一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效 率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而master的存储过程中最好能调用外部的动态连接库, 我们在触发器中调用master的存储过程即可。
下载源代码 大小:14K
说明:VC6需要安装较新的Platform SDK才能顺利编译本代码,VC.Net可以直接编译本代码。另外还需要连接Opends60.lib
为了使没有较新Platform SDK的朋友也能编译本例子,已经将VC.Net中的Srv.h和Opends60.lib放到压缩包中
程序实现:
我们来实现一个存储过程中调用外部的dll(storeproc.dll)的函数SetFileName和addLine。
存储过程如下(需放到master库中):
具体可参考SQL-Server的在线帮助。
笔者环境:win2000 professional + SQL-Server7.0(2000也可)
VC6.0+SP5+Platform SDK 20001.8
VC知识库测试环境:win2000 professional + SQL-Server 7.0 + VC.Net
一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效 率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而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动态连接库的实现:这种动态连接库和普通的有所不同。该动态连接库要放入SQL的执行目录下,或直接放到Window的System32目录下,并重起SQL-Server
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)
#include <windows.h>编译完成后,把动态链接库放到WINNT/System32目录下,启动SQL Server。我们可以打开SQL Server Query Analyzer调用存储过程sp_testdll以测试其运行是否正确。
#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;
}
BYTEbType;
unsigned longcbMaxLen;
unsigned longcbActualLen;
BOOLfNull;
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 longcbMaxLen;
unsigned longcbActualLen;
BOOLfNull;
boolrt = 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;
}
具体可参考SQL-Server的在线帮助。
笔者环境:win2000 professional + SQL-Server7.0(2000也可)
VC6.0+SP5+Platform SDK 20001.8
VC知识库测试环境:win2000 professional + SQL-Server 7.0 + VC.Net
- 在存储过程中调用外部的动态连接库(MS SQL Server7.0/2000环境)
- 在存储过程中调用外部的动态连接库
- 在存储过程中调用外部的动态连接库
- jsp连接Sql Server7.0/2000数据库
- jsp连接Sql Server7.0/2000数据库
- 在易语言中调用MS SQL SERVER数据库存储过程(Transact-SQL)方法总结
- 在动态SQL语句中调用存储过程
- oracle动态sql:存储过程中动态调用存储过程,并且动态调用的存储过程出参数游标
- JAVA中使用JDBC调用MS SQL存储过程
- 使用JTDS调用MS SQL Server 2005的存储过程
- 在存储过程中动态的创建连接服务器
- 关于在PB中动态调用ORACLE的存储过程
- 收集到的:如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- VB6远程调用MS SQL 存储过程
- PHP调用MS SQL 存储过程
- 如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- 在vb.net编写的应用程序中取得由MS-SQL存储过程产生的值
- 在SQL Server的存储过程中调用Com组件
- 一直拖拉欠没做完的事情
- 项目经理的工具箱---走出软件作坊:三五个人十来条枪 如何成为开发正规军(三)
- HTML代码注释
- this is my first login
- JTable中随意位置插入列
- 在存储过程中调用外部的动态连接库(MS SQL Server7.0/2000环境)
- Linux 添加系统字体
- 求用VB和AXXESS做的学生上机数据库
- 地震救灾急速拉近中日民间情感 超乎所有人预料
- 关于魔兽世界demo
- js asp.net幻灯片
- Client Side Validation of GridView control with javascript
- asp.net里导出excel表方法汇总
- jS循环图片