2013-05-14 86 views
3

我想使用此代碼使用List< int>作爲SQL參數:如何使用列表<int>作爲SQL參數在C#

var listID= new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

     using (var sqlConnection = new SqlConnection(_connectionstring)) 
     { 
      using (var cmd = new SqlCommand()) 
      { 
       cmd.Connection = sqlConnection; 
       cmd.CommandText = "delete from MyTable where TableID in (@tableID)"; 

       string param = String.Join(",", listID.ToArray()); 
       cmd.Parameters.Add("@tableID", param); 
       sqlConnection.Open(); 
       cmd.ExecuteNonQuery(); 
      } 
      sqlConnection.Close(); 
     } 

的問題是,這個代碼將生成:

EXEC sp_executesql N'delete from MyTable where TableID in( @tableID)',N'@ tableID nvarchar(17)',@ tableID = N'1,2,3,4,5,6,7,8,9'

這將失敗,因爲:

將nvarchar值 '1,2,3,4,5,6,7,8,9'轉換爲數據類型int時轉換失敗。

任何想法如何解決這個問題?謝謝。

編輯:我使用的是MS SQL 2012

+0

是SQL服務器,如果是的話,是什麼版本? – Jodrell 2013-05-14 14:47:52

+0

對不起,這是sql server 2012.我會延長我的問題。 – Chatumbabub 2013-05-14 14:50:07

+1

多個參數之間存在邏輯差異,用逗號分隔,而且* *逗號包含* single *字符串參數。 T-SQL(就像其他任何理智的語言一樣)並不試圖撕開那個單一的參數。 – 2013-05-14 14:54:31

回答

8

您應該使用TVP,比您可以完全按照指定保持查詢。他們在2008年的SQL

Table Valued Parameter, with example

+2

鑑於OP在談論SQL2012,這是要走的路。 +1 – Jodrell 2013-05-14 15:06:19

+0

+1是的。同意。當我寫回答時,我們不知道他在說什麼版本的SQL。 – 2013-05-14 15:11:55

+1

好信息!僅鏈接答案有幾個問題:。你能否考慮複製/粘貼信息到你的答案? – JumpingJezza 2015-04-08 02:00:52

0

在SQL Server 2008及以上版本,您可以使用表值參數。由於它們只是comman分隔的整數,所以我還會嘗試在存儲過程中保留delete語句並傳遞xml字符串或按原樣將其解析爲表變量。這在許多方面都是可行的,正如其他答案中所提到的,表格值參數似乎很乾淨。

+0

不要使用XML 。這正是TVP的目的。 TVP也可以作爲參數發送到存儲區 – Matthew 2013-05-14 15:00:23

+0

你說得對,tvp看起來很乾淨。但只有逗號分隔的整數使我提供了額外的選項。在 Sunny 2013-05-14 15:06:07

0

我一般會使用某種ORM的,但如果你想用類似你有什麼東西來進行,你總是可以試試這個:

var listID= new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
    using (var sqlConnection = new SqlConnection(_connectionstring)) 
    { 
     using (var cmd = new SqlCommand()) 
     { 
      cmd.Connection = sqlConnection; 
      cmd.CommandText = "delete from MyTable where TableID in (" + String.Join(",",listID) + ")"; 
      sqlConnection.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
     sqlConnection.Close(); 
    } 
+2

爲什麼這是低調?給出這個問題似乎是合理的。 – 2013-05-14 14:57:25

+1

如果你正在做動態SQL,它是非常有效的。 – Jodrell 2013-05-14 15:03:24

+3

@MichaelTodd我猜測,因爲即使目前的形式是安全的,但微小的修改('List ')使其危險不安全。就個人而言,我並不一定反對動態SQL,但如果需要使用它,通常更好的替代方法是在(@ p0,@ p1,@ p2,...)查詢中建立一個where TableID並將這些列表值存儲在參數中。 – hvd 2013-05-14 15:04:28

2

介紹了在SQL Server 2005年,我寫了一個逗號分隔的列表轉換成一組nvarchars的CLR函數。

[SqlFunction(DataAccess = DataAccessKind.None, 
       IsDeterministic = true, 
       SystemDataAccess = SystemDataAccesskind.None, 
       IsPrecise = true, 
       FillRowMethodName = "SplitFillRow", 
       TableDefinition = "s NVARCHAR(MAX)")] 
public static IEnumerable Split(SqlChars seperator, SqlString s) 
{ 
    if (s.IsNull) 
    { 
     return new string[0]; 
    } 

    return s.ToString().Split(seperator.Buffer); 
} 

public static void SplitFillRow(object row, out SqlString s) 
{ 
    s = new SqlString(row.ToString()); 
} 

我認爲這是一種有效的利用.NET CLR和優於非CLR替代using a CTE function


在SQL Server 2008+中,您可以使用Table Valued Parameters

相關問題