2

DBDirectMethodsを使用して、ストアドプロシージャの呼び出しを使用してデータベースにデータを挿入する、強く型付けされたデータセットがあります。ストアドプロシージャは、新しく作成されたレコードの主キーを返します。ストアドプロシージャの例は次のとおりです。

CREATE PROCEDURE dbo.CreateUser
(
    @UserName   VARCHAR(50)
    @Password   VARCHAR(50)
)
AS

SET NOCOUNT OFF

DECLARE @UserID INT

BEGIN TRANSACTION

INSERT INTO dbo.Users (UserName, Password) VALUES (@UserName, @Password)

SET @UserID = SCOPE_IDENTITY()

INSERT INTO dbo.Users_History (UserID, Status, TimeStamp) VALUES (@UserID, 'C', GETUTCDATE())

COMMIT TRANSACTION

RETURN @UserID

GO

SSMSからストアドプロシージャを実行すると、ユーザーアカウントが作成され、履歴テーブルが更新され、主キーが返されます。強く型付けされたデータセットを使用してアプリケーションを実行し、SQLプロファイラーをチェックすると、同じコードが実行されていることがわかります。ただし、データセットは主キーとして-1を返し、アプリを破壊します。

テーブルアダプタ用にVSで生成されたコード内で、関連する行は次のとおりです。

this._adapter.InsertCommand.CommandText = "dbo.CreateUser";
this._adapter.InsertCommand.CommandType = global::System.Data.CommandType.StoredProcedure;
this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.ReturnValue, 10, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@UserName", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Password", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "Password", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));

try {
    int returnValue = this.Adapter.InsertCommand.ExecuteNonQuery();
    return returnValue;
}
finally {
    if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
        this.Adapter.InsertCommand.Connection.Close();
    }
}

これはすべて、VSが通常生成する標準の定型コードです。手動で編集されたものはありません。戻り値を取得しないだけです。

SQL 2008 R2SP1ExpressでWindows7を実行しています。

4

3 に答える 3

2

PKだけを返すのではなく、新しいレコード全体を返す必要があるようです。ストアドプロシージャを次のように変更します。

CREATE PROCEDURE dbo.CreateUser
(
    @UserName   VARCHAR(50)
    @Password   VARCHAR(50)
)
AS

SET NOCOUNT OFF

DECLARE @UserID INT

BEGIN TRANSACTION

INSERT INTO dbo.Users (UserName, Password) VALUES (@UserName, @Password)

SET @UserID = SCOPE_IDENTITY()

INSERT INTO dbo.Users_History (UserID, Status, TimeStamp) VALUES (@UserID, 'C', GETUTCDATE())

COMMIT TRANSACTION

SELECT UserID, UserName, Password FROM dbo.Users WHERE UserID = @UserID

GO

次に、ADO.NETは返された結果をデータセットに自動的にロードし、そこからUserIDを取得できます。

于 2012-08-07T00:18:09.457 に答える
2

メモリから、ここでの問題は、ExecuteNonQuery()が返す値が、クエリの影響を受ける行の数であるということです。

代わりに、戻り値には次の方法でアクセスできる必要があります。

InsertCommand.Parameters["@RETURN_VALUE"].Value;

また

InsertCommand.Parameters[0].Value;

@UserIDさらに、戻りパラメーター名をではなくに変更してみることができますが、@RETURN_VALUEそれでもそのまま機能するはずです。

于 2012-08-06T08:11:11.643 に答える
0

クエリの種類をExecuteNonQueryからExecuteScalarに変更する必要があります。http://blogs.msdn.com/b/smartclientdata/archive/2005/10/31/returnidentityvaluequery.aspxを参照してください

于 2013-01-06T14:57:21.193 に答える