要求是这样的:这个service时时监控着数据库,一旦有新的数据插入,则service立即处理新插入的数据。我该从何入手呢?有这方面的资料也给我发一分。多谢了

解决方案 »

  1.   

    提供如下建议:1。编写win32 服务程序,这的在网上找资料,但涉及数据库重连及其它异常处理,感觉不如下面
    2。另一中方式写个trigger程序,insert后处理的方式,这种方式把处理权交给数据库,应该更加实时和稳定
      

  2.   

    写个服务就可以了:
    SERVICE_STATUS          MyServiceStatus; 
    SERVICE_STATUS_HANDLE   MyServiceStatusHandle; 
     
    VOID  MyServiceStart (DWORD argc, LPTSTR *argv); 
    VOID  MyServiceCtrlHandler (DWORD opcode); 
    DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv, 
            DWORD *specificError); 
     
    void main( ) 

        SERVICE_TABLE_ENTRY   DispatchTable[] = 
        { 
            { "MyService", MyServiceStart      }, 
            { NULL,              NULL          } 
        }; 
     
        if (!StartServiceCtrlDispatcher( DispatchTable)) 
        { 
            SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error = 
                %d\n", GetLastError()); 
        } 

     
    VOID SvcDebugOut(LPSTR String, DWORD Status) 

        CHAR  Buffer[1024]; 
        if (strlen(String) < 1000) 
        { 
            sprintf(Buffer, String, Status); 
            OutputDebugStringA(Buffer); 
        } 

      

  3.   

    利用vc提供的向导写一个服务,然后在服务中利用trigger实现对数据库的监控
      

  4.   

    /////////////////////////////////////////////////////////////
    // service.cpp 创建service #include "service.h"
    #include "CopyRightSafe.h"#include "windows.h"
    #include "string.h"
    #include "stdio.h"
    #include "Windowsx.h"
    #include "resource.h"
    #include "Shellapi.h"
    //////////////////////
    // NT service 的成员
    VOID  WINAPI ServiceMain(DWORD argc,LPTSTR *argv); // service的入口地址
    VOID  WINAPI ServiceCtrlHandler(DWORD dwControl);  // server的控制函数
    SERVICE_STATUS          ServiceStatus; 
    SERVICE_STATUS_HANDLE   ServiceStatusHandle; 
    HINSTANCE g_hInstance;
    int g_iWhichIcon ;////////////////////////////////////////////////////////////////////////////////
    /////////////////////// /    NT service 程序实体部分   /////////////////////////
    ////////////////////////////////////////////////////////////////////////////////// First Implement main function,this is server's main thread
    int main( int argc, char** argv )
    {
    // The SERVICE_TABLE_ENTRY structure is used by the StartServiceCtrlDispatcher function 
    // to specify the ServiceMain function for a service that can run in the calling process. 
        SERVICE_TABLE_ENTRY DispatchTable[] = { { "ExceptionService", ServiceMain}, {NULL,NULL}};

        if ( (argc > 1) && (!( stricmp(argv[1], "-i") )) )//stricmp 字符串比较
    {
            char szBuffer[255];
            char szPath[MAX_PATH];        SC_HANDLE scmHandle = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
            if (scmHandle == NULL) // Perform error handling.
            {
                //sprintf( g_Msg, "IHISSERVICE_ANFANG OpenSCManager error = %d\n", GetLastError() ); 
                //WriteInLogFile(g_Msg);
            }

    GetModuleFileName( GetModuleHandle(NULL), szPath, MAX_PATH );
            strcpy( szBuffer, "\"" );
            strcat( szBuffer, szPath );
            strcat( szBuffer, "\"" ); printf( "CreateService succeed ! ServerName is ExceptionService !\nServer's path is %s\n", szPath );

    //创建server("HelloService")
    SC_HANDLE scHandle;
    scHandle = CreateService (
    scmHandle, 
    "ExceptionService", // server的名字 
                "ExceptionService", // server的显示名字
    SERVICE_ALL_ACCESS,   // 返回所有的功能
                SERVICE_WIN32_OWN_PROCESS, //
                SERVICE_AUTO_START, 
                SERVICE_ERROR_NORMAL,
    // LpBinaryPathName指明Service本体程序的路径名,
    // 是一个可执行的EXE文件名 +  路径名,是server的运行实体
                szBuffer,
    NULL, NULL, NULL, NULL, NULL );
            if ( scHandle == NULL ) 
            {
    //sprintf(g_Msg, "IHISSERVICE_ANFANG CreateService error! " ); 
    //WriteInLogFile(g_Msg);
            }
            else
    {
    //sprintf(g_Msg, "IHISSERVICE_ANFANG CreateService succeed! " ); 
    //WriteInLogFile(g_Msg);
    }
            CloseServiceHandle(scHandle);
            CloseServiceHandle(scmHandle);
        }//  end of create service
     //  delete service!
    else if ( argc > 1 && !( stricmp(argv[1], "-u" ) ) ) // Uninstall the Service
        {
            SC_HANDLE scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);

            if (scmHandle == NULL) // Perform error handling.
            {
                //sprintf(g_Msg, "IHISSERVICE_ANFANG  OpenSCManager error = %d\n", GetLastError() ); 
                //WriteInLogFile(g_Msg);
            }
           else
    {
    SC_HANDLE scHandle;
    scHandle = OpenService( scmHandle, "ExceptionService", SERVICE_ALL_ACCESS );
    DeleteService( scHandle );
                printf("ExceptionService UNINSTALLED SUCCEED!\n");
    }
        } // end of delete service

    // start service
    else if ( argc > 1 && !( stricmp(argv[1], "-k" ) ) ) // start the Service(k—开始)
    {
    SC_HANDLE scmHandle = OpenSCManager (NULL, NULL,  SC_MANAGER_CONNECT/*允许连接到service control manager database*/); if ( scmHandle != NULL )
    {
    //Enables calling of the StartService function to start the service.          
    SC_HANDLE scHandle=OpenService(scmHandle,"ExceptionService",SERVICE_START );
    if ( scHandle != NULL )
    {
    //start Service
    StartService ( 
    scHandle,// 为指向Service的句柄,由OpenService返回
    0,       // 为启动服务所需的参数的个数
    NULL     // 为 启 动 服务所需的参数
    );
    printf("START SERVICE SUCCEEDS !\n");
    }
    CloseServiceHandle(scHandle);
    }
    CloseServiceHandle(scmHandle);
    } // end of start service
    // stop the service
    else if ( argc > 1 && !( stricmp(argv[1], "-t" ) ) ) // stop the Service (t—停止)
    {
    SC_HANDLE scmHandle = OpenSCManager (NULL, NULL,  SC_MANAGER_CONNECT/*允许连接到service control manager database*/);

    if ( scmHandle != NULL )
    {
    //Enables calling of the StartService function to start the service.          
    SC_HANDLE scHandle=OpenService(scmHandle,"ExceptionService",SERVICE_STOP|SERVICE_QUERY_STATUS );
    if ( scHandle != NULL )
    {
    QueryServiceStatus(scHandle,&ServiceStatus);              // 查询server的状态
    if (ServiceStatus.dwCurrentState==SERVICE_RUNNING)
    {
    ControlService(scHandle,SERVICE_CONTROL_STOP,&ServiceStatus);
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);// update service status
    }
    printf("STOP SERVICE SUCCEEDS \n!");
    }
    CloseServiceHandle(scHandle);
    }
    CloseServiceHandle(scmHandle); } // end of stop the service
    else
    {
    //sprintf( g_Msg, "StartServiceCtrlDispatcher()...\n" );
    //WriteInLogFile(g_Msg);

    if ( !StartServiceCtrlDispatcher(DispatchTable) ) 

    //sprintf( g_Msg,"IHISSERVICE_ANFANG StartServiceCtrlDispatcher error = %d\n", GetLastError() ); 
    //WriteInLogFile(g_Msg);
    }
    else
    {
    //sprintf( g_Msg,"IHISSERVICE_ANFANG StartServiceCtrlDispatcher succeed! " ); 
    //WriteInLogFile(g_Msg);
    }
    }
    return 0;
    }//end of main()


    if (!SetProcessWindowStation(hwinstaCurrent))
    {
    return FALSE;
    }
    if (!SetThreadDesktop(hdeskCurrent))
    {
    return FALSE;
    }
    if (!CloseWindowStation(hwinsta))
    {
    return FALSE;
    }
    if (!CloseDesktop(hdesk))
    {
             return FALSE;
    }  return true;
    }

      

  5.   

    续// Second function to implement
    VOID WINAPI ServiceMain( DWORD argc, LPTSTR *argv ) 

        ServiceStatus.dwServiceType             = SERVICE_WIN32_OWN_PROCESS  ; 
        ServiceStatus.dwCurrentState            = SERVICE_START_PENDING; //server处于正在启动状态
        ServiceStatus.dwControlsAccepted        = SERVICE_ACCEPT_STOP /*| SERVICE_ACCEPT_PAUSE_CONTINUE*/ , 
    ServiceStatus.dwWin32ExitCode           = 0; 
        ServiceStatus.dwServiceSpecificExitCode = 0; 
        ServiceStatus.dwCheckPoint              = 0; 
        ServiceStatus.dwWaitHint                = 0; 

    // 在ServiceMain()中应该立即调用RegisterServiceCtrlHandler()注册一个Handler去处理控                             
    ServiceStatusHandle = RegisterServiceCtrlHandler( "ExceptionService", ServiceCtrlHandler ); 
        
    // 判断注册信息
    if ( ServiceStatusHandle == (SERVICE_STATUS_HANDLE) 0 ) //(SERVICE_STATUS_HANDLE) 0 :类型转换
        { 
    if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)) 

    sprintf(g_Msg,"IHISSERVICE_ANFANG SetServiceStatus error %ld\n", GetLastError() ); 
    WriteInLogFile( g_Msg );

    return; 
        } 
        else
    {         
    if( !m_WriteLog.create() )   // 创建写日志的守护线程
    {
    MessageBox(NULL,"创建日至线程失败,服务不能运行","安防服务提示",0 | 0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    return; 
    }
        
    Sleep(2000); ulDogHandle = 0;
        ulRet = CopyRightSafe_Login(ulDogHandle);
        if ( ulRet == 0 )
    {
             ulRet = CopyRightSafe_GetLicenseEnable(ulDogHandle, LicenseNumber, MaxLicenseNumber, AddLicenseNumber, MaxAddLicenseNumber);
             if ( ulRet == 1 )
     {
              ulRet = CopyRightSafe_DownLicenseNumber(ulDogHandle);
              if ( ulRet == 0 )
      {
      }
              else
      {
                   MessageBox(NULL,"读取加密狗工作次数失败,服务不能运行","故障服务提示",MB_OK | 0x00200000L);
       ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
                   SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
       AddLogtoQ("读取加密狗工作次数失败,服务不能运行");
       return; 
      }

              ZeroMemory(inikey, 8);
              ulRet = CopyRightSafe_GetServiceINIKey(ulDogHandle, inikey);
              if ( ulRet == 0 )
      {               
      }
              else
      {
      MessageBox(NULL,"读取加密狗密钥1失败,服务不能运行","故障服务提示",MB_OK |  0x00200000L);
      ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
      SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
      AddLogtoQ("读取加密狗密钥1失败,服务不能运行");
      return; 
      }

              ZeroMemory(basickey, 8);
              ulRet = CopyRightSafe_GetBasicKey(ulDogHandle, basickey);
              if ( ulRet == 0 )
      { 
                   
      }
              else
      {
      MessageBox(NULL,"读取加密狗密钥2失败,服务不能运行","故障服务提示",MB_OK |  0x00200000L);
      ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
      SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
      AddLogtoQ("读取加密狗密钥2失败,服务不能运行");
      
      return; 
      }

              ZeroMemory(comkey, 8);
              ulRet = CopyRightSafe_GetInitTempKey(ulDogHandle, comkey);
              if ( ulRet == 0 )
      {
                   
      }
              else
      {
      MessageBox(NULL,"读取加密狗密钥3失败,服务不能运行","故障服务提示",MB_OK |  0x00200000L);
      ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
      SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
      AddLogtoQ("读取加密狗密钥2失败,服务不能运行");
      
      return; 
      }   
     }   
             else
     {
     MessageBox(NULL,"读取加密狗失败,软件不能运行!","故障服务提示",MB_OK |  0x00200000L );
     ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
     SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
     AddLogtoQ("读取加密狗失败,软件不能运行");
     return; 
     }
    }
        else
    {
    MessageBox(NULL,"没有找到加密狗,软件不能运行!","ExceptionService提示信息",MB_OK |  0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    AddLogtoQ("没有找到加密狗,软件不能运行");
    return; 
    }
        }

    GetINIData();
        if (servername.IsEmpty() || dbname.IsEmpty() || administratorname.IsEmpty() || loginpwd.IsEmpty() || NoQued==0||PortNum==0 || administratropwd=="AdministratorPWD Error" ||loginname.IsEmpty()   )    
    {
    MessageBox(NULL,"读取系统配置文件错误,软件不能运行!","故障服务提示",MB_OK |  0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    AddLogtoQ("读取系统配置文件错误,软件不能运行!");

    return; 
    }    CString str = "Provider=SQLOLEDB.1;Password="+ loginpwd+";Persist Security Info=True;User ID=" + loginname + ";Initial Catalog=" + dbname + ";Data Source=" +  servername ; 
    strConnection = str; 

    // socket部分
    WSADATA wsadata;
    int wsaret=WSAStartup(0x202,&wsadata);
    if(wsaret)
    {
    MessageBox(NULL,"初始化SOCKET错误,软件不能运行!","故障服务提示",MB_OK |  0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    AddLogtoQ("初始化SOCKET错误,软件不能运行!");

    return; 
    }

    ServerSocket   server;
    server.setnoQued (NoQued);
    if ( !server.open(PortNum) )
    {
    MessageBox(NULL,"初始化服务器IP地址错误,软件不能运行!","故障服务提示",MB_OK |  0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    AddLogtoQ("初始化服务器IP地址错误,软件不能运行!");
    return;
    }

    createSocket = NULL;
    handler      = NULL;  
    createSocket = new CreateSocketHandlerImpl();
    handler      = new ServerSocketHandler;
    handler->setServerSocket(server);
    handler->setCreateSocketHandler((CreateSocketHandler *)createSocket);
    if(handler->create())
    {

    }
    else
    {
    MessageBox(NULL,"创建于客户端的通讯器失败,软件不能运行","故障服务提示",MB_OK |  0x00200000L);
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    AddLogtoQ("创建于客户端的通讯器失败,软件不能运行");
    return ;
    }

    // 第三部分:创建守护线程
    if( !m_processAlarm.create() )              // 创建处理报警信息的线程
    {
           ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
        string str = "创建守护线程失败";
    AddLogtoQ(str);
    return;
    } if(!m_filemappingprocee.create())          // 创建文件映射守护线程  
    {
           ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
        string str = "创建文件映射线程失败";
    AddLogtoQ(str);
    return;
    }

    ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
        if ( !SetServiceStatus( ServiceStatusHandle, &ServiceStatus ) ) 
        { 
    // 注册系统当前的状态,处理错误情况
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
    return; 
        } 
    AddLogtoQ( "成功启动故障报警服务");
        g_isRunning = true;

        // 创建任务栏图标的接收窗口
        AddTrayIconWindows(); while (1)
        {

    Sleep(100); if ( !g_isRunning )
            {
                break;
            }
        }
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
        SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

    return; 

      

  6.   

    续// 接受service的控制命令
    VOID WINAPI ServiceCtrlHandler(DWORD dwControl)

       switch(dwControl) 
        {      
            case SERVICE_CONTROL_STOP: 
                ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING; 
         
    m_processAlarm.release();               
                m_filemappingprocee.release();
    handler->release();
    m_sockImpl.Del();   
                
    ulRet = CopyRightSafe_Logout(ulDogHandle);
    if ( ulRet != 0 )
    {
    MessageBox(NULL,"加密狗异常退出!","服务提示",0 |  0x00200000L);
    AddLogtoQ("加密狗异常退出");
    }   
    delete []comkey;
    comkey = NULL;
    delete []inikey;   
    inikey = NULL;
    delete []basickey; 
    basickey = NULL; AddLogtoQ("成功关闭故障报警服务");
       m_WriteLog.release();                   
    g_isRunning = false;
    ServiceStatus.dwCurrentState  = SERVICE_STOPPED;

    break; 

    default: 
    break;
        } //end of switch()    // Send current status. 
        if ( !SetServiceStatus(ServiceStatusHandle, &ServiceStatus) ) 
        { 
        } 
        return; 

      

  7.   

    看看这本书吧programming server side application for windows 
    里面有怎么做一个Service
      

  8.   

    我也认为写个触发器最好,用service太繁琐
      

  9.   

    trigger吧
    数据库的问题让他自己解决,这就是典型的有容易的不用,非要用华丽的...
      

  10.   

    研究一下数据库里面怎么调用DLL文件的函数吧。