2012-02-11 50 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

相关问题