2012-02-11 82 views
4

我可以在單個語句中插入項目,但我想要做的是使用存儲過程的另一個版本。我怎麼做。這裏是我的代碼:如何使用存儲過程在SQL中插入多行?

private void button1_Click(object sender, EventArgs e) 
     { 
#region Get Values 

      string[] array = {textBox1.Text+":"+textBox5.Text,textBox2.Text+":"+textBox6.Text,textBox3.Text+":"+textBox7.Text,textBox4.Text+":"+textBox8.Text}; 
      string query = ""; 
      string product = ""; 
      int qty = 0; 
      for (int i = 0; i < array.Length; i++) 
      { 
       product = array[i].ToString().Substring(0,array[i].ToString().IndexOf(':')); 
       qty = int.Parse(array[i].ToString().Substring(array[i].ToString().IndexOf(':')+1)); 
       if (string.IsNullOrEmpty(query)) 
       { 
        query = "Insert Into MySampleTable Values ('"+product+"','"+qty+"')"; 
       } 
       else 
       { 
        query += ",('" + product + "','" + qty + "')"; 
       } 


      } 

#endregion 

      string connect = "Data Source=RANDEL-PC;Initial Catalog=Randel;Integrated Security=True"; 
      SqlConnection connection = new SqlConnection(connect); 
      connection.Open(); 
      string insert = query; 
      SqlCommand command = new SqlCommand(query,connection); 
      command.ExecuteNonQuery(); 
      command.Dispose(); 
      connection.Close(); 
      connection.Dispose(); 
      label5.Visible = true; 
      label5.Text = insert; 
     } 
    } 

先生/女士,您的答案會有很大的幫助,非常感謝。謝謝++

+0

有這麼多的事情是錯誤的。我認爲你需要研究很多關於數據訪問層,防止sql注入,企業庫數據塊(如果你願意,可以用你的數據訪問層來幫助你),之後我認爲你可以做到這一點。我可以回答你的問題,但我更願意幫你告訴你要學習的東西。 – 2012-02-11 12:52:48

+2

作爲一個側面提示:您應該爲您的SQL插入使用**參數化查詢** - 您不應該只是將您的SQL語句連接在一起 - 這會打開SQL注入攻擊的大門。 [請參見此處如何執行參數化查詢](http://www.4guysfromrolla.com/webtech/092601-1.shtml) – 2012-02-11 12:53:05

回答

2

如果你想多值傳遞到存儲過程有兩種方式:

  • 和醜陋的一個:通過你的價值觀作爲一個單獨的字符串,你的存儲過程中分裂,這樣做散插。你會在Google找到大量的例子。

  • 一個聰明的方法:使用表值參數,這是ADO.NET和SQL Server都支持的功能。然後您將能夠傳遞一個參數值並將其作爲存儲過程中的普通表變量。

+0

您是否有表值參數示例?謝謝。 – 2012-02-13 08:50:39

7

在SQL Server 2008+中,有更簡單的方法在單個語句中插入多行。例如,此語法是有效的:

INSERT dbo.table(col1, col2) VALUES 
    (1, 2), 
    (2, 3), 
    (3, 4); 

上面將插入三行。在老版本中,你可以做稍微詳細的東西,如:

INSERT dbo.table(col1, col2) 
SELECT 1, 2 
    UNION ALL SELECT 2, 3 
    UNION ALL SELECT 3, 4; 

當然你ExecuteNonQuery不必是單一的命令,你可以通過這個作爲一個字符串,它仍然可以工作:

INSERT dbo.table(col1, col2) VALUES(1, 2); 
INSERT dbo.table(col1, col2) VALUES(2, 3); 
INSERT dbo.table(col1, col2) VALUES(3, 4); 

如果你想這樣做,在存儲過程中,你可以,如果你在下面的字符串傳遞輕鬆執行多值參數的分裂,例如:

1,2;2,3;3,4 

你可以處理使用的功能,如一個我張貼在這裏的那些值:

Split value pairs and a create table using UDF

所以你的過程可能是這樣的:

CREATE PROCEDURE dbo.AddOrderLineItems 
    @LineItems VARCHAR(MAX) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT dbo.OrderItems(Product, Quantity) 
     SELECT Product, Quantity FROM dbo.MultiSplit(@LineItems); 
END 
GO 

而且你會使用C#相當於調用它:

EXEC dbo.AddOrderLineItems @LineItems = '1,2;2,3;3,4'; 

或者您可以使用Alexey建議的表值參數。一個簡單的例子:

CREATE TYPE OrderLineItem AS TABLE 
(
    Product INT, 
    Quantity INT 
); 

然後你就可以創建一個過程:

CREATE PROCEDURE dbo.AddOrderLineItems 
    @LineItems OrderLineItem READONLY 
    -- other parameters 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT dbo.OrderItems(Product, Quantity) 
    SELECT Product, Quantity FROM @LineItems; 
END 
GO 

然後在你的C#代碼創建等效的TVP(我不是你想要做的人,你可以看到一個example here)。

但也有一些注意事項,請看看這個問題:

Creating a generalized type for use as a table value parameter

相關問題