首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

*怎么用sqlserver存储过程调用Dll动态链接库文件

2012-01-14 
*高手请进*如何用sqlserver存储过程调用Dll动态链接库文件1、用于sqlserver存储过程调用的dll在编写时要尊

*高手请进*如何用sqlserver存储过程调用Dll动态链接库文件
1、用于sqlserver存储过程调用的dll在编写时要尊守那些标准吗?
2、在SQL   server里用   sp_addextendproc   和用   sp_OAcreate   调用DLL有那些区别,分别在什么时候用到
3、能否用个VC代码的小例子写个DLL,代码请贴出来,还有sqlserver调用的例子

不胜感激!


[解决办法]
--參考:

SQL Server对于调用dll要求比较严格,基本的思路是编写dll,创建调用该dll的扩展存储过程,调用扩展存储过程。以下是转贴大斑竹zjcxc的一个帖子,希望能对你有所帮助:

**********************************************************************************************************************

扩展DLL好像是要用VC编写,而且有一定要求,具体地参考SQL联机帮助

另一种是编写ole,参考下面的VB代码及调用示例

--SQL Server的存储过程调用Com组件


/*--下面的部分在VB中完成

首先我们先用VB 作一个最简单的组件

工程名称: testSQLCOM
类名: TestMath

'函数,计算两个整数相加的结果
Public Function AddMe(a As Long, b As Long) As Long
AddMe = a + b
End Function

编译生成后,我们就可以在 Sql Server 中对这个 Com 组件进行调用了
--*/

/*--下面是SQL中对上面DLL的调用--*/

--定义用到的变量
declare @err int,@src varchar(255),@desc varchar(255)
declare @obj int,@re int

--创建调用实例
exec @err=sp_OACreate 'testSQLCOM.TestMath ', @obj out
if @err <> 0 goto lberr --如果创建失败,则进行错误处理

--调用DLL中的函数
exec @err=sp_OAMethod @obj, 'AddMe ',@re out,100,200
if @err <> 0 goto lberr --如果调用错误,则进行错误处理

print '返回的结果是: ' + str(@re)

--完成后释放
exec sp_OADestroy @obj

return

lberr:
exec sp_oageterrorinfo 0,@src out,@desc out
select cast(@err as varbinary(4)) as 错误号
,@src as 错误源,@desc as 错误描述

[解决办法]
--例子:
******************************************************
作者: suntt(两条腿的狗)
******************************************************

用vc写dll,然后使用sp_addextendedproc 添加扩展的存储。
给一个过去曾经写的一个扩展存储:

/*根据指定的IP地址返回网卡的Mac地址*/

#include <stdafx.h>
#include "stdio.h "
#include "stdlib.h "
#include "Winsock2.h "
#include "iphlpapi.h "

#pragma comment ( lib, "ws2_32.lib " )
#pragma comment ( lib, "Iphlpapi.lib " )

#define XP_NOERROR 0
#define XP_ERROR 1
#define MAXCOLNAME 25
#define MAXNAME 255
#define MAXTEXT 255

#ifdef __cplusplus
extern "C " {
#endif

RETCODE __declspec(dllexport) xp_proc5(SRV_PROC *srvproc);

#ifdef __cplusplus
}
#endif

RETCODE __declspec(dllexport) xp_proc5(SRV_PROC *srvproc)
{

DBSMALLINT i = 0;
DBCHAR colname[MAXCOLNAME];
DBCHAR spText[MAXTEXT];
DBCHAR spIP[MAXTEXT];
DBCHAR spHostName[MAXTEXT];
DBCHAR spMac[18];
DBCHAR szFileName[MAX_PATH+1];

struct hostent *remoteHostent;
int numberOfHost = 1;
int nArgs = srv_rpcparams(srvproc);


if (nArgs> 0)
{
//初始化SOCKET
WSADATA wsaData;
int iRet = WSAStartup(MAKEWORD(2,1), &wsaData);
if ( iRet != 0 )
exit( 0 );

int paramCount=srv_rpcparams(srvproc);//检测参数个数
if(paramCount!=1)
{
return XP_ERROR;
}

BYTE bType;
unsigned long cbMaxLen;
unsigned long cbActualLen;
BOOL fNull;

int ret=srv_paraminfo(srvproc,1,&bType,&cbMaxLen,&cbActualLen,NULL,&fNull);

if (cbActualLen){
ZeroMemory(szFileName, MAX_PATH+1);
memcpy(szFileName, srv_paramdata(srvproc, 1), cbActualLen);
}
else{
return XP_ERROR;
}

int nRemoteAddr=inet_addr((const char*)szFileName);
_snprintf(spText, MAXTEXT, "%s 示例扩展存储过程 ", szFileName);
srv_sendmsg(
srvproc,
SRV_MSG_INFO,
0,
(DBTINYINT)0,
(DBTINYINT)0,
NULL,
0,
0,
spText,
SRV_NULLTERM);

remoteHostent= (struct hostent*)malloc( sizeof(struct hostent ));
struct in_addr sa;
for ( int i = 0; i < numberOfHost; i ++ )
{
//获取远程机器名
sa.s_addr = nRemoteAddr;
_snprintf( spIP,MAXTEXT, "%s\0 ",inet_ntoa( sa ) );//输出IP地址

remoteHostent = gethostbyaddr( (char*)&nRemoteAddr,4, AF_INET );
if ( remoteHostent )
_snprintf(spHostName,MAXTEXT, "%s\0 ",remoteHostent-> h_name);
else
_snprintf(spHostName,5, "null ");

//发送ARP查询包获得远程MAC地址
unsigned char macAddress[6];
ULONG macAddLen = 6;
iRet=SendARP(nRemoteAddr, (unsigned long)NULL,(PULONG)&macAddress, &macAddLen);
if ( iRet == NO_ERROR )
{
sprintf(spMac, "%02X-%02X-%02X-%02X-%02X-%02X ",macAddress[0],macAddress[1],macAddress[2],macAddress[3],macAddress[4],macAddress[5]);
}
else
sprintf(spMac, "null ");
nRemoteAddr = htonl( ntohl( nRemoteAddr ) + 1 );
}
}

//设置列名称
_snprintf(colname, MAXCOLNAME, "IP ");
srv_describe(srvproc, 1, colname, SRV_NULLTERM, SRVCHAR, MAXTEXT, SRVCHAR, 0, NULL);

_snprintf(colname, MAXCOLNAME, "HOSTNAME ");
srv_describe(srvproc, 2, colname, SRV_NULLTERM, SRVCHAR, MAXNAME, SRVCHAR, 0, NULL);

_snprintf(colname, MAXTEXT, "MAC ");
srv_describe(srvproc, 3, colname, SRV_NULLTERM, SRVCHAR, MAXTEXT, SRVCHAR, 0, NULL);

//读进数据
srv_setcoldata(srvproc, 1, spIP);
srv_setcollen(srvproc, 1, static_cast <int> (strlen(spIP)));
srv_setcoldata(srvproc, 2, spHostName);
srv_setcollen(srvproc, 2, static_cast <int> (strlen(spHostName)));
srv_setcoldata(srvproc, 3, spMac);
srv_setcollen(srvproc, 3, static_cast <int> (strlen(spMac)));

// 发送整行
srv_sendrow(srvproc);

// 现在返回已处理的行数
srv_senddone(srvproc, SRV_DONE_MORE | SRV_DONE_COUNT, (DBUSMALLINT)0, (DBINT)i);

return XP_NOERROR ;
}

******************************************


编译好后,添加到mssql中
sp_addextendedproc 'xp_proc5 ', 'dllpath '

调用方法:
xp_proc5 '10.50.0.1 ' --指定IP地址即可

返回效果:

IP HOSTNAME MAC
--------------------
10.50.80.22 sunshine 00-80-C8-EE-11-03

卸载的方法:
sp_dropextendedproc 'xp_proc5 '

热点排行
Bad Request.