在存储过程中调用外部的动态连接库(MS SQL Server7.0/2000环境)
2008-05-26 12:25
501 查看
问题的提出: 一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效 率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而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 |
相关文章推荐
- 如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- 收集到的:如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- 如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- MS SQL Server:存储过程实例
- 查询MS sql server里的所有表 SQL中所有列,说明,类型 查询总存储过程数
- MS SQL SERVER 存储过程小记!
- 用XML和SQL 2000来管理存储过程调用
- 用XML和SQL 2000来管理存储过程调用
- Java 环境中执行SQL命令和调用存储过程
- 在存储过程中调用外部的动态连接库
- MS SQL Server 分页存储过程
- 代码调用存储过程超时,SQL Server Management Studio里运行很快 (改进)
- MS SQL Server之光标、存储过程和触发器
- MS SqlServer海量数据分页存储过程收集
- MS sql server 判断表/视图/存储过程是否存在
- [转]C# 调用sql 2000存储过程
- MS SQL Server中数据表、视图、函数/方法、存储过程是否存在判断及创建
- MS SQL Server中数据表、视图、函数/方法、存储过程是否存在判断及创建
- 用XML和SQL 2000来管理存储过程调用
- CodeSmith 5.0工具实例篇系列3——根据表生成新增的存储过程,针对MS Sqlserver