为什么我的存储过程返回-1?

时间:2018-03-06 22:02:57

标签: sql-server entity-framework tsql stored-procedures

我有一个存储过程。对它的调用返回-1。这是什么意思?

以下是调用存储过程的代码(由Entity Framework自动生成):

public virtual int DeleteProjectData(Nullable<int> projectId, string deleteType, string username)
{
    var projectIdParameter = projectId.HasValue ?
                new ObjectParameter("projectId", projectId) :
                new ObjectParameter("projectId", typeof(int));

    var deleteTypeParameter = deleteType != null ?
                new ObjectParameter("deleteType", deleteType) :
                new ObjectParameter("deleteType", typeof(string));

    var usernameParameter = username != null ?
                new ObjectParameter("username", username) :
                new ObjectParameter("username", typeof(string));

    int result = ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("DeleteProjectData", 

projectIdParameter, deleteTypeParameter, usernameParameter);

    return result; // result is -1
}

这是存储过程:

ALTER PROCEDURE [dbo].[DeleteProjectData]
    @projectId INT,
    @deleteType VARCHAR(10),
    @username NVARCHAR(255)
AS
    SET NOCOUNT ON

    BEGIN TRY

    DECLARE @realProjectId      INT = NULL,
            @isTemplate         BIT,
            @ErrorMessage       NVARCHAR(4000),
            @deleteTypeAll      VARCHAR(10),
            @deleteTypeNodes    VARCHAR(10)

    DECLARE @usernameBinary VARBINARY(255)
    SET @usernameBinary = CAST(@username AS VARBINARY(255))
    SET CONTEXT_INFO @usernameBinary

    SELECT @deleteTypeAll = 'All',
           @deleteTypeNodes = 'Nodes'

    -- ensure the input project exists and is not a template
    SELECT @realProjectId = ProjectId
    FROM Project
    WHERE ProjectId = @projectId

    IF @deleteType NOT IN (@deleteTypeAll, @deleteTypeNodes)
        BEGIN
        -- create a the error message for a project that does not exist            
        SELECT @ErrorMessage = N'The input Delete Type is not valid. Valid values are: ''' + @deleteTypeAll 
                                 + ''' and ''' + @deleteTypeNodes + ''''

        -- raise the error
        RAISERROR (@ErrorMessage, 16, 1)

        END

    IF @realProjectId IS NULL
        BEGIN
        -- create a the error message for a project that does not exist            
        SELECT @ErrorMessage = N'The input ProjectId does not have a corresponding Project record. No calculations will 

be performed. ProjectId: ' + CAST(@projectId AS VARCHAR)

        -- raise the error
        RAISERROR (@ErrorMessage, 16, 1)

        END

    BEGIN TRANSACTION

    -- If deleting all, delete all reports associated with project first:
    IF @deleteType = @deleteTypeAll
        BEGIN

        DELETE [dbo].[ReportComment]
        WHERE ReportId in (SELECT ReportId
        FROM [dbo].[Report]
        WHERE ProjectId = @realProjectId)

        DELETE [dbo].[ReportMetric]
        WHERE ReportId in (SELECT ReportId
        FROM [dbo].[Report]
        WHERE ProjectId = @realProjectId)

        DELETE [dbo].[ReportTopN]
        WHERE ReportId in (SELECT ReportId
        FROM [dbo].[Report]
        WHERE ProjectId = @realProjectId)

        DELETE [dbo].[Report]
        WHERE ReportId in (SELECT ReportId
        FROM [dbo].[Report]
        WHERE ProjectId = @realProjectId)

        END
    ELSE
        BEGIN

        DELETE [dbo].[ReportTopN]
        WHERE ReportId in (SELECT ReportId
        FROM [dbo].[Report]
        WHERE ProjectId = @realProjectId)

        END

    IF @deleteType IN (@deleteTypeAll, @deleteTypeNodes)
        BEGIN
        DECLARE @Keys TABLE (
            ProjectId INT,
            NodeId INT,
            DeviationId INT,
            CauseId INT,
            ConsequenceId INT,
            SafeguardId INT,
            RecommendationId INT,
            RemarkId INT,
            DrawingId INT,
            RiskDataId INT,
            BowtieLoopId INT,
            BowtieId INT)

        -- build a list of keys associated with the project (simplifies delete queries)
        INSERT INTO @Keys (ProjectId,
                           NodeId,
                           DeviationId,
                           CauseId,
                           ConsequenceId,
                           SafeguardId,
                           RecommendationId,
                           RemarkId,
                           DrawingId,
                           RiskDataId,
                           BowtieLoopId,
                           BowtieId)
            SELECT p.ProjectId,
                   n.NodeId,
                   d.DeviationId,
                   ca.CauseId,                 
                   co.ConsequenceId,
                   s.SafeguardId,
                   r.RecommendationId,
                   re.RemarkId,
                   dr.DrawingId,
                   rd.RiskDataId,
                   bl.BowtieLoopId,
                   b.BowtieId
            FROM Project p
                 LEFT OUTER JOIN Node n
                    ON p.ProjectId = n.ProjectId
                 LEFT OUTER JOIN Deviation d
                    ON n.NodeId = d.NodeId
                 LEFT OUTER JOIN Cause ca
                    ON d.DeviationId = ca.DeviationId
                 LEFT OUTER JOIN Consequence co
                    ON ca.CauseId = co.CauseId
                 LEFT OUTER JOIN Safeguard s
                    ON co.ConsequenceId = s.ConsequenceId
                 LEFT OUTER JOIN Recommendation r
                    ON co.ConsequenceId = r.ConsequenceId
                 LEFT OUTER JOIN Remark re
                    ON co.ConsequenceId = re.ConsequenceId
                 LEFT OUTER JOIN Drawing dr
                    ON r.RecommendationId = dr.RecommendationId
                 LEFT OUTER JOIN Bowtie b 
                    ON b.ProjectId = p.ProjectId
                 LEFT OUTER JOIN BowtieLoop bl
                    ON bl.BowtieId = b.BowtieId
                 LEFT Outer JOIN RiskData rd
                    ON rd.BowtieLoopId = bl.BowtieLoopId

            WHERE p.ProjectId = @realProjectId

        -- delete the data that was imported 

        DELETE FROM Drawing
        WHERE DrawingId IN (SELECT DISTINCT DrawingId
                            FROM @Keys)

        DELETE FROM Recommendation
        WHERE RecommendationId IN (SELECT DISTINCT RecommendationId
                                   FROM @Keys)

        DELETE FROM Safeguard
        WHERE SafeguardId IN (SELECT DISTINCT SafeguardId
                              FROM @Keys)

        DELETE FROM Remark
        WHERE RemarkId IN (SELECT DISTINCT RemarkId
                           FROM @Keys)

        DELETE FROM Consequence
        WHERE ConsequenceId IN (SELECT DISTINCT ConsequenceId
                                FROM @Keys)

        DELETE FROM CauseToBowtieLoopDetails
        Where CauseId IN (Select Distinct CauseId 
                          FROM @Keys)

        DELETE FROM Cause
        WHERE CauseId IN (SELECT DISTINCT CauseId
                          FROM @Keys)       

        DELETE FROM Deviation
        WHERE DeviationId IN (SELECT DISTINCT DeviationId
                              FROM @Keys)

        DELETE FROM Node
        WHERE NodeId IN (SELECT DISTINCT NodeId
                         FROM @Keys)

        DELETE FROM RiskData
        WHERE RiskDataId IN (SELECT DISTINCT RiskDataId
                          FROM @Keys)   

        DELETE FROM BowtieLoop
        WHERE BowtieLoopId IN (SELECT DISTINCT BowtieLoopId
                          FROM @Keys)

        DELETE FROM BowtieToEquipmentLookup
        WHERE BowtieId IN (SELECT DISTINCT BowtieId
                            FROM @Keys)

        DELETE FROM Bowtie
        WHERE BowtieId IN (SELECT DISTINCT BowtieId
                          FROM @Keys)   

        DELETE FROM ProjectDeviation
        WHERE ProjectId = @realProjectId

        DELETE FROM ProjectSafeguard
        WHERE ProjectId = @realProjectId

        DELETE FROM ProjectRecommendation
        WHERE ProjectId = @realProjectId

        -- also delete from the metrics tables

        DELETE FROM ProjectMetrics
        WHERE ProjectId = @realProjectId

        DELETE FROM CauseMetrics
        WHERE ProjectId = @realProjectId

        DELETE FROM ConsequenceMetrics
        WHERE ProjectId = @realProjectId

        DELETE FROM RecommendationMetrics
        WHERE ProjectId = @realProjectId

        DELETE FROM SafeguardMetrics
        WHERE ProjectId = @realProjectId        

        END

    IF @deleteType = @deleteTypeAll
        BEGIN

        -- delete the project specific data (i.e., data not imported)

        DELETE FROM RiskMatrixAxis
        WHERE ProjectId = @realProjectId

        DELETE FROM SafeRecCategory
        WHERE ProjectId = @realProjectId

        DELETE FROM Participant
        WHERE ProjectId = @realProjectId

        DELETE FROM RiskRanking
        WHERE ProjectId = @realProjectId

        DELETE FROM Category
        WHERE ProjectId = @realProjectId

        DELETE FROM ImportFile
        WHERE ProjectId = @realProjectId

        DELETE FROM Project
        WHERE ProjectId = @realProjectId

        END

    COMMIT TRANSACTION

    END TRY

    BEGIN CATCH

        IF(@@TRANCOUNT > 0)
            BEGIN
            -- rollback all changes if any error occurred
            ROLLBACK TRANSACTION
            END

            -- raise the original error
        EXEC RethrowError;
    END CATCH

如您所见,存储过程不会返回任何内容。我告诉过,如果它没有返回任何内容,那么运行存储过程的Entity Framework调用将返回行数。那么它返回-1意味着什么呢?我是否正确将-1解释为错误?

1 个答案:

答案 0 :(得分:2)

来自Microsoft doc on ExecuteNonQuery(here):

  

对于UPDATE,INSERT和DELETE语句,返回值为   受命令影响的行数。当a上存在触发器时   正在插入或更新的表,返回值包括数字   受插入或更新操作影响的行数和数字   受触发器或触发器影响的行数。对于所有其他类型的   语句,返回值为-1。如果发生回滚,则返回   值也是-1。

由于您正在调用proc,但尝试将其视为函数,我认为检索它的返回值会导致相同的行为。