简体   繁体   English

如何在单个查询中执行多个Insert语句?

[英]How to execute Multiple Insert statements in a single query?

I'm making a form where a user answers some questions to make a pricehold. 我正在制作一个表单,其中用户回答一些问题以定价。 My problem is I can't store the data from the questions into more than one sql table. 我的问题是我无法将问题中的数据存储到多个sql表中。

I have tried inserting the other table into the sql command (shown below) and I have tried making another sql command that basically says the same thing with a different name but splitting the name and phone number into the first one and the date created and pick up date into the second one but that only runs the first sql command and then stops so data is never stored into the second table 我尝试将另一个表插入sql命令(如下所示),并且尝试制作另一个sql命令,该命令基本上用相同的名称表示相同的内容,但将名称和电话号码分为第一个和创建的日期,然后选择最新日期进入第二个,但仅运行第一个sql命令,然后停止,因此数据永远不会存储到第二个表中

private void AddPhBttn_Click(object sender, RoutedEventArgs e)
    {
        SqlConnection furniture = new SqlConnection("Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True");



        furniture.Open();
        SqlCommand add = new SqlCommand("insert into Customers(Name, Phone) PriceHold(DateCreated, PickUpDate) values ('" + nameTxtBox.Text + "', '" + phoneTxtbox.Text + "', '" + dateTxtBox.Text + "', '" + puDateTxtBox.Text + "')", furniture);

        int i = add.ExecuteNonQuery();
        if (i != 0)
        {
            MessageBox.Show("saved");
        }
        else MessageBox.Show("error");
    }

As @Caius Jard said, you can't do this with an ad-hoc query. 正如@Caius Jard所说,您不能通过即席查询来做到这一点。

So what is an option to do so? 那么有什么选择呢?

Step 1: Create a Stored Procedure in the Database: 步骤1:在数据库中创建一个Stored Procedure

CREATE PROCEDURE usp_InsertData
@Name NVARCHAR(200),
@Phone NVARCHAR(100),
@DateCreated Date,
@PickUpDate Date
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Customers(Name, Phone) VALUES (@Name,@Phone)

    INSERT INTO PriceHold(DateCreated, PickUpDate) VALUES (@DateCreated,@PickUpDate) 
END

Step 2: Call above Stored procedure in C# Code: 步骤2:使用C#代码调用上述存储过程:

private void AddPhBttn_Click(object sender, RoutedEventArgs e)
{
     var furniture = new SqlConnection("Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True");

     SqlCommand add = new SqlCommand("usp_InsertData", furniture);
     add.CommandType = System.Data.CommandType.StoredProcedure;

     add.Parameters.AddWithValue("@Name", nameTxtBox.Text);
     add.Parameters.AddWithValue("@Phone", phoneTxtbox.Text);
     add.Parameters.AddWithValue("@DateCreated", dateTxtBox.Text);
     add.Parameters.AddWithValue("@PickUpDate", puDateTxtBox.Text);
     furniture.Open();

     int i = add.ExecuteNonQuery();

     if (i != 0)
     {
          MessageBox.Show("saved");
     }
     else
     {
         MessageBox.Show("error");
     }
     furniture.Dispose();

}

You can't do this in SQL 您无法在SQL中执行此操作

INSERT INTO 
  myfirsttable(column1, column2)
  mysecondtable(column3, column4, column5)
VALUES(value1, value2, value3, value4)

It's flat out a syntax error. 这完全是语法错误。 Only one table may appear in an insert. 插入中只能出现一个表。 The number of values inserted must match the number of columns 插入的值数必须与列数匹配

If you want to insert into two tables, run two separate inserts from your c# code 如果要插入两个表,请从C#代码运行两个单独的插入

Finally, have a long read of http://bobby-tables.com - your code is currently highly insecure and while this may not matter right now because it's just some small test app, it is best to avoid embarking on a learning path that includes coding in this way. 最后,请仔细阅读http://bobby-tables.com-您的代码目前非常不安全,尽管现在这可能并不重要,因为它只是一些小型测试应用程序,因此最好避免走上一条学习道路包括以这种方式编码。 As a recruiter I've turned down many job candidates who have written SQL like this and I'd never employ someone who demonstrated this style to me 作为一名招聘人员,我拒绝了许多这样编写SQL的求职者,而且我从不雇用任何向我展示这种风格的人

When working with data in more than one table, if you want to ensure either all insert/update/delete complete successfully or none of them are applied on your data to ensure data integrity, use transactions. 当使用多个表中的数据时,如果要确保成功完成所有插入/更新/删除操作, 或者没有任何插入/更新/删除操作应用于数据以确保数据完整性,请使用事务。 I think SqlTransaction is what you're after. 我认为SqlTransaction是您所追求的。 Read about it here . 在这里阅读。

For your specific case, this is one possibility: 对于您的特定情况,这是一种可能性:

private void AddPhBttn_Click(object sender, RoutedEventArgs e)
{
    // Necessary input validation to collect and data from input fields. Good practice to avoid SQL injection.
    AddFurniture(nameTxtBox.Text, phoneTxtbox.Text, dateTxtBox.Text, puDateTxtBox.Text);
}

private void AddFurniture(string name, string phoneNumber, string createdDate, string pickupDate)
{
    string connectionString = "Data Source=LAPTOP-F4QFMPFD\\MSSQLSERVER1;Initial Catalog=Furniture;Integrated Security=True"; // This should ideally come from some configuration.
    using(SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = connection.CreateCommand();
        SqlTransaction transaction = connection.BeginTransaction("Add Furniture");
        command.Connection = connection;
        command.Transaction = transaction;

        try
        {
             connection.Open();
            command.CommandText = $"insert into Customers (Name, Phone) values ({name}, {phoneNumber});";
            command.ExecuteNonQuery();
            command.CommandText = $"insert into PriceHold (DateCreated, PickUpDate) values ({createdDate}, {pickupDate});";
            command.ExecuteNonQuery();

            // Try to commit to database.
            // Both the above queries are executed at this point. If any one of them fails, 'transaction' will throw an exception.
            transaction.Commit();
        }
        catch (Exception ex1)
        {
            // Considering the statements executed using the 'transaction' for this 'connection',
            // one of the insert operations have clearly failed.
            // Attempt to roll back the change which was applied.
            MessageBox.Show($"Insert failed. Trying to roll back {ex1.Message}");
            try
            {
                transaction.RollBack();
            }
            catch (Exception ex2)
            {
                // Rollback also failed. Possible data integrity issue. Handle it in your application.
                MessageBox.Show($"Roll back failed. {ex2.Message}");
            }
         }
     }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM