为什么游标不会在SQL中停止

时间:2018-03-25 07:16:46

标签: sql-server tsql cursor

我运行以下代码在SQL Server中执行我的存储过程,但是在运行此游标并更新存储过程中的列之后,此游标不会停止并继续执行。你能给我一些想法吗?

DECLARE @MyCursor CURSOR;
DECLARE @id AS INT
DECLARE @asin AS NVARCHAR(50)
DECLARE @date AS DATE

BEGIN
    SET @MyCursor = CURSOR FOR
                        SELECT id, asin, ReviewDate 
                        FROM software

    OPEN @MyCursor 

    FETCH NEXT FROM @MyCursor INTO @id , @asin, @date

    WHILE @@FETCH_STATUS = 0
    BEGIN
        EXEC [dbo].[SP_Review_Group_Agreemnet] @id, @asin, @date
        --print @id

        FETCH NEXT FROM @MyCursor INTO @id, @asin, @date
    END; 

    CLOSE @MyCursor ;
    DEALLOCATE @MyCursor;
END;

存储过程如下所示:

GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[SP_Review_Group_Agreemnet]  
    @id AS INT, 
    @asin AS NVARCHAR(50), 
    @date AS DATE   -- @Product_Second_Date
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @number_of_day AS INT 

    SET @number_of_day = (SELECT dbo.fn_date_copy(@asin, 1)) 

    DECLARE @after_day AS DATE
    SET @after_day = DATEADD(d, @number_of_day, @date)

    DECLARE @previous_day AS DATE
    SET @previous_day = DATEADD(d, -@number_of_day, @date)

    DECLARE @avg_prev AS FLOAT
    SET @avg_prev= (SELECT ROUND(AVG(overall), 2) 
                    FROM Software 
                    WHERE (ReviewDate BETWEEN @previous_day AND @date) 
                      AND asin = @asin AND id != @id)

    DECLARE @avg_after AS FLOAT
    SET @avg_after = (SELECT ROUND(AVG(overall), 2) 
                      FROM Software 
                      WHERE (ReviewDate BETWEEN @date AND @after_day) 
                        AND asin = @asin AND id != @id)     

    UPDATE dbo.software 
    SET Review_Group_Agreement = t.agreement 
    FROM 
        (SELECT
             id, 
             (CASE WHEN ABS(overall - @avg_after) <= 1 OR
                        ABS(overall - @avg_prev) < 1 
                      THEN 1
                      ELSE 0
              END) AS agreement
         FROM 
             Software) AS t
    WHERE
        Software.id = t.id
END

,功能是:

USE [ReviewDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[fn_date_copy]
     (@asin NVARCHAR(50), @baze AS INT)
RETURNS INT
AS
BEGIN
    DECLARE @DateDiff AS INT
    DECLARE @Quotient AS INT 
    DECLARE @Remainder AS INT 
    DECLARE @Number_of_Days AS INT 

    SET @DateDiff = (SELECT DATEDIFF(d, First_Date, Last_Date)  
                     FROM metaData 
                     WHERE asin = @asin)
    SET @Quotient = @DateDiff * @baze / 100
    SET @Remainder = @DateDiff * @baze % 100

    IF @Remainder != 0
       SET @Number_of_Days = @Quotient + 1
    ELSE
       SET @Number_of_Days = @Quotient

    RETURN @Number_of_Days
END

最后表的结构是:

CREATE TABLE [dbo].[Software]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [reviewerID] [nvarchar](28) NULL,
    [asin] [nvarchar](18) NULL,
    [reviewerName] [nvarchar](60) NULL,
    [helpful] [int] NULL,
    [overall] [float] NULL,
    [unixReviewTime] [int] NULL,
    [reviewTime] [nvarchar](15) NULL,
    [ReviewDate] [date] NULL,
    [Review_Group_Agreement] [int] NULL,
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

0 个答案:

没有答案