T-SQL嵌套游标带参数

时间:2016-07-01 07:06:39

标签: sql-server tsql

我有两个游标,我想循环第一个游标,并使用其值作为第二个游标的参数,然后进行一些处理。我知道如何在PL-SQL中执行此操作,但T-SQL让我感到困惑。

到目前为止我已经到了。由于某种原因,嵌套游标不会打印任何内容。

DECLARE @period DATE
DECLARE @table_type VARCHAR(2)
DECLARE @clmn_clr VARCHAR(100)
DECLARE @clmn_per VARCHAR(100)
DECLARE @period_num INT
DECLARE @period_date DATE
DECLARE @table_type2 VARCHAR(2)

DECLARE c_table CURSOR FOR SELECT   period,
                                    table_type
                            FROM    #period_table
DECLARE c_period CURSOR LOCAL FAST_FORWARD FOR SELECT   clmn_clr,
                                                        clmn_per,
                                                        period_num,
                                                        period_date,
                                                        table_type
                                                 FROM   #column_period
                                                 WHERE  table_type = @table_type

OPEN c_table
    FETCH NEXT FROM c_table
    INTO @period, @table_type
WHILE @@FETCH_STATUS = 0
BEGIN
    print @period
    print @table_type
    print '------------'
    FETCH NEXT FROM c_table
        INTO @period, @table_type

    --Nested cursor
    OPEN c_period
        FETCH NEXT FROM c_period
        INTO @clmn_clr, @clmn_per, @period_num, @period_date, @table_type2

    BEGIN
        print @clmn_clr
        print @clmn_per
        print @period_num
        print @period_date
        print @table_type2
        FETCH NEXT FROM c_period
            INTO @clmn_clr, @clmn_per, @period_num, @period_date, @table_type2
    END
    CLOSE c_period
    DEALLOCATE c_period
END
CLOSE c_table
DEALLOCATE c_table

它确实打印了游标c_table的第一行,但这就是全部。

此外,非常欢迎任何关于如何更好地在T-SQL中执行此操作的评论。

2 个答案:

答案 0 :(得分:1)

没有必要进行嵌套,这是唯一可以执行所有操作的游标:

DECLARE c_period CURSOR LOCAL FAST_FORWARD FOR
    SELECT  p.period,
            c.clmn_clr,
            c.clmn_per,
            c.period_num,
            c.period_date,
            c.table_type
    FROM   #period_table p
    INNER JOIN #column_period c
    ON c.table_type = p.table_type
    ORDER BY p.table_type

我从来没有对它进行过测试,但在我看来,MS并不认为MSSQL允许游标使用“动态参数绑定”之类的东西。自从你打开它 - 它已经完成了。如果应用appripriate选项,它只能对数据修改做出反应。

如果您仍需要为任何目的进行嵌套,则可以重新打开游标。从外部游标获取@table_type,然后DECLARE ... OPEN嵌套游标。

另请注意,要打印的字符串(如果这是您的真实主题)可以通过单个选择获得,不带任何游标(搜索“字符串聚合”用于mssql)。

答案 1 :(得分:0)

这是我找到的工作解决方案 - 我只将嵌套的光标移到了里面。

DECLARE @period DATE
DECLARE @table_type VARCHAR(2)

DECLARE @clmn_clr VARCHAR(100)
DECLARE @clmn_per VARCHAR(100)
DECLARE @period_num INT
DECLARE @period_date DATE
DECLARE @table_type2 VARCHAR(2)

DECLARE c_table CURSOR FOR SELECT   period,
                                    table_type
                            FROM    #period_table
--Fetch first row
OPEN c_table
    FETCH NEXT FROM c_table
    INTO @period, @table_type
--Loop starts here, until it is empty
WHILE @@FETCH_STATUS = 0
BEGIN
    print @period
    print @table_type
    print '----------'

    --Nested cursor
    DECLARE c_period CURSOR LOCAL FAST_FORWARD FOR SELECT   clmn_clr,
                                                            clmn_per,
                                                            period_num,
                                                            period_date,
                                                            table_type
                                                     FROM   #column_period
                                                     WHERE  table_type = @table_type
    OPEN c_period
        FETCH NEXT FROM c_period
        INTO @clmn_clr, @clmn_per, @period_num, @period_date, @table_type2
    WHILE @@FETCH_STATUS = 0
    BEGIN
        print @clmn_clr
        print @clmn_per
        print @period_num
        print @period_date
        print @table_type2
        FETCH NEXT FROM c_period
            INTO @clmn_clr, @clmn_per, @period_num, @period_date, @table_type2
    END
    CLOSE c_period
    DEALLOCATE c_period

    FETCH NEXT FROM c_table
        INTO @period, @table_type
END
CLOSE c_table
DEALLOCATE c_table