0

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.

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

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");
    }
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
  • Very unclear what you want... but please read on https://stackoverflow.com/questions/5468425/how-do-parameterized-queries-help-against-sql-injection before [edit] of the question with clarifications. – Alexei Levenkov Dec 30 '18 at 06:07
  • I went through the guide when I made it. I'm not sure where I went wrong. I'm sorry – Keegan Hart Dec 30 '18 at 06:10

3 Answers3

1

As @Caius Jard said, you can't do this with an ad-hoc query.

So what is an option to do so?

Step 1: Create a Stored Procedure in the Database:

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:

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();

}
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
  • Thank you so much! This is exactly what I was looking for! I was trying to do what you did in the database in the c# code. This makes so much more sense – Keegan Hart Dec 30 '18 at 23:12
0

You can't do this in 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

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. 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

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
0

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. 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}");
            }
         }
     }
}
KSK
  • 666
  • 4
  • 22
  • Do not post a link to a tool or library as an answer. Demonstrate [how it solves the problem](http://meta.stackoverflow.com/a/251605) in the answer itself. Do [edit] the answer, and flag for undeletion once you have added the demonstration. – Bhargav Rao Dec 30 '18 at 09:12