一般我们要根据数据库的纪录变化时,进行某种操作。我们习惯的操作方式是在程序中不停的查询表,判断是否有新纪录。这样耗费的资源就很高,如何提高这种效率,我想在表中创建触发器,在触发器中调用外部动态连接库通过消息或事件通知应用程序就可实现。而master的存储过程中最好能调用外部的动态连接库,我们在触发器中调用master的存储过程即可。
说明: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'' --声明函数 declare @szFileName varchar(200) Select @szFileName = ''c:/welcome.txt'' EXEC @rt = SetFileName @szFileName --调用SetFileName函数,参数为--szFileName; end dbcc SetFileName(free) |
动态连接库的实现:这种动态连接库和普通的有所不同。该动态连接库要放入SQL的执行目录下,或直接放到Window的System32目录下,并重起SQL-Server #include
#include //要加入这个.h文件 #define XP_NOERROR 0 #ifndef _DEBUG char szFileName[MAX_PATH+1]; void WriteInfo(const char * str); extern "C" SRVRETCODE WINAPI SetFileName(SRV_PROC* pSrvProc) BYTE bType; int ret = srv_paraminfo(pSrvProc, 1, &bType, &cbMaxLen, &cbActualLen, extern "C" SRVRETCODE WINAPI addLine(SRV_PROC* pSrvProc) BYTE bType; int ret = srv_paraminfo(pSrvProc, 1, &bType, &cbMaxLen, &cbActualLen, if (cbActualLen){ char * c = new char[cbActualLen + 3]; ZeroMemory(c, cbActualLen + 3); HANDLE hf = CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, WriteInfo("addline create file ok "); inline void WriteInfo(const char * str){ BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved) |
编译完成后,把动态链接库放到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