2

SQL Server 2005 データベースの ID 列である "Id" 列を持つ DataTable があります。この列には、AutoIncrement プロパティが true に設定されています。テーブルは挿入のみに使用するため、DB からのデータをテーブルに入力しません。そのため、1 から始まる偽の ID が割り当てられます。

しかし、tableAdapter.Update() を呼び出した後、データベースによって割り当てられた REAL ID をその列に入れたいと思います。

何らかの理由で、最初の行のみが更新され、残りはすべて更新されません。このテーブルは、カスケード DataRelation (階層構造) を使用して自身を参照し、最初の行への参照も更新されます。

それに応じてすべてのIDを更新する方法を教えてください。

前もって感謝します!

INSERT ステートメント:

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo) 

コンポーネント テーブルのスキーマは次のとおりです。

Id BIGINT PK, 
ComponentId BIGINT FK, 
OrderNo int, 
SerialNo int 

Id 列の名前は「Id」、「ComponentId」は FK 参照列であることに注意してください。

4

4 に答える 4

4

これは以前はとても簡単でした。Column.AutoIncrementSeed と Column.AutoIncrementStep の両方を「-1」に設定するだけです。そうすれば、追加された新しい行の ID は -1、-2 などになります。次に、ストアド プロシージャまたは TSQL コードは次のようになります。

UPDATE Table
SET 
    Col1 = @Col1
    Col2 = @Col2
WHERE (ID = @ID) -- If this is -1, -2, etc, it won't update

IF (@@ROWCOUNT = 0)
    BEGIN
    INSERT INTO Table(Col1, Col2) VALUES(Col1, Col2)
    SET @ID = SCOPE_IDENTITY();  -- @ID would now change from -1 to 1, 2, 3, etc.
END

しかし、Microsoft はその無限の知恵により、ADO.NET 4.0 でこれらすべてを悪化させました。いつ変更されたのかはよくわかりませんが、その列の現在の値を内部に格納する AutoIncrement 列に、基になるプライベート フィールドがあります。データベースで、最後に挿入された値が「52」であるとしましょう。これは、AutoIncrement 列内に隠されています。これにより、マルチユーザー アプリで大きな問題が発生し、最後の AutoIncrement 値から逆方向にカウントを開始するため、「-1」トリックを使用できなくなりました。これを変更するためにリフレクションに頼ろうとさえしましたが、それはうまくいきません。Microsoft が ADO​​.NET でこれを壊したことを私は嫌いますが、彼らは「いいえ、バグ X を修正しません」というマントラを支持しています。

于 2011-07-18T02:39:53.293 に答える
0

SQLからIDを返す必要があります。しかし、正確な構文についてはもうわかりません

試す

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo);
SET @ComponentId = SCOPE_IDENTITY()

また

INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
VALUES (@ComponentId, @OrderNo, @SerialNo);
SELECT SCOPE_IDENTITY()
于 2009-09-08T11:22:31.593 に答える
0

The problem was in the mentioned DataRelation. For some reason, because of this DataRelation, the "child" rows were not inserted in the DB and their Ids were not updated to the real Ids, although the DataTable had the "Refresh the Data Table" check on (in Configure/Advanced Settings).

I've removed the DataRelation and did all the work by hand. The following code did the trick for me:

ComponentsTableAdapter cta = new ComponentsTableAdapter();                    
foreach (UpdaterDataSet.ComponentsRow r in uds.Components.Rows)
{                    
   long origId = r.Id;
   cta.Update(r);

   foreach (UpdaterDataSet.ComponentsRow s in uds.Components.Rows)
   {
      if (s.Id != r.Id && !s.IsComponentIdNull() && s.ComponentId == origId)
         s.ComponentId = r.Id;
   }                 
}
于 2009-09-08T12:44:38.913 に答える
0

Fill メソッドの実行前に、オートインクリメントでデータ列を作成し、

編集:

    SqlConnection cn = new SqlConnection(@"Connection_String");
    SqlDataAdapter adp;
    SqlCommandBuilder cb;
    DataTable dt;

    private void Form3_Load(object sender, EventArgs e)
    {
        adp= new SqlDataAdapter("select * from temp", cn);
        cb = new SqlCommandBuilder(adp);
        dt = new DataTable();
        dt.Columns.Add("SrNo", typeof(int));
        dt.Columns[0].AutoIncrement = true;
        dt.Columns[0].AutoIncrementSeed = 1;
        dt.Columns[0].AutoIncrementStep = 1;

        adp.Fill(dt);
        dataGridView1.DataSource = dt;
    }
    private void button1_Click(object sender, EventArgs e)
    {
        adp.Update(dt);
    }  
于 2009-09-08T10:55:34.143 に答える