我的代码如下:
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 COLUMN_NAME!=@IdentifierT) 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 COLUMN_NAME!=@IdentifierX) b
on a.r = b.r
--Declare and set variables containing the query which will insert the mismatch columns into a new table
--@sqlfull 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 '+@prefix+'.dbo.' +@TableX +' x inner join '+@prefix+'.dbo.' +@TableT + ' t on t.' +@IdentifierT + ' = 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.' +@ColListTvar + ' != x.[' +@ColListXvar + '] 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 COLUMN_NAME!=@IdentifierT
-- 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_'+@TableT and COLUMN_NAME!=@IdentifierT)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 '+@prefix+'.[dbo].report_' + @TableT + ' from '
set @sqlloop = ''
set @sqlpost2 = ' select * from ((select count(*) as countTransfLayer from '+@prefix+'.dbo.'+@TableT+')dt1 cross join (select count(*) as countXPLAN from '+@prefix+'.dbo.['+@TableX+'])dt2 cross join (select count(*) as countMatchedIdentifiers from '+@prefix+'.dbo.mismatches_'+@TableT+')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
out put of:
(1行受影响)
(0行(s)受影响)
在While =>之前-1
在While =>之后-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 ..
我遇到代码的问题不会进入下面的代码循环
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.' +@ColListTvar + ' != x.[' +@ColListXvar + '] 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 :(得分: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 COLUMN_NAME!=@IdentifierT) 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 COLUMN_NAME!=@IdentifierX) b
on a.r = b.r
如果我使用内连接,那么取代全外连接,它起作用。
2个表中的列数存在问题,其中一个表的列数少于其他表,这就是它无法正常工作的原因。