3

私は、数時間の冒険に変わった一見単純なタスクを完了しようとしてい@@IdentityますTableAdapter.Insert()

これが私のコードです:

protected void submitBtn_Click(object sender, EventArgs e)
{
    AssetsDataSetTableAdapters.SitesTableAdapter sta = new AssetsDataSetTableAdapters.SitesTableAdapter();
    int insertedID = sta.Insert(siteTxt.Text,descTxt.Text);

    AssetsDataSetTableAdapters.NotesTableAdapter nta = new AssetsDataSetTableAdapters.NotesTableAdapter();
    nta.Insert(notesTxt.Text, insertedID, null,null,null,null,null,null);
    Response.Redirect("~/Default.aspx");
}

1つの答えは、私がしなければならないのはを変更することだけだということを示唆していますExecuteMode。やってみました。これによりGetData()、動作を停止します(rowdataの代わりにスカラーを返すため)(GetData()を保持する必要があります)。また、insertedID変数がまだ1に設定されているという問題も解決しません。

TableAdapterで秒を作成し、TypedDataSet.XSDそのアダプタのプロパティを「スカラー」に設定しようとしましたが、変数が値1を取得しても失敗します。

生成された挿入コマンドは

INSERT INTO [dbo].[Sites] ([Name], [Description]) VALUES (@Name, @Description);
SELECT Id, Name, Description FROM Sites WHERE (Id = SCOPE_IDENTITY())

また、「データテーブルの更新」(IDを取得するためのInsertステートメントとUpdateステートメントの後にselectステートメントを追加する)も設定されています。

環境

SQL Server 2008 R2、Visual Studio 2010、.NET 4、Windows XP、すべてローカルの同じマシン。

これは何が原因ですか?

編集/更新

VisualStudio内で自動生成されたコードを使用していることを明確にしたい。コードを生成した「ツール」が何であるかはわかりませんが、*。XSDファイルをダブルクリックすると、SQLテーブルスキーマと関連するTableAdapterのUIが表示されます。自動生成されたコードを使い続け、どういうわけかIDの取得を有効にしたい。ストアドプロシージャを使用して、これをすべて手作業で記述したくありません。

4

7 に答える 7

7

本当の答え:

  • 以下の注意事項をお読みください。

tableadapter挿入関数からIDを取得します

私はこの問題について頻繁に質問を受け続け、それを書き留める時間がありませんでした。

問題は次のとおりです。int型がIdentityとして定義された主キーを持つテーブルがあり、挿入後、新しく挿入された行のPK値を知る必要があります。これを実行するための手順は次のとおりです。

ウィザードを使用して、クエリの本文に新しい挿入クエリ(InsertQueryと呼びます)を追加します。このクエリを保存した後、下部にSELECT SCOPE_IDENTITY()を追加し、このクエリのExecuteModeプロパティをNonQueryからScalarに変更します。 TableAdapterインスタンス):

int id;

try
{
 id = Convert.toInt32(ta.InsertQuery(firstName, lastName, description));
}
catch (SQLException ex)
{
//...
}
finally
{
//...
}

これでお金を稼ごう!:)DraškoSarićによって2009年3月12日に投稿されました

差出人:http : //quickdeveloperstips.blogspot.nl/2009/03/get-identity-from-tableadapter-insert.html

ノート:

  • ExecutModeScalarに設定するには、生成された挿入クエリのプロパティを使用します。(F4を押します)。

  • 私のバージョン(Visual Studio 2010 SP1)では、selectステートメントが自動的に生成されました。

于 2012-06-21T08:59:03.510 に答える
4

これが私のSQLコードです。

CREATE PROCEDURE [dbo].[Branch_Insert]
(
    @UserId uniqueidentifier,
    @OrganisationId int,
    @InsertedID int OUTPUT
)
AS
    SET NOCOUNT OFF;
INSERT INTO [Branch] ([UserId], [OrganisationId]) 
VALUES (@UserId, @OrganisationId);

SELECT Id, UserId, OrganisationId FROM Branch WHERE (Id = SCOPE_IDENTITY())
SELECT @InsertedID = SCOPE_IDENTITY()

次に、テーブルアダプタを作成すると、@InsertedIDパラメータがすぐに表示されます。

次に、コードから、私がすることは次のとおりです。

int? insertedId = 0;
branchTA.Insert(userId, orgId, ref insertedId);

refを使用することが最良のオプションであるかどうかは、100%ではありませんが、これは私にとってはうまくいきます。

幸運を。

于 2010-09-13T21:23:57.227 に答える
3

すべての情報はここにありますが、完全な答えは1つも見つかりませんでした。そのため、私が使用する完全な手順は次のとおりです。

挿入クエリを追加SELECT SCOPE_IDENTITY()し、次のように追加します。

INSERT INTO foo(bar) VALUES(@bar);
SELECT SCOPE_IDENTITY()

必ず;を追加してください。VSが作成するINSERTステートメントの最後まで。

クエリの追加ウィザードを終了したら、デザインビューでクエリが選択されていることを確認しScalar、プロパティペインから[実行モード]をに変更します。

次のように、コードからクエリを呼び出すときは、必ずConvert.ToInt32()を使用してください。

id = Convert.ToInt32( dataTableAdapter.myInsertQuery("bar") )

Convert.ToInt32がないとコンパイラエラーは発生しませんが、間違った戻り値が発生します。

また、クエリを変更するときはいつでも、実行モードをにリセットする必要があります。これはScalar、VSがNon Query毎回クエリを元に戻すためです。

于 2013-12-06T23:33:19.860 に答える
1

これがあなたがそれをする方法です(ビジュアルデザイナーで)

  1. テーブルアダプタを右クリックし、[クエリの追加]を選択します
  2. SQLステートメント-更新を選択します(最適な自動生成パラメーター)
  3. SQLをコピーして貼り付けます。複数行にすることができます。複数のコマンドを解釈できないため、「クエリデザイナ」が開かないように注意してください。私の例では、次の「マージ」セットのサンプルを示しています。ステートメント(新しいサーバーにはマージコマンドがあることに注意してください)。

    UPDATE YOURTABLE
    SET  YourTable_Column1 = @YourTable_Column1, YourTable_Column2 = @YourTableColumn2
    WHERE (YourTable_ID = @YourTable_ID)
    IF @@ROWCOUNT=0
      INSERT INTO YOURTABLE ([YourTable_Column1], [YourTable_Column2])
      VALUES (@YourTable_Column1, @YourTable_Column2)
    @YourTable_ID = SCOPE_IDENTITY()
    
  4. クエリプロパティウィンドウ/サイドバーから@YourTable_IDパラメータを変更/追加します。パラメーターコレクションエディターでは、IDパラメーターにInputOutputの方向を指定する必要があります。これにより、テーブルアダプター関数が呼び出されたときに値が更新されます。(特記事項:Designerが「読み取り専用」としてこの列を持たないInputOutputの列を作成し、データ型も一致することを確認してください。そうでない場合は、データテーブルの列またはパラメーター情報を適宜変更してください)

これにより、このような単純なアクティビティのストアドプロシージャを作成する必要がなくなります。

わあ。このメソッドは、SQLプロシージャに侵入して大量のプロシージャを作成することなく、データレイヤ関数を実行するための高速な方法であることに気付くでしょう。唯一の問題は、あなたがしなければならないダンスがたくさんあるということです...

于 2014-06-05T15:33:48.543 に答える
0

IDを出力値として返すように挿入をセットアップしてから、アダプターのパラメーターとしてそれを取得する必要があります。

これらの2つのリンクはあなたを動かすはずです:

http://www.akadia.com/services/dotnet_autoincrement.html

http://msdn.microsoft.com/en-us/library/ks9f57t0.aspx

于 2010-09-13T21:11:14.387 に答える
0

正確に2つの選択肢があります。

  • SQLコードを手動で変更する
  • VisualStudioが生成するものは何でも使用してください

次のSQLとExecuteScalarを使用します。

INSERT INTO [dbo].[Sites] ([Name], [Description])
OUTPUT INSERTED.ID
VALUES (@Name, @Description);
于 2010-09-14T03:59:05.997 に答える
-1

1つの方法は、挿入コマンドの後にselectクエリを実行することです。良い方法は、次のように元のコマンドをラップすることです。

    public int WrapInsert(Parameters)
    {
        .....
        int RowsAffected = this.Insert(..Parameters..);
        if ( RowsAffected > 0)
        {
            try
            {
                SqlCommand cm = this.Connection.CreateCommand();
                cm.CommandText = "SELECT @@IDENTITY";
                identity = Convert.ToInt32(cm.ExecuteScalar());
            }
            finally
            {
                ....
            }
        }
        return RowsAffected;
    }
于 2010-09-13T21:21:28.707 に答える