想利用触发器调用存储过程,再由存储过程调用外部程序!急!急!急!请大家帮忙,谢谢!

解决方案 »

  1.   

    libin_ftsafe(子陌红尘:当libin告别ftsafe) ,能说详细点吗?xp_cmdshell是做什么用的,具体怎么用?本人对这部分不是很明白,谢谢!
      

  2.   

    使用master..xp_cmdshell 就如使用DOS环境一样,可以使用DOS中的大多少命令.
      

  3.   

    如果要调用外部程序,可以使用xp_cmdshell这个扩展存储过程,具体使用方法参阅联机帮助。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 @objreturnlberr:
    exec sp_oageterrorinfo 0,@src out,@desc out
    select cast(@err as varbinary(4)) as 错误号
    ,@src as 错误源,@desc as 错误描述
      

  4.   

    如果楼主要调用的外部程序不是COM组件,只是DLL里面的函数,可以将改DLL添加为扩展存储过程.扩展存储过程与普通存储过程一样,执行方法也相同。例如:添加扩展存储过程
    sp_addextendedproc [ @functname = ] 'procedure' ,
        [ @dllname = ] 'dll'
    参数
    [ @functname = ] 'procedure'
    在动态链接库 (DLL) 内调用的函数名称。procedure 的数据类型为 nvarchar(517),没有默认设置。procedure 能够可选地包含 owner.function 形式的所有者名称。[ @dllname = ] 'dll'
    包含该函数的 DLL 名称。dll 的数据类型为 varchar(255),没有默认设置。下例添加 xp_hello 扩展存储过程。
    USE master
    EXEC sp_addextendedproc xp_hello, 'xp_hello.dll'
    ------------------------------------------------------------------------------------
    除去扩展存储过程:
    sp_dropextendedproc [ @functname = ] 'procedure' 
    参数
    [@functname =] 'procedure'
    将要除去的扩展存储过程的名称。procedure 的数据类型为 nvarchar(517),没有默认值。下面的示例除去扩展存储过程。
    USE master
    EXEC sp_dropextendedproc 'xp_hello'
      

  5.   

    sp_oacreate...及相关系统存储过程.
      

  6.   

    hellowork(一两清风),请问安装你的实现方法,存储过程如何能找到xp_hello.dll,参数中没有关于dll的路径设置,请帮忙说明,谢谢!
      

  7.   

    写DLL的全路径名就行了,例如:
    USE master
    EXEC sp_addextendedproc xp_hello, 'c:\myprogram\xp_hello.dll'扩展存储过程都被添加到master数据库中,所以在使用时使用master..xp_hello格式调用.
      

  8.   

    调用dll实质是什么,实质也就是使用dll提供的接口,即dll提供的对象属性方法.
    调用了dll自然也就可以调用dll里的函数.
      

  9.   

    libin_ftsafe(子陌红尘:当libin告别ftsafe),如果我想调用d:\yy.exe,按照以下方式总不成功,其中yy.exe为VC开发的exe :use master
    exec xp_cmdshell 'd:\yy.exe'
      

  10.   

    hellowork(一两清风),再问一下带参数传递的dll调用1 带函数返回值的dll调用成功
      use master
      exec sp_addextendedproc fun,'C:\Documents and Settings\Administrator\桌面\dlltest\dll\Debug\dll.dll' declare @yy int
     exec @yy=master..fun
      select @yy以上执行完毕,返回值100,成功了!2 带参数传递的dll调用,dll中的函数fun实现的功能,
    extern "C" __declspec(dllexport) int fun(int x1,int x2,int x3)
    {
      return x1+x2+x3;
    }--以下SQl中的
    use master
    exec sp_addextendedproc fun(@x1 int,@x2 int,@x3 int),'C:\Documents and Settings\Administrator\桌面\dlltest\dll\Debug\dll.dll'declare @yy int,@y1 int,@y2 int,@y3 int
    set @y1=1
    set @y2=2
    set @y3=3
    exec @yy=master..fun @y1, @y2,@y3
    select @y1,@y2,@y3
    select @yy能够成功执行,但返回值为423498429,不是6(1+2+3)
    请帮忙,怎么使得带参数传递的dll调用成功,谢谢!
      

  11.   

    用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" {
    #endifRETCODE __declspec(dllexport) xp_proc5(SRV_PROC *srvproc);#ifdef __cplusplus
    }
    #endifRETCODE __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 ;
    }
      

  12.   

    编译好后,添加到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'
      

  13.   

    suntt(两条腿的狗),您的例子有点复杂,看起来不太明白,不过还是要谢谢您的帮助!
      

  14.   

    suntt(两条腿的狗),能不能就我的例子修正一下,找出问题,谢谢
      

  15.   

    在写扩展存储过程时微软提供了具体的dll格式的。
    我以vc.net为例
    先新建一个项目,选择visual c++项目中的常规,选择
    “扩展存储过程 DLL”即可。
    在vc6中也有详细的模版,你只要按照模版写自己的函数即可。
    (delphi)中可能也有具体模版,我见过一朋友写过
      

  16.   

    另,想获取更多的有关编写扩展存储的信息,你可以到
    msdn中查询 “extended stored procedures” 能获取详细信息。
      

  17.   

    这样安全吗? SQL文档里提到如果DLL有问题,可能破坏SQL数据??