2016-01-20 73 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

相關問題