I have done something similar before where there was a multiple valued column in a table, so in order to normalise it, and report on it I had to create a mapping table. I did it using a cursor though in SQL. I had a guid column followed by a ; seperated column which started with a record count such as 3;guid1;guid2;guid3
Something like this:
create procedure dbo.SP_MakeMappingTable
(
@sSrcTable varchar(100),
@sDstTable varchar(100),
@sGuidField varchar(100),
@sSplitField varchar(100)
)
as
begin
declare @sTmp varchar(4000),
@sNewGuid varchar(40),
@nCnt int,
@sSplitString varchar(4000),
@sSql nvarchar(4000)
if (select OBJECTPROPERTY(OBJECT_ID(N'dbo.'+@sDstTable), N'IsUserTable')) = 1
exec('drop table dbo.'+@sDstTable)
exec('create table dbo.'+@sDstTable+' ('+@sGuidField+' varchar(40), '+@sSplitField+' varchar(40))')
create table #tmp (TMP_GUID varchar(40), TMP_BASKET varchar(4000))
set @sSql = 'select '+@sGuidField+', '+@sSplitField+' from '+@sSrcTable
insert #tmp exec sp_executesql @sSql
declare @sGuid VARCHAR(40), @sBasket varchar(4000)
declare csr cursor for
select TMP_GUID, TMP_BASKET from #tmp
open csr
fetch next from csr into @sGuid, @sBasket
while @@fetch_status = 0
begin
set @sTmp = @sBasket
set @nCnt = 1
while 1=1
begin
if (@nCnt!=1)
begin
set @sNewGuid = substring(@sTmp, 0, charindex(';',@sTmp))
exec('insert into '+ @sDstTable +' ('+@sGuidField+', '+@sSplitField+') values ('''+@sGuid+''', '''+@sNewGuid+''')')
end
set @sTmp = substring(@sTmp,charindex(';',@sTmp)+1,4000)
set @nCnt = @nCnt +1
if charindex(';',@sTmp) < 1
break
end
set @sNewGuid = substring(@sTmp, 0, 4000)
exec('insert into '+ @sDstTable +' ('+@sGuidField+', '+@sSplitField+') values ('''+@sGuid+''', '''+@sNewGuid+''')')
fetch next from csr into @sGuid, @sBasket
end
close csr
deallocate csr
end
Messy I know, but effective at the time :)
commented on Mar 10 2011 9:58AM