-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)
任何建议将不胜感激。
在此先感谢。
如果**可能**简化您的代码 –
'关闭'后释放'。并且不要在循环内声明任何东西 - 局部变量的作用域是当前批处理,而不是代码块。在脚本的开头声明所有内容。 –
我从来没有见过用'@'符号将游标声明为变量。请参阅在此声明光标。 https://msdn.microsoft.com/en-us/library/ms180169.aspx。我也不会'选择*'来选择光标。定义进入游标变量的列。 –