2016-01-20 40 views
0

我想查询远程服务器上的服务并将它们插入到SQL中。我知道我错过了一些实际上会写回来的东西,但我无法弄清楚它是什么。一切工作,直到我试图写入数据到SQL。以编程方式获取Windows服务并写入SQL

static void Main(string[] args) 
{ 
    string username = ConfigurationManager.AppSettings["UserName"].ToString(); 
    string password = ConfigurationManager.AppSettings["Password"].ToString(); 
    string domain = ConfigurationManager.AppSettings["Domain"].ToString(); 
    var logonType = SimpleImpersonation.LogonType.NewCredentials; 

    using (SimpleImpersonation.Impersonation.LogonUser(domain, username, password, logonType)) 
    { 
     var connection = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString; 

     using (SqlConnection conn = new SqlConnection(connection)) 
     { 
      conn.Open(); 
      using (SqlCommand command = new SqlCommand("SELECT ServerName, ServerIP FROM Server", conn)) 
      { 
       SqlDataReader reader = command.ExecuteReader(); 

       while (reader.Read()) 
       { 
        string serverIP = reader["ServerIP"].ToString(); 
        string serverName = reader["ServerName"].ToString(); 

        ServiceController[] services = ServiceController.GetServices(serverIP); 

        foreach (ServiceController service in services) 
        { 
         using (SqlCommand cmd = new SqlCommand("sp_InsertServices", conn)) 
         { 
          cmd.CommandType = System.Data.CommandType.StoredProcedure; 
          SqlParameter ID = new SqlParameter(); 
          ID.ParameterName = "@ID"; 
          ID.Direction = System.Data.ParameterDirection.Output; 
          cmd.Parameters.AddWithValue("@ID", ID); 
          cmd.Parameters.AddWithValue("@Display", service.DisplayName); 
          cmd.Parameters.AddWithValue("@Service", service.ServiceName); 
          cmd.Parameters.AddWithValue("@Status", service.Status); 
          cmd.Parameters.AddWithValue("@Server", serverName); 
         } 
        } 
       } 
      } 
     } 
    } 
} 

这里是存储过程

PROCEDURE [dbo].[sp_InsertServices] 
@ID   int, 
@Display nvarchar(50), 
@Service nvarchar(50), 
@Status  nvarchar(50), 
@Server  nvarchar(50) 

AS 
BEGIN 

SET NOCOUNT ON 

INSERT INTO Services 
(ID, 
DisplayName, 
ServiceName, 
Status, 
Server) 

VALUES 
(@ID, 
@Display, 
@Service, 
@Status, 
@Server) 

SET @ID = SCOPE_IDENTITY() 

END 

编辑:对不起一些更多的信息。在param添加后,我在最后添加了一个执行,并且出现此错误。

“System.InvalidOperationException”类型的未处理的异常出现在system.data.dll

其他信息:已经有一个用此命令,必须先关闭相关联的打开的DataReader。

看起来我需要关闭第一个阅读器,但我仍然在第二个命令中使用它。现在不要在那里我可以安全地关闭它。

+2

什么是你的错误? –

+0

在执行完第一个之后关闭它,然后重新打开它:) – ImDeveloping

回答

3

你永远不会执行你的SqlCommand。添加参数后,请尝试添加cmd.ExecuteNonQuery();

第二个问题是您试图重复使用相同的SqlConnection。您需要创建一个新的SqlConnection,因为您正在使用现有连接来遍历服务器列表。

+0

对不起,这是我尝试过的一件事。执行时出现以下错误 System.Data.dll中发生未处理的System.InvalidOperationException类型异常 附加信息:已经有一个与此命令关联的打开的DataReader,必须先关闭它。 – maltman

+0

这是您需要修复的错误。您需要创建第二个连接对象,因为您正在使用现有连接来遍历服务器列表。 – David

+0

谢谢。添加第二个SQL连接解决了问题。 – maltman

1

你已经建立了Command对象(CMD),现在你只需要保存它,就像cmd.ExecuteNonQuery();

1

首先为此,您需要更改存储过程声明为

ALTER PROCEDURE [dbo].[sp_InsertServices] 
    @Display nvarchar(50), 
    @Service nvarchar(50), 
    @Status  nvarchar(50), 
    @Server  nvarchar(50) 

AS 
BEGIN 

    SET NOCOUNT ON 

    INSERT INTO Services 
    (DisplayName, ServiceName, Status, Server) 
    VALUES 
    (@Display,@Service,@Status,@Server) 

    SELECT SCOPE_IDENTITY() 

END 

现在调用代码更改为

using (SqlCommand cmd = new SqlCommand("sp_InsertServices", conn)) 
{ 
    cmd.CommandType = System.Data.CommandType.StoredProcedure; 
    cmd.Parameters.AddWithValue("@Display", service.DisplayName); 
    cmd.Parameters.AddWithValue("@Service", service.ServiceName); 
    cmd.Parameters.AddWithValue("@Status", service.Status); 
    cmd.Parameters.AddWithValue("@Server", serverName); 

    int serviceID = (int)cmd.ExecuteScalar(); 

    // What you want to do with the ID returned? 


} 

不需要ID参数,如果你的ID字段是标识列,它是由数据库自动计算和你凑LD使用简单的选择返回它。如果存储过程以SELECT SCOPE_IDENTITY()结束,则可以使用简单的ExecuteScalar在C#代码中检索结果,而不需要输出参数。

最后,如果您尝试使用SqlDataReader使用的相同连接执行ExecuteXXX SqlCommand,您会得到一个异常,因为连接正忙于服务SqlDataReader并且无法执行该命令。

简单的解决办法是添加到您的连接字符串

....;MultipleActiveResultSets=True;.... 

See MSDN for MultipleActiveResultSets

相关问题