Friday, April 24, 2015

@@FETCH_STATUS in nested loops

It basically works, e.g.

DECLARE tables CURSOR FOR
        SELECT object_id, name FROM sys.tables;
DECLARE @object_id INT;
DECLARE @name SYSNAME;
DECLARE @NO_ERROR INT = 0;

OPEN tables;
FETCH NEXT FROM tables INTO @object_id, @name;
WHILE @@FETCH_STATUS = @NO_ERROR
BEGIN
        PRINT @name;

        DECLARE columns CURSOR FOR
                SELECT name FROM sys.columns WHERE object_id = @object_id;
        OPEN columns;
        WHILE @@FETCH_STATUS = @NO_ERROR
        BEGIN
                PRINT '    ' + @name;       
                FETCH NEXT FROM columns INTO @name;
        END;
        CLOSE columns;
        DEALLOCATE columns;

        FETCH NEXT FROM tables INTO @object_id, @name;
END;
CLOSE tables;
DEALLOCATE tables;

But there's offten no need for nesting it:

DECLARE both CURSOR FOR
        SELECT T.name, C.name FROM sys.tables T
                INNER JOIN sys.columns C ON C.object_id = T.object_id;;
DECLARE @table_name SYSNAME;
DECLARE @column_name SYSNAME;
DECLARE @last_name SYSNAME;
DECLARE @NO_ERROR INT = 0;

SET @last_name = '';
OPEN both;
FETCH NEXT FROM both INTO @table_name, @column_name;
WHILE @@FETCH_STATUS = @NO_ERROR
BEGIN
        IF ( @last_name != @table_name )
        BEGIN
                PRINT @table_name;
                PRINT '    ' + @column_name;
        END
        ELSE
        BEGIN
                PRINT '    ' + @column_name;
        END;

        SET @last_name = @table_name;
        FETCH NEXT FROM both INTO @table_name, @column_name;
END;
CLOSE both;
DEALLOCATE both;

So check your conditions in both cursor definitions.

No comments:

Post a Comment