-1

C# と SQL の初心者はこちら。table1の主キーを外部キーとして使用する 2 つのテーブルがありtable2ます。ID を取得するために、私は使用してSELECT MAXおり、すべてが必要に応じて機能します (以下のコード):

        {
            con1.Open();

            SqlCommand cmd1 = new SqlCommand();
            cmd1.CommandText = "INSERT INTO dbo.testDriver(name) Values(@name)";
            cmd1.Connection = con1;
            cmd1.Parameters.AddWithValue("@name", name.Text);
            cmd1.ExecuteNonQuery();
            cmd1.Parameters.Clear();

            cmd1.CommandText = "SELECT MAX(PkDriverID) FROM dbo.testDriver";
            int FkDriverID = Convert.ToInt32(cmd1.ExecuteScalar());

            cmd1.CommandText = "INSERT INTO dbo.testCar(brand, model, FkDriverID) Values(@brand, @model, @FkDriverID)";
            cmd1.Connection = con1;
            cmd1.Parameters.AddWithValue("@brand", brand.Text);
            cmd1.Parameters.AddWithValue("@model", model.Text);
            cmd1.Parameters.AddWithValue("@FkDriverID", FkDriverID);
            cmd1.ExecuteNonQuery();
            cmd1.Parameters.Clear();

            con1.Close();
        }
        {
            Response.Redirect(this.Request.Url.ToString());
        }

SCOPE_IDENTITY()しかし、同僚は代わりにを使うべきだと言っていますSELECT MAX。なぜそれを使用する必要があるのか​​ (複数のユーザーの場合など)は理解していますが、SELECT MAXそれを置き換えた後、エラーが発生します:

オブジェクトを DBNull から他の型にキャストすることはできません。

私のデータベースでは、PK と FK のデータ型は int で、Null は許可されておらず、SELECT MAXそのままで機能します。それで、私はここで何が間違っていますか?

4

1 に答える 1

1

競合状態Select MAXでは、挿入直後に他の誰かによって生成された ID が返される場合があります。さらに、identity永遠に成長する必要はありませんreseeded。また、不適切な追加select作業を行います。

SCOPE_IDENTITYあなたの(そして他のほとんどの)ケースにとって唯一の正しい方法です。

さらに、2 つのクエリを 1 つのクエリにまとめ、両方の挿入をトランザクションで囲むことをお勧めします。このようにして、 に問題が発生した場合に にrollback変更できます。DriverCar

于 2016-02-15T10:44:05.297 に答える