Right Approach to Insert in Table then copy it to another table

坚强是说给别人听的谎言 提交于 2019-12-11 19:27:03

问题


In my application a user will insert a book. For example someBook will be insert with 3 copies. Table1.BookID = 1, Table1.Copy = 3, Then in another table those 3 books will have their primary key so it will be Table2.AccessionID = 1,2,3 Table2.BookID = 1, 1, 1.

This is what I current doing but a bad practice as what Aaron Bertrand said.

int BookTitlesID;
public void addBookTitle()
{
  int copy = int.Parse(textBox2.Text);
  try
  {
    using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
    {
      myDatabaseConnection.Open();

      using (SqlCommand mySqlCommand1 = new SqlCommand("INSERT INTO BookTitles(BookTitle, Copies) Values(@BookTitle,  @Copies)", myDatabaseConnection))
      {
        mySqlCommand1.Parameters.AddWithValue("@BookTitle", BookTitletextBox.Text);
        mySqlCommand1.Parameters.AddWithValue("@Copies", copy);
        mySqlCommand1.ExecuteNonQuery();
      }
    }
  }
  catch (Exception Ex)
  {
    MessageBox.Show(Ex.Message, "Exception");
  }
}

public void addBook()
{
  int copy = int.Parse(textBox2.Text);
  try
  {
    for (int x = 0; x < copy; x++)
    {
      using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
      {
        myDatabaseConnection.Open();
        using (SqlCommand mySqlCommand1 = new SqlCommand("INSERT INTO book(BookTitleID) Values(@BookTitleID)", myDatabaseConnection))
        {
          mySqlCommand1.Parameters.AddWithValue("@BookTitleID", BookTitlesID);
          mySqlCommand1.ExecuteNonQuery();
        }
      }
    }
  }
  catch (Exception Ex)
  {
    MessageBox.Show(Ex.Message, "Exception");
  }
}

private void Form_Load(object sender, EventArgs e)
{
  using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
  {
    myDatabaseConnection.Open();
    using (SqlCommand mySqlCommand1 = new SqlCommand("SELECT TOP 1 BookTitleID + 1 FROM BookTitles ORDER BY BookTitleID DESC", myDatabaseConnection))
    {
      string x = mySqlCommand1.ExecuteScalar().ToString();
      BookTitlesID = Convert.ToInt32(x);
    }
  }
}

private void button1_Click(object sender, EventArgs e)
{
  addBookTitle();
  addBook();
}

回答1:


Simplify. Most notably, as discussed in your other, related question, there is absolutely no safety in going out and seeing what the current MAX is, adding 1, and assuming that will be the next identity value generated. You can only rely on that number if you retrieve it after you have inserted, and the most reliable way to do that is to use SCOPE_IDENTITY() (or, for a multiple-row INSERT, an OUTPUT clause).

CREATE PROCEDURE dbo.InsertBook
  @BookTitle NVARCHAR(256),
  @Copies    INT
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @BookTitleID INT;

  INSERT dbo.BookTitles(BookTitle, Copies) SELECT @BookTitle, @Copies;

  SELECT @BookTitleID = SCOPE_IDENTITY();

  INSERT dbo.Books(BookTitleID) SELECT @BookTitleID
  FROM (SELECT TOP (@Copies) rn = ROW_NUMBER() OVER (ORDER BY [object_id])
        FROM sys.all_objects ORDER BY [object_id]) AS y;
END
GO

Now you can really simplify your C# code (I'm not a C# guy, so whether this is the best approach or if it will even compile is beyond me, but hopefully you can sort that out on your own).

public void addBook()
{
  try
  {
    int Copies    = int.Parse(textBox2.Text);
    string BTitle = BookTitletextBox.Text
    using (SqlConnection conn = new SqlConnection ...blah blah...)
    {
      conn.Open();

      using (SqlCommand cmd = new SqlCommand("EXEC dbo.InsertBook", conn))
      {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@BookTitle", BTitle);
        cmd.Parameters.AddWithValue("@Copies",    Copies);
        cmd.ExecuteNonQuery();
      }
    }
  }
  catch (Exception Ex)
  {
    MessageBox.Show(Ex.Message, "Exception");
  }
}

private void button1_Click(object sender, EventArgs e)
{
  addBook();
}


来源:https://stackoverflow.com/questions/18195528/right-approach-to-insert-in-table-then-copy-it-to-another-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!