将嵌套游标存储过程更改为嵌套循环

时间:2019-05-14 13:50:53

标签: sql-server tsql while-loop cursor

我有一个存储过程,当前正在使用嵌套游标使用数据库,表,列参数建立视图。我需要将其更改为while循环查询。我知道结果是相同的,但我们只是不想使用游标。

由于动态SQL,这似乎非常棘手。

ALTER PROCEDURE [dbo].[spReCreateCommonViews_AK] 
AS
    DECLARE @Exec INT = 1, @Print INT = 2
    -- DECLARE @debug INT = @Exec
    DECLARE @debug INT = @Print

    DECLARE @Sql VARCHAR(MAX),
            @SourceName VARCHAR(100),
            @DatabaseName VARCHAR(100),
            @CompanyName VARCHAR(100),
            @ColumnCursor VARCHAR(800),
            @TableId INT,
            @TableName VARCHAR(100),
            @ColumnType INT,
            @ColumnName VARCHAR(100),
            @ColumnList VARCHAR(MAX) = '',
            @CreateViewSQL VARCHAR(MAX)

    /**  COMPANIES ********/
    DECLARE CompaniesCursor CURSOR FOR
        SELECT
            [Database],
            REPLACE(REPLACE(REPLACE([Name], '.', '_'), '/', '_'), '''', '_') AS [Name],
            CASE 
               WHEN RIGHT([Source], 7) = '_SOURCE'  
                  THEN '[' + [Source] + '].[' + [Database] + ']' 
                  ELSE '[' + [Database] + ']' 
            END AS [Source]
        FROM
            Company 

    OPEN CompaniesCursor
    FETCH NEXT FROM CompaniesCursor INTO @DatabaseName, @CompanyName, @SourceName

    WHILE @@fetch_status = 0
    BEGIN
        /**  TABLES  ***********/
        SELECT @Sql = 'DECLARE TablesCursor CURSOR FOR 
                                        select 
                                            o.[id] as TableId,
                                            o.[name] as TableName
                                        from '+@SourceName+'.dbo.sysobjects o 
                                        inner join '+@SourceName+'.dbo.[Object] t 
                                        on o.[name] = replace(replace(replace(t.[Name],''.'',''_''),''/'',''_''),'''''''',''_'')
                                        and t.[Company Name] = ''''
                                        and t.[Type] = 0
                                        where o.[name] <> ''Company''
                                        and o.[name] not like ''' + @CompanyName + '$%''
                                            and o.type = ''U'' 
                                        order by o.[name]

                                '

                                    exec(@Sql)
                                    open TablesCursor
                                    fetch next from TablesCursor into @TableId, @TableName
                                    while @@fetch_status = 0
                                    begin


                                                                                    /**  COLUMNS  ************************************************************/
                                                                                    select @ColumnCursor = 
                                                                                    '
                                                                                    declare ColumnsCursor cursor
                                                                                    for 
                                                                                        select ''['' + [name] + '']'' as ColumnName, xtype as ColumnType
                                                                                        from '+@SourceName+'.dbo.syscolumns 
                                                                                        where [id] = ' + convert(varchar, @TableId) + '
                                                                                        order by colid
                                                                                    '
                                                                                    exec(@ColumnCursor)
                                                                                    open ColumnsCursor
                                                                                    fetch next from ColumnsCursor into @ColumnName, @ColumnType
                                                                                    while @@fetch_status = 0
                                                                                    begin

                                                                                                                                    select @ColumnList = @ColumnList + @ColumnName + case when @ColumnType in (35, 99, 167, 175, 231, 239) then ' collate database_default as ' + @ColumnName + ', ' else ', ' end


                                                                                    -----------------------------
                                                                                    fetch next from ColumnsCursor into @ColumnName, @ColumnType
                                                                                    end
                                                                                    close ColumnsCursor
                                                                                    deallocate ColumnsCursor
                                                                                    -----------------------------




                                select @CreateViewSQL= 'if object_id(N'''+@CompanyName+'$' + @TableName + ''', N''V'') is not null drop view ['+@CompanyName+'$' + @TableName + ']'
                                if @debug & @Print = @Print print(@CreateViewSQL)
                                if @debug & @Exec = @Exec exec (@CreateViewSQL)

                                select @CreateViewSQL= 'create view ['+@CompanyName+'$' + @TableName + '] as select ' + left(@ColumnList,len(@ColumnList)-1) + ' from ' + @SourceName + '.dbo.[' + @TableName + ']'
                                if @debug & @Print = @Print print(@CreateViewSQL)
                                if @debug & @Exec = @Exec exec (@CreateViewSQL)

                                select @ColumnList = ''


                                -----------------------------
                                fetch next from TablesCursor into @TableId, @TableName
                                end
                                close TablesCursor
                                deallocate TablesCursor
                                ------------------------------          

                select @Sql = '
                        insert into [Object] (
                        [Type],
                        [Company Name],
                        [ID],
                        [Name],
                        [Modified],
                        [Compiled],
                        [BLOB Reference],
                        [BLOB Size],
                        [DBM Table No_],
                        [Date],
                        [Time],
                        [Version List]
                    )
                    select 
                        o.[Type],
                        '''+@CompanyName+''' as [Company Name],
                        o.[ID],
                        o.[Name] collate database_default,
                        o.[Modified],
                        o.[Compiled],
                        o.[BLOB Reference],
                        o.[BLOB Size],
                        o.[DBM Table No_],
                        o.[Date],
                        o.[Time],
                        o.[Version List] collate database_default 
                    from '+@SourceName+'.dbo.Object o 
                    where o.[Name] <> ''Company''
                    and o.[Company Name] = ''''
                    and o.[Type] = 0
                    and not exists (
                        select c.*
                        from [Object] c
                        where c.[Name] = o.[Name] collate database_default 
                        and c.[Company Name] = '''+@CompanyName+'''
                        and c.[Type] = 0
                        and c.[ID] = o.[ID]
                    )
                '

                if @debug & @Print = @Print
                    print(@Sql)
                if @debug & @Exec = @Exec
                    exec (@Sql)

                -----------------------------
                fetch next from CompaniesCursor into @DatabaseName, @CompanyName, @SourceName
                end
                close CompaniesCursor
                deallocate CompaniesCursor
                -----------------------------

0 个答案:

没有答案