我做了一个服务程序,为什么在服务中无法使用SQL Server数据库阿?
程序结构如下:
主程序:负责启动网络服务模块
网络服务模块:负责分发消息
业务处理模块:调用数据模块
数据模块:使用SQL Server;//每次使用该模块就崩溃,但是在普通应用程序中调用没问题

解决方案 »

  1.   

    可以使用。要注意不少问题。如果你的服务是一启动就要运行sql server相关的模块,那需要设置你的服务依赖于mssqlserver服务(dependencies),并且在模块中最好增加检查sql server是否已启动的相应判断。如果有跟桌面交互的地方,如要显示窗口或者对话框什么的,service的Interactive需要设置为True
      

  2.   

    to 核桃:我一直找不到出错在什么地方,我在程序中共用VCL跟RTL包,并且用到了ShareMem,我把代码中连接池部分贴出来类定义
      TDBPool = class(TComponentList)
      private
        { Private declarations }
        function GetItems(Index: Integer): TDBConnector;
        procedure SetItems(Index: Integer; const Value: TDBConnector);
      protected
        { Protected declarations }
      public
        { Public declarations }
        property Items[Index: Integer]: TDBConnector read GetItems write SetItems; default;  published
        { Published declarations }
      end;  // 空闲连接池
      TDBFreePool = class(TDBPool)
      private
        { Private declarations }
        FTimer: TTimer;
        FCriticalSection: TCriticalSection;
      protected
        { Protected declarations }
        procedure OnTimer(Sender: TObject);
      public
        { Public declarations }
        constructor Create; reintroduce;
        destructor Destroy; override;
        procedure Lock;
        procedure UnLock;
      published
        { Published declarations }
      end;使用部分:TdmDataBase是单例模式,在单元finalization中释放function TdmDataBase.Add: TDBConnector;
    begin
      Result := TDBConnector.Create(nil);
      Add(Result);
    end;function TdmDataBase.Add(AConnector: TDBConnector): Integer;
    begin
      Result := -1;
      if Assigned(AConnector) then
      begin
        AConnector.OnWillExecute := OnWillExecuteEvent;
        AConnector.OnExecuteComplete := OnExecCompleteEvent;
      end;
    end;function TdmDataBase.GetDataSet(const ASQL: PChar; AOwner: TComponent = nil): TDataSet;
    var
      FConnector: TDBConnector;
    begin
      Result := nil;
      FConnector := GetUnLockedConnector;
      if Assigned(FConnector) then
      begin
        Result := FConnector.GetDataSetEx(ASQL, AOwner);
        if Assigned(FDataSetList) and Assigned(Result) then
          FDataSetList.Add(Result);
      end;
    end;function TdmDataBase.GetUnLockedConnector: TDBConnector;
    begin
      Result := nil;
      if Assigned(FFreePool) then
      try  // try
        FFreePool.Lock;
        if FFreePool.Count > 0 then
          Result := FFreePool.Extract(FFreePool[0])
        else Result := Add;
      finally  // wrap up finally
        FFreePool.UnLock;
      end;  // end try finally
    end;class function TdmDataBase.Instance: TdmDataBase;
    begin
      Result := inherited Instance as TdmDataBase;
    end;procedure TdmDataBase.OnExecCompleteEvent(Connection: TADOConnection;
      RecordsAffected: Integer; const Error: Error; var EventStatus: TEventStatus;
      const Command: _Command; const Recordset: _Recordset);
    var
      AConnector: TDBConnector;
    begin
      if Assigned(FBusyPool) and Assigned(FFreePool) then
      begin
        AConnector := FBusyPool.Extract(Connection as TDBConnector);
        if Assigned(AConnector) then
          FFreePool.Add(AConnector);
      end;
    end;procedure TdmDataBase.OnWillExecuteEvent(Connection: TADOConnection;
      var CommandText: WideString; var CursorType: TCursorType;
      var LockType: TADOLockType; var CommandType: TCommandType;
      var ExecuteOptions: TExecuteOptions; var EventStatus: TEventStatus;
      const Command: _Command; const Recordset: _Recordset);
    var
      AConnector: TDBConnector;
    begin
      if Assigned(FBusyPool)and Assigned(FFreePool) then
      begin
        AConnector := Connection as TDBConnector;
        if Assigned(AConnector) then
          FBusyPool.Add(AConnector);
      end;
    end;
      

  3.   

    TDBConnector = class(TADOConnection)function TDBConnector.GetDataSetEx(const ASQL: PChar; AOwner: TComponent = nil): TDataSet;
    begin
      Result := TADOQuery.Create(AOwner);
      with TADOQuery(Result) do  // with
      try  // try
        Connection := Self;    SQL.Text := ASQL;
        Active := True;
      except  // wrap up except
        FreeAndNil(Result);
        raise;
      end;  // end try except
    end;
      

  4.   

    TDBConnector.GetDataSetEx里面通过局部变量连接一下
    TmpAdo := TAdoQuery.create;
    try
      ...
      Result := TmpAdo;
    finally
      TmpAdo.free;
    end;