-1

我有以下代码:游标循环 - >而(@@ FETCH_STATUS = 0)不进入循环

declare @prefix varchar(50) 
set @prefix = 'schema1' 

declare @TablesAndIdentifiers table (TableT0 varchar(50), TableX0 varchar(50), IdentifierT0 varchar(50), IdentifierX0 varchar(50)) 
insert into @TablesAndIdentifiers(TableT0, TableX0, IdentifierT0, IdentifierX0) 
values 
('table1', 'table2', 'external_Id', 'Key Details | External Id') 
declare @TableT varchar(50) 
declare @TableX varchar(50) 
declare @IdentifierT varchar(50) 
declare @IdentifierX varchar(50) 

------------------------------------------OUTER LOOP------------------------------------------ 
declare @OuterCursor cursor 
set @OuterCursor = cursor for select * from @TablesAndIdentifiers 
open @OuterCursor 
fetch next from @OuterCursor into @TableT, @TableX, @IdentifierT, @IdentifierX 
while(@@FETCH_STATUS = 0) 
begin 

declare @ColList2 table (ColListT varchar(50), ColListX varchar(50)) 
    insert into @ColList2(ColListT,ColListX) 
    select ColListT, ColListX 
    from (
    select COLUMN_NAME as ColListT, row_number() over (order by table_name) as r from INFORMATION_SCHEMA.Columns 
    where table_name = @TableT and [email protected]) a 
    full outer join 
    (select COLUMN_NAME as ColListX, row_number() over (order by table_name) as r from INFORMATION_SCHEMA.Columns 
    where table_name = @TableX and [email protected]) b 
    on a.r = b.r 

    --Declare and set variables containing the query which will insert the mismatch columns into a new table 
    [email protected] is a concatenation of @sqlpre, @sql, @sqlpost, @sqlwhere, @sqlpregroup, @sqlgroupstatement, @sqlpostgroup 
    --The reason for this is that @sql is the only part of the query we want to be contained in the loop - the others should run outside of the loop 
    declare @sqlpre varchar(max) 
    declare @sql varchar(max) 
    declare @sqlpost varchar(max) 
    declare @sqlgroupstatement varchar(max) 
    declare @sqlpostgroup varchar(max) 
    declare @sqlfull varchar(max) 

    set @sqlpre = 'select * from (select ' 
    set @sql = '' 
    set @sqlpost = @IdentifierT + ' from '[email protected]+'.dbo.' [email protected] +' x inner join '[email protected]+'.dbo.' [email protected] + ' t on t.' [email protected] + ' = x.[' + @IdentifierX +'])dt1 group by ' 
    set @sqlgroupstatement = '' 
    set @sqlpostgroup = ' ' + @IdentifierT 


declare @Cursor cursor, @ColListTvar varchar(100), @ColListXvar varchar(100) 
     set @Cursor = cursor for select * from @ColList2 
     open @Cursor 
     fetch next from @Cursor into @ColListTvar,@ColListXvar 
     Print 'Before While => ' + CAST(@@FETCH_STATUS AS varchar(32)) 
     while (@@FETCH_STATUS = 0) 
     begin 
     Print 'Inside while -=> ' + CAST(@@FETCH_STATUS AS varchar(32)) 
     set @sql = @sql + 'case when t.' [email protected] + ' != x.[' [email protected] + '] then 1 else null end as ' + @ColListTvar+'_mismatch, ' 
     set @sqlgroupstatement = @sqlgroupstatement + @ColListTvar+'_mismatch, ' 
     fetch next from @Cursor into @ColListTvar,@ColListXvar 
     end 
    close @Cursor 
    Print 'After While => ' + CAST(@@FETCH_STATUS AS varchar(32)) 
    set @sqlfull = concat(@sqlpre,@sql,@sqlpost,@sqlgroupstatement,@sqlpostgroup) 
    print(@sqlfull) 
    --exec(@sqlfull) 


    declare @ColListMismatch varchar(max) 
     select @ColListMismatch = coalesce(@ColListMismatch+'_count,' ,'') + column_name 
     from INFORMATION_SCHEMA.COLUMNS where table_name = 'mismatches_' + @TableT and [email protected] 
     -- The last column in the list won't get a '_count' in its name (but it needs it as the rest of the code assumes this is the naming convention) 
     -- See below for workaround to get round this 

    --Create table variable containing the list of mismatch columns (in which we want to count the non-nulls - non-null implies there has been a mismatch) 
    declare @ColListMismatchTable table (ColListM varchar(50)) 
     insert into @ColListMismatchTable(ColListM) 
     select ColListM 
     from (select [COLUMN_NAME] as ColListM from INFORMATION_SCHEMA.Columns 
     where table_name = 'mismatches_'[email protected] and [email protected])dt1 

    --Declare variables for use in queries 
    declare @sqlpre2 varchar(max) 
    declare @sqlloop varchar(max) 
    declare @sqlpost2 varchar(max) 
    declare @sqlfull2 varchar(max) 
    -- Select counts from the transformation layer table and the XPLAN table; also select the count of the table produced as a result of the inner join between the two 
    -- If the migration has functioned correctly, these three counts should all be the same 
    set @sqlpre2 = 'select countXPLAN, countTransfLayer, countXPLAN-countTransfLayer as CountDiff, countMatchedIdentifiers, ' 
    -- As mentioned above, the  "+ @ColListMismatch + '_count into "  part of the below is necessary to append the _count to the last variable 
    + @ColListMismatch + '_count into '[email protected]+'.[dbo].report_' + @TableT + ' from ' 
    set @sqlloop = '' 
    set @sqlpost2 = ' select * from ((select count(*) as countTransfLayer from '[email protected]+'.dbo.'[email protected]+')dt1 cross join (select count(*) as countXPLAN from '[email protected]+'.dbo.['[email protected]+'])dt2 cross join (select count(*) as countMatchedIdentifiers from '[email protected]+'.dbo.mismatches_'[email protected]+')dt4)' 

------------------------------------------SECOND INNER LOOP------------------------------------------ 
    --Use Cursor to create loop to produce counts for each column in mismatches_* 
    declare @Cursor2 cursor, @ColListMismatchvar varchar(50) 
     set @Cursor2 = cursor for select * from @ColListMismatchTable 
     open @Cursor2 
     fetch next from @Cursor2 into @ColListMismatchvar 
     while(@@FETCH_STATUS = 0) 
     begin 
     -- Select all the counts of non-nulls 
     set @sqlloop = @sqlloop + '(select count(*) as '+ @ColListMismatchvar + '_count from mismatches_' + @TableT + ' where ' + @ColListMismatchvar + '=1)dt_' + @ColListMismatchvar + ' cross join ' 
     fetch next from @Cursor2 into @ColListMismatchvar 
     end 
     -- Remove variables so that they can be reused by the next data entity 
     delete @ColListMismatchTable 
     select @ColListMismatch=null 
    close @Cursor2 
    print('in loop to execute sqlfull2') 
    set @sqlfull2 = concat(@sqlpre2,@sqlloop,@sqlpost2) 
    print(@sqlfull2) 
-- exec(@sqlfull2) 
    print('executed sqlfull2') 

fetch next from @OuterCursor into @TableT, @TableX, @IdentifierT, @IdentifierX 
end 
close @OuterCursor 

出放的是:

(1行(一个或多个)受影响)

(0行(或多个)受影响)

之前虽然=> -1

虽然后=> -1

select * from (select external_Id from schema1.dbo.table22 x inner join schama1.dbo.table1 t on t.external_Id = x.[Key Details | External Id])dt1 group by external_Id 

(0行(S)的影响)

(0行(S)的影响) 在循环执行sqlfull2 ..

我面临的代码的问题是没有进入while循环以下代码

declare @Cursor cursor, @ColListTvar varchar(100), @ColListXvar varchar(100) 
     set @Cursor = cursor for select * from @ColList2 
     open @Cursor 
     fetch next from @Cursor into @ColListTvar,@ColListXvar 
     Print 'Before While => ' + CAST(@@FETCH_STATUS AS varchar(32)) 
     while (@@FETCH_STATUS = 0) 
     begin 
     Print 'Inside while -=> ' + CAST(@@FETCH_STATUS AS varchar(32)) 
     set @sql = @sql + 'case when t.' [email protected] + ' != x.['  [email protected] + '] then 1 else null end as ' + @ColListTvar+'_mismatch, ' 
     set @sqlgroupstatement = @sqlgroupstatement +  @ColListTvar+'_mismatch, ' 
     fetch next from @Cursor into @ColListTvar,@ColListXvar 
     end 
    close @Cursor 
    Print 'After While => ' + CAST(@@FETCH_STATUS AS varchar(32)) 
    set @sqlfull = concat(@sqlpre,@sql,@sqlpost,@sqlgroupstatement,@sqlpostgroup) 
    print(@sqlfull) 
    --exec(@sqlfull) 

任何建议将不胜感激。

在此先感谢。

+0

如果**可能**简化您的代码 –

+1

'关闭'后释放'。并且不要在循环内声明任何东西 - 局部变量的作用域是当前批处理,而不是代码块。在脚本的开头声明所有内容。 –

+0

我从来没有见过用'@'符号将游标声明为变量。请参阅在此声明光标。 https://msdn.microsoft.com/en-us/library/ms180169.aspx。我也不会'选择*'来选择光标。定义进入游标变量的列。 –

回答

0

大量的分析后,我发现这个问题与

select ColListT, ColListX 
from (
select COLUMN_NAME as ColListT, row_number() over (order by table_name) as r   from INFORMATION_SCHEMA.Columns 
where table_name = @TableT and [email protected]) a 
full outer join 
(select COLUMN_NAME as ColListX, row_number() over (order by table_name) as r from INFORMATION_SCHEMA.Columns 
where table_name = @TableX and [email protected]) b 
on a.r = b.r 

而是全外部联接如果我使用内部连接,它的工作。

有两个表中的列数有问题,其中一个表的列比其他列少,这就是它无法正常工作的原因。