How do I pass a parameter in a stored procedure lo

2020-05-08 08:08发布

问题:

How do I create a stored procedure which can be passed a @CandidatelistID as a parameter to the existing stored procedure logic below.

I am looping the CandidateID and CandidateListID and running a stored procedure usp_ApplyRankingRules inside the loop to get the Weightage for each of them.

Then instead of insert and update the values in a table - RPT_CandidateCardReport I want to load the same fields in a temp table. When I am doing that I am getting the following error -

(0 row(s) affected)

(0 row(s) affected)
Msg 208, Level 16, State 0, Procedure usp_RPT_CandidateCardReporttest, Line     24 [Batch Start Line 53]
Invalid object name '#tempRPTCandidateCardReport'.

The data is present in the tables I am trying to loop and should show display the result from the temptable select statement at the bottom..

CREATE PROCEDURE [dbo].[usp_RPT_CandidateCardReporttest]     @candidateListIDs varchar(36)
    AS
    BEGIN
declare @candidateListID varchar(36)
declare @candidateID varchar(36)
declare @var_weightage decimal
declare @listcount INT = (SELECT COUNT(1) FROM CandidateList_Candidates)
declare @loopcount INT = 1


IF OBJECT_ID('tempdb..#tmpListCandidate') IS NOT NULL DROP TABLE #tmpListCandidate
SELECT CandidateListID, CandidateID, ROW_NUMBER()OVER(ORDER BY cl.CandidateID) AS Id INTO #tmpListCandidate 
FROM CandidateList_Candidates cl
where CandidateListID = @candidateListIDs

WHILE(@loopcount <= @listcount)
    BEGIN
        SET @candidateListID = (SELECT CandidateListID FROM #tmpListCandidate WHERE Id = @loopcount)
        SET @candidateID = (SELECT CandidateID FROM #tmpListCandidate WHERE Id = @loopcount)

        EXEC usp_ApplyRankingRules @candidateListID, @candidateID, @var_weightage OUTPUT

        IF EXISTS (SELECT 1 FROM #tempRPTCandidateCardReport WHERE listID = @candidateListID AND candidateID = @candidateID)
            BEGIN
                UPDATE #tempRPTCandidateCardReport SET weightage = @var_weightage WHERE listID = @candidateListID AND candidateID = @candidateID
            END
        ELSE
            BEGIN    
                INSERT INTO #tempRPTCandidateCardReport (listID, candidateID, weightage)
                    VALUES (@candidateListID, @candidateID, @var_weightage) 
            END
        SET @loopcount = @loopcount + 1
    END

select listid,candidateid,weightage from #tempRPTCandidateCardReport

IF OBJECT_ID('tempdb..#tmpListCandidate') IS NOT NULL 
BEGIN 
    DROP TABLE #tmpListCandidate
    DROP TABLE #tempRPTCandidateCardReport
END

END GO

回答1:

I'm not going to comment on several aspects of the stored procedure, but I think you want:

CREATE PROCEDURE [dbo].[usp_RPT_CandidateCardReporttest] ( 
   @candidateListID varchar(36)
)
AS
BEGIN
    . . . 
    SELECT CandidateListID, CandidateID, 
           ROW_NUMBER() OVER (ORDER BY cl.CandidateID) AS Id 
    INTO #tmpListCandidate 
    FROM CandidateList_Candidates cl
    WHERE CandidateListID = @CandidateListID OR @CandidateListID IS NULL;

    SELECT @ListCounct = COUNT(*)
    FROM #tmpListCandidate ;

    . . .
END;

Notes:

  • Set the row count based on the number of rows in the temporary table. The above code uses SELECT COUNT(*) to be explicit, but @@ROWCOUNT would work just as well.
  • There is no need to delete the temporary table or to test for its existence. Temporary tables will only "live" for the duration of each call of the stored procedure.
  • BUT . . . I would actually recommend using a cursor instead. I'm not a fan of cursors, but the use-case of calling a stored procedure for each row of a result set is definitely one place where they are helpful. Not temporary table or looping values would then be necessary.

If you are going to loop through a temporary table (or table variable), then code such as this:

   SET @candidateListID = (SELECT CandidateListID FROM #tmpListCandidate WHERE Id = @loopcount)
   SET @candidateID = (SELECT CandidateID FROM #tmpListCandidate WHERE Id = @loopcount)

Can be replaced with:

SELECT @candidateListID = CandidateListID,
       @candidateID = CandidateID
FROM #tmpListCandidate
WHERE Id = @loopcount;