返回仅从存储过程中的一个命令中删除的行数

时间:2015-01-19 15:03:52

标签: c# sql-server stored-procedures

我的存储过程正在返回其他一些数字,我无法理解它。这是程序:

CREATE PROCEDURE DeleteCandidate(@candidate_id int) AS
BEGIN
    DECLARE @NumCandidatesDeleted AS int;
    SET @NumCandidatesDeleted = 0;
    SET XACT_ABORT ON;
    BEGIN TRANSACTION ucDelCand

        /* I've removed some code from here for brevity */

        DELETE FROM [answers] WHERE [candidate_id] = @candidate_id;
        DELETE FROM [documents] WHERE [candidate_id] = @candidate_id;

        DELETE FROM [candidates] WHERE [candidate_id] = @candidate_id;

        SET @NumCandidatesDeleted = @@ROWCOUNT;

    COMMIT TRANSACTION ucDelCand

    SELECT @NumCandidatesDeleted;
END

这是我的C#(winforms)调用代码:

var cmd = new SqlCommand("DeleteCandidate", conn);
cmd.Parameters.AddWithValue("@candidate_id", CandidateId);

var rows = cmd.ExecuteScalar(); // This seems to return a variety of int values

我也在SP中尝试了RETURN (@NumCandidatesDeleted)。我错过了什么?!!

修改
我只想返回被删除的候选人数。即来自最终delete的受影响的行。

解决方案(问题?):
答案是:我发布的代码应该按预期工作 问题是“我为简洁而删除的代码”(抱歉)。我仍然不会发布所有内容,因为......简洁。但是,违规行是之前的另一个SELECT声明。因此,当调用ExecuteScalar时,它给了我第一个SELECT而不是最后一个{{1}}。

对于处于类似困境的下一个想法者 - 请务必在SQL Server Management Studio中尝试存储过程。如果您删除代码以使其更简洁...请说明您所做的事情(抱歉。再次。)。


感谢所有回答和回应的人。很大的帮助。希望下一只猴子坚持使用存储过程返回值找到这个并且也有帮助!

2 个答案:

答案 0 :(得分:0)

您可以尝试重构存储过程以包含OUTPUT参数: 由于@@ROWCOUNT返回受最后一个语句影响的行数,因此需要使用@@ROWCOUNT值填充变量,然后在每个delete语句之后递增它以捕获正确删除的行数。您可以在MSDN上阅读有关@@ROWCOUNT的更多信息:

CREATE PROCEDURE DeleteCandidate 
      @candidate_id INT, 
      @total_deletions INT OUTPUT 
AS
BEGIN
    DECLARE @NumCandidatesDeleted AS int;
    SET @NumCandidatesDeleted = 0;
    SET XACT_ABORT ON;
    BEGIN TRANSACTION ucDelCand

        DELETE FROM [answers] WHERE [candidate_id] = @candidate_id;
        SELECT @NumCandidatesDeleted = @@ROWCOUNT;

        DELETE FROM [documents] WHERE [candidate_id] = @candidate_id;
        SELECT @NumCandidatesDeleted = @NumCandidatesDeleted + @@ROWCOUNT;

        DELETE FROM [candidates] WHERE [candidate_id] = @candidate_id;
        SELECT @NumCandidatesDeleted = @NumCandidatesDeleted + @@ROWCOUNT;    

    COMMIT TRANSACTION ucDelCand

    SELECT @NumCandidatesDeleted;
END

C#

var cmd = new SqlCommand("DeleteCandidate", conn);
cmd.Parameters.AddWithValue("@candidate_id", CandidateId);
SqlParameter output = new SqlParameter("@total_deletions", SqlDbType.Int);
output.Direction = ParameterDirection.Output;
cmd.Parameters.Add(output);
cmd.ExecuteNonQuery();
var rows = output.Value;

答案 1 :(得分:-1)

试试这个

Declare @tempTable as table
(
pkid bigint null,
tablename nvarchar(200)
)

Delete Tablename
OUTPUT Deleted.pkid,'Tablename'
INTO @tempTable 
From Tablename

以上代码中的代码

CREATE PROCEDURE DeleteCandidate(@candidate_id int) AS
BEGIN
SET XACT_ABORT ON;
BEGIN TRANSACTION ucDelCand

DECLARE @tempTable as TABLE 
( 
    pkid bigint null, 
    tablename nvarchar(200) 
)

DELETE [answers]
OUTPUT DELETED.candidate_id, 'answers'
INTO @tempTable 
FROM [answers] WHERE [candidate_id] = @candidate_id;

DELETE [documents]
OUTPUT DELETED.candidate_id, 'documents'
INTO @tempTable
FROM [documents] WHERE [candidate_id] = @candidate_id;

DELETE [candidates]
OUTPUT DELETED.candidate_id, 'candidates'
INTO @tempTable
FROM [candidates] WHERE [candidate_id] = @candidate_id;

SELECT COUNT(pkid), tablename
FROM @tempTable
GROUP BY tablename

COMMIT TRANSACTION ucDelCand
END