2013-02-21 45 views
0

所以我不知道這是否可行,或者甚至是可取的,但我想知道如何在我的web服務中創建一個可以構建的更新命令動態地由用戶。基本上,目標是有一個表具有x列的數量,用戶應該能夠更新任意數量的列,而不必爲沒有更新的列傳遞null或現有值。例如,一個人可能要運行在Web服務中動態創建SQL更新命令

UPDATE calendar_table 
SET title = 'Some new Title' 
WHERE (id = 12344) 

而另一用戶可能要執行此操作,而不是

UPDATE calendar_table 
SET title = 'New Event', type = 'Meeting', note = 'Meet with new client' 
WHERE (id = 12344) 

那麼下面就是我試圖用,但我不斷收到異常說明有附近的「WHERE」這使我相信它的東西與我如何努力把更新串

String MyConnStr = ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString; 
     SqlConnection connection = new SqlConnection(MyConnStr); 
     SqlCommand Query = new SqlCommand("UPDATE dbo.calendar_table " + 
      "SET @newText " + 
      "WHERE (id = @appointmentID)", connection); 
     Query.Parameters.Add("@newText", SqlDbType.VarChar).Value = note; 
     Query.Parameters.Add("@appointmentID", SqlDbType.VarChar).Value = appointment; 
     Query.CommandType = CommandType.Text; 
     try 
     { 
      connection.Open(); 
      Query.ExecuteNonQuery(); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
     } 
     finally 
     { 
      connection.Close(); 
      Query.Dispose(); 
     } 

任何幫助或想法,將不勝感激問題因爲我能想到的唯一的其他選項就是創建包含所有可能值的Web服務,然後傳遞不隨值更改的現有值。

+0

只是根本不使用任何參數來表示「set」。創建一個這樣的查詢:Query = new SqlCommand(「UPDATE dbo.calendar_table」+ 「SET」+ note + 「WHERE(id = @appointmentID)」,connection); – cha 2013-02-21 23:44:12

+0

通常,您不能使用主變量來準備SQL語句。請注意,動態SQL是最「危險的」(因爲您擁有SQL注入的最高機會)。你在用什麼語言/框架?他們中的一些人有一種'安全'構建語句的方法,像'Query.UpdateColumn(「note」)'等等(我不知道你看起來像什麼)。 – 2013-02-22 00:42:15

回答

0

您的代碼將假定知道將爲給定更新設置哪些字段。因此,您可以動態地將每個字段添加到SET子句和Parameters集合中。使用每個字段的參數還可以避免註釋中提到的SQL注入問題。

基於您的示例代碼的語法,我假設它是C#。以下是您可以處理更新變量,用戶定義的字段數量的一種方法。

假定存在包含該用戶具有輸入值的變量:userInputTitleuserInputTypeuserInputNote

id字段被包括在SET子句中除去的是否要添加一個逗號的問題在SET子句中的每個動態添加字段之前。作爲其副作用,即使用戶尚未定義任何字段,也可以運行更新。

順便說一下,使用using代替明確嘗試清理實現接口的對象,被認爲是更好的做法,因此下面的示例將相應地進行重寫。 using語句將關閉連接並處理連接和命令。此外,使用Parameters.AddWithValue()可避免指定參數的數據類型。

我還沒有測試過這段代碼。

String MyConnStr = 
     ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString; 
using (SqlConnection connection = new SqlConnection(MyConnStr)) 
{ 
    using (SqlCommand Query = new SqlCommand()) 
    { 
     try 
     { 
      Query.Connection = connection; 
      String sql = "UPDATE dbo.calendar_table SET id = @appointmentID"; 
      // The has-field-been-updated-by-user logic below assumes the 
      // fields are strings. Different logic might be necessary 
      // for other data types. 
      if (!String.IsNullOrWhitespace(userInputTitle)) 
      { 
       sql += ", title = @title"; 
       Query.Parameters.AddWithValue("@title", userInputTitle); 
      } 
      if (!String.IsNullOrWhitespace(userInputType)) 
      { 
       sql += ", type = @type"; 
       Query.Parameters.AddWithValue("@type", userInputType); 
      } 
      if (!String.IsNullOrWhitespace(userInputNote)) 
      { 
       sql += ", note = @note"; 
       Query.Parameters.AddWithValue("@note", userInputNote); 
      } 
      // Additional fields... 
      sql += " WHERE (id = @appointmentID)"; 
      Query.Parameters.AddWithValue("@appointmentID", appointmentID); 
      Query.CommandText = sql; 
      Query.CommandType = CommandType.Text; 
      connection.Open(); 
      Query.ExecuteNonQuery(); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
     } 
    } 
} 
+1

感謝gmm,這確實有效,我只需要對可更新的不同字段進行一些調整,但這是我需要確保我在正確的軌道上以避免SQL注入。 – 2013-02-22 17:07:43