存储过程中的多个游标,用于二级查找

时间:2018-02-14 17:57:20

标签: sql sql-server stored-procedures

我将两个参数传递给我的存储过程aCodebCode。我目前只有一个光标db_cursor正在使用aCode进行查找。

但是,如果没有从第一个游标返回的行,我需要进行第二级匹配并且还有一个带bCode的游标。

这可能吗?我怎样才能做到这一点?基本上,我需要先获取@ID才能进行更新/插入操作。 @aCode有90%的时间给我@ID,但是,如果@bCode没有给出,我需要使用@aCode获取@ID。 aCodebCode是数据库中的不同列。

另一个需要考虑的问题是,数据库中可能有多个IDs映射到一个aCodebCode,在这种情况下我需要更新两个ID。

ALTER PROCEDURE [dbo].[myproc]
    @aCode VARCHAR(50),
    @bCode VARCHAR(50),
    @ClosingPrice DECIMAL(28,4),
    @specialDate DATETIME,
    @person VARCHAR(50),
    @priced INT = NULL
AS
    SET @specialDate = LEFT(CONVERT(VARCHAR, @specialDate, 112), 8)
    SET @priced = (SELECT CASE WHEN @ClosingPrice > 0 THEN 1 ELSE 0 END)
BEGIN 
    DECLARE @ID INT

    DECLARE db_cursor CURSOR FOR
        SELECT sec.ID
        FROM dbo.Securities sec
        WHERE sec.aCode = @aCode

    OPEN db_cursor

    FETCH NEXT FROM db_cursor INTO @ID

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF EXISTS(SELECT 1 FROM Prices WITH (nolock)
                  WHERE DATEDIFF(YEAR, @specialDate, specialDate) = 0
                    AND DATEDIFF(MONTH, @specialDate, specialDate) = 0
                    AND DATEDIFF(DAY, @specialDate, specialDate) = 0
                    AND ID = @ID)
        BEGIN
            -- Update
            UPDATE dbo.Prices
            SET ClosingPrice = @ClosingPrice,
                UpdatedDate = GETDATE(),
                DownloadFileID = null,
                UpdatedByUser = @person,
                Priced = @priced
            WHERE
                DATEDIFF(YEAR, @specialDate, specialDate) = 0
                AND DATEDIFF(MONTH, @specialDate, specialDate) = 0
                AND DATEDIFF(DAY, @specialDate, specialDate) = 0
                AND ID = @ID
        END
        ELSE
        BEGIN
            -- Insert
            INSERT INTO dbo.Prices (ID, ClosingPrice, specialDate, UpdatedDate, UpdatedByUser, Priced)
            VALUES (@ID, @ClosingPrice, @specialDate, GETDATE(), @person, @priced)
        END

        FETCH NEXT FROM db_cursor INTO @ID;
    END

    CLOSE db_cursor
    DEALLOCATE db_cursor
END

2 个答案:

答案 0 :(得分:0)

如果使用Post.create(title: "Sample title" , body: "Sample Body"),则可以检查填充游标的查询是否返回任何行。如果是,请保留原始值,如果不是@aCode

set @aCode = @bCode

答案 1 :(得分:0)

在这里使用的细节不是很多,但很确定可以删除此光标并使用基于这些行的集合。

ALTER PROCEDURE [dbo].[myproc]
(
    @aCode VARCHAR(50),
    @bCode VARCHAR(50),
    @ClosingPrice DECIMAL(28,4),
    @specialDate DATETIME,
    @person VARCHAR(50),
    @priced INT = NULL
) as
    set nocount on;

    UPDATE p
    SET ClosingPrice = @ClosingPrice,
        UpdatedDate = GETDATE(),
        DownloadFileID = null,
        UpdatedByUser = @person,
        Priced = @priced
    from Prices p
    join Securities s on s.ID = p.ID
    WHERE convert(date, @specialDate) = convert(date, specialDate)
        and s.aCode in (@aCode, @bCode)


    if @@ROWCOUNT = 0
        INSERT INTO dbo.Prices
        (
            ID
            , ClosingPrice
            , specialDate
            , UpdatedDate
            , UpdatedByUser
            , Priced
        )
        select sec.ID
            , @ClosingPrice
            , LEFT(CONVERT(VARCHAR, @specialDate, 112), 8)
            , GETDATE()
            , @person
            , CASE WHEN @ClosingPrice > 0 THEN 1 ELSE 0 END
        from dbo.Securities sec
        WHERE sec.aCode in (@aCode, @bCode)