sql - Parsing range values to comma separated array of values in insert trigger -


i need parsing values in before insert trigger on sql2008 server.

i have table contains text field (lets call source). field value may

10-15,20-22,25-26,

and want comma separated values in field (lets target):

10,11,12,13,14,15,20,21,22,25,26,

can done in before insert trigger or need external app of sort?

thank you.

first need create table valued function takes start , end value generate sequence.this done using recursive cte

create function fngetrange(@startvalue int,@endvalue int) returns  @rtntable table  (   generatedval varchar(max) ) begin ;with cte(startvalue,rangeval,generatedval) ( select @startvalue,@endvalue,@startvalue generatedval union select  startvalue, rangeval, generatedval+1 cte r  rangeval > generatedval  ) insert @rtntable select  generatedval cte return end 

you need split single column rows can range , pass function

 ;with cte(range)   (    select     right(left(t.rangeval,number-1),   charindex(',',reverse(left(','+t.rangeval,number-1)))) range     master..spt_values,   yourtable t     type = 'p' , number between 1 , len(t.rangeval)+1   ,  (substring(t.rangeval,number,1) = ',' or substring(t.rangeval,number,1)  = '')  ) 

the above solution posted here uses master..spt_values generate sequence

the cte return result

range 10-15 20-22 25-26 

now need split range startvalue , endvalue

rangecte  (startvalue,endvalue) ( select parsename(replace(range,'-','.'),2) startvalue, parsename(replace(range,'-','.'),1) endvalue cte ) 

the above rangecte return data like

  startvalue  endvalue     10         15     20         22     25         26 

once these values need pass function fngetrange using cross apply

 rowvalue (rangesep)  ( select val.generatedval rangesep rangecte r   cross apply   dbo.fngetrange(r.startvalue,r.endvalue) val )  

this generate sequence in multiple rows .to convert single row use xml path

 select stuff( (select ',' + rangesep    rowvalue     xml path(''),type).value('.','varchar(max)'),1,1,'')  

now combining cte's final query

;with cte(range)  (   select    right(left(t.rangeval,number-1),   charindex(',',reverse(left(','+t.rangeval,number-1)))) range     master..spt_values,   yourtable t     type = 'p' , number between 1 , len(t.rangeval)+1   ,  (substring(t.rangeval,number,1) = ',' or substring(t.rangeval,number,1)  = '')  ),rangecte  (startvalue,endvalue)   ( select parsename(replace(range,'-','.'),2) startvalue, parsename(replace(range,'-','.'),1) endvalue cte   ),rowvalue (rangesep)      ( select val.generatedval rangesep rangecte r       cross apply       dbo.fngetrange(r.startvalue,r.endvalue) val     )       select stuff(     (select ',' + rangesep      rowvalue      xml path(''),type).value('.','varchar(max)'),1,1,'')  

the result

 10,11,12,13,14,15,20,21,22,25,26 

as others have suggested ,you should change table design .instead of storing string create columns store range of type int

updated

just on same page . create insert trigger on source table contains values 10-15,20-22,25-26.you need convert these values sequence , insert target table.if case can use below code.

basically trigger created derived table inserts data inserted logical tables in trigger.then using above nested cte's ,you insert sequence in target table

create trigger tri_inserts on after insert set nocount on declare @rangetable table (rangeval varchar(max))  insert @rangetable select rangecolumn inserted  ;with cte(range)  (  select   right(left(t.rangeval,number-1),  charindex(',',reverse(left(','+t.rangeval,number-1)))) range   master..spt_values,  @rangetable t   type = 'p' , number between 1 , len(t.rangeval)+1  ,  (substring(t.rangeval,number,1) = ',' or substring(t.rangeval,number,1)  = '')   ),rangecte  (startvalue,endvalue)    (     select parsename(replace(range,'-','.'),2) startvalue,     parsename(replace(range,'-','.'),1) endvalue     cte    ),rowvalue (rangesep)      ( select val.generatedval rangesep rangecte r       cross apply       dbo.fngetrange(r.startvalue,r.endvalue) val     )       insert target(destcolumn)     --change target name       select stuff(      (select ',' + rangesep       rowvalue       xml path(''),type).value('.','varchar(max)'),1,1,'')    go 

Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -