简体   繁体   English

强类型数据集无法从存储过程中获取返回值

[英]Strongly-typed dataset not retrieving return value from stored procedure

I have a strongly-typed dataset that is using DBDirectMethods to insert data into a database using calls to stored procedures. 我有一个强类型的数据集,它使用DBDirectMethods通过调用存储过程将数据插入数据库。 The stored procedures return the primary key of the newly-created record. 存储过程返回新创建的记录的主键。 Here's a sample stored procedure: 这是一个示例存储过程:

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

If I execute the stored procedure from SSMS, then the user account is created, the history table updated, and the primary key returned. 如果我从SSMS执行存储过程,则将创建用户帐户,更新历史记录表,并返回主键。 If I run my application using the strongly-typed dataset and have SQL Profiler ticking away, I can see the same code being executed; 如果我使用强类型的数据集运行应用程序,并且勾选了SQL事件探查器,则可以看到相同的代码正在执行。 however, the dataset returns -1 as the primary key and breaks the app. 但是,数据集返回-1作为主键并中断应用程序。

Inside the VS-generated code for the table adapter, the relevant lines are: 在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, "", "", ""));

and

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

which is all just the standard boiler-plate code that VS usually generates - nothing has been edited by hand. 这只是VS通常生成的标准样板代码-无需手动编辑任何内容。 It just doesn't pick up the return value. 它只是不获取返回值。

I am running Windows 7 with SQL 2008 R2 SP1 Express. 我正在运行Windows 7和SQL 2008 R2 SP1 Express。

From memory, the issue here is that the value ExecuteNonQuery () returns is the number of rows affected by the query. 从内存来看,这里的问题是ExecuteNonQuery ()返回的值是受查询影响的行数。

Instead, your return value should be accessible via: 相反,您的返回值应该可以通过以下方式访问:

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

or 要么

InsertCommand.Parameters[0].Value;

In addition, you can try changing your return parameter name to @UserID rather than @RETURN_VALUE but it should still work as you have it. 另外,您可以尝试将返回参数名称更改为@UserID而不是@RETURN_VALUE但是它仍然可以正常使用。

It seems that rather than returning only the PK, I need to return the entire new record. 似乎我不仅需要返回PK,还需要返回整个新记录。 By changing my stored procedure to the following: 通过将存储过程更改为以下内容:

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

then ADO.NET automatically loads the returned result into the dataset, and I can get UserID from there. 然后ADO.NET自动将返回的结果加载到数据集中,我可以从那里获取UserID。

您需要将查询类型从ExecuteNonQuery更改为ExecuteScalar,请参见http://blogs.msdn.com/b/smartclientdata/archive/2005/10/31/returnidentityvaluequery.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM