0

私のアプリケーションでは、ユーザーは本を挿入します。たとえば、someBook は 3 部で挿入されます。Table1.BookID = 1、Table1.Copy = 3、次に別のテーブルでは、これら 3 冊の本が主キーを持つため、Table2.AccessionID = 1,2,3 Table2.BookID = 1, 1, 1 になります。

これは私が現在行っていることですが、アーロン・バートランドが言ったように悪い習慣です。

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

1 に答える 1

5

簡素化する。最も注目すべきは、他の関連する質問で説明されているように、外に出て現在のMAX値を確認し、1 を追加して、それが次に生成される ID 値であると想定することは絶対に安全ではありません。挿入後に取得する場合にのみ、その番号に依存できます。これを行う最も信頼できる方法は、使用することですSCOPE_IDENTITY()(または、複数行INSERTの場合はOUTPUT句)。

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

これで、C# コードを本当に単純化できます (私は C# の専門家ではないので、これが最善のアプローチなのか、コンパイルできるのかはわかりませんが、ご自分で解決できることを願っています)。

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();
}
于 2013-08-12T19:55:43.817 に答える