Link to home
Start Free TrialLog in
Avatar of Larry Brister
Larry BristerFlag for United States of America

asked on

SQL Parse string

I have a Telerik RadScheduler running that stores the "recurrence" in a column

I need the ability to "read" and parse the string that's stored

For example I'd want the ability to set
@interval=1
@BYDAY='MO,TH,SU '

and so on as needed.

DTSTART:20110530T000000Z  DTEND:20110531T000000Z  RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TH,SU
Avatar of jramacciottiyahoocom
jramacciottiyahoocom
Flag of United States of America image

Take a look at http://msdn.microsoft.com/en-us/library/aa259342%28SQL.80%29.aspx . If you are parsing the string using SQL Server, you use "SELECT SUBSTRING("expression to find",0, 10) as BLAH FROM tblName WHERE Blah = 'blah';
Avatar of Patrick Matthews
This worked in my testing:

DECLARE @Recurrence varchar(100)
SET @Recurrence = 'DTSTART:20110530T000000Z  DTEND:20110531T000000Z  RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TH,SU'

SELECT SUBSTRING(@Recurrence, CHARINDEX('FREQ=', @Recurrence) + 5, CHARINDEX(';', @Recurrence) - CHARINDEX('FREQ=', @Recurrence) - 5) AS Freq,
    SUBSTRING(@Recurrence, CHARINDEX('INTERVAL=', @Recurrence) + 9, CHARINDEX(';', @Recurrence, CHARINDEX('INTERVAL=', @Recurrence)) - CHARINDEX('INTERVAL=', @Recurrence) - 9) AS Interval,
    SUBSTRING(@Recurrence, CHARINDEX('BYDAY=', @Recurrence) + 6, LEN(@Recurrence)) AS ByDay
WHERE @Recurrence LIKE '%FREQ=[A-Z]%;INTERVAL=[0-9]%;BYDAY=[A-Z]%'

Open in new window



Turning it into a query:


SELECT SUBSTRING(Recurrence, CHARINDEX('FREQ=', Recurrence) + 5, CHARINDEX(';', Recurrence) - CHARINDEX('FREQ=', Recurrence) - 5) AS Freq,
    SUBSTRING(Recurrence, CHARINDEX('INTERVAL=', Recurrence) + 9, CHARINDEX(';', Recurrence, CHARINDEX('INTERVAL=', Recurrence)) - CHARINDEX('INTERVAL=', Recurrence) - 9) AS Interval,
    SUBSTRING(Recurrence, CHARINDEX('BYDAY=', Recurrence) + 6, LEN(Recurrence)) AS ByDay
FROM SomeTable
WHERE Recurrence LIKE '%FREQ=[A-Z]%;INTERVAL=[0-9]%;BYDAY=[A-Z]%'

Open in new window

You can use the following function to parse your configuration:

CREATE FUNCTION [dbo].[ToKeyValuePairs]
(	
	@input nvarchar(4000),
	@keydelim nchar(1),
	@pairdelim nchar(1)
)
RETURNS @result TABLE ([Key] nvarchar(4000), [Value] nvarchar(4000))
AS
BEGIN
	declare @i int, @len int, @mode bit, @c nchar(1)
	declare @eval nvarchar(4000)
	declare @key nvarchar(4000)
	declare @value nvarchar(4000)

	set @len = len(@input) + 1
	set @input = @input + @pairdelim
	set @key = ''
	set @value = ''
	set @i = 1
	set @mode = 0 -- 0=key; 1=value

	while @i <= @len begin
		set @c = substring(@input, @i, 1)
		
		if @mode = 0 begin -- capturing key
			if @c <> @pairdelim
				if @c <> @keydelim
					set @key = @key + @c
				else
					set @mode = 1
		end else begin
			if @c <> @pairdelim
				set @value = @value + @c
			else begin
				set @mode = 0
				
				insert into @result values (@key, @value)
				
				set @key = ''
				set @value = ''
			end
		end
		
		set @i = @i + 1
	end
	
	return
END

Open in new window


Usage test case:
declare @config varchar(4000)
declare @rrule varchar(4000)
declare @params table ([Key] varchar(4000), [Value] varchar(4000))
declare @freq varchar(10)
declare @interval varchar(10)
declare @byday varchar(10)

set @config = 'DTSTART:20110530T000000Z  DTEND:20110531T000000Z  RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TH,SU'

select @rrule = [Value] 
  from dbo.ToKeyValuePairs(@config,':', ' ')
 where [Key] = 'RRULE'
 
insert into @params
	select [Key], [Value]
	  from dbo.ToKeyValuePairs(@rrule,'=', ';')
	  
select @freq = [Value] from @params where [Key] = 'FREQ'
select @interval = [Value] from @params where [Key] = 'INTERVAL'
select @byday = [Value] from @params where [Key] = 'BYDAY'

select @freq, @interval, @byday

Open in new window


Output:
---------- ---------- ----------
WEEKLY     1          MO,TH,SU

Open in new window

Avatar of Larry Brister

ASKER

Wow!

Guys...both answers were amazing and will have equal use in my project(s)

A split ok with slightly larger nod going to matthewspatrick: for being first with a useable complete answer?
Split for matthewspatrick: and wdosanjos: was what I meant for amazing answers.
Maybe 300/200?
Hey guys...I just realized that the answer doesn't handle the Start date and time and end date and time...tried modifying your answers and having some trouble
ASKER CERTIFIED SOLUTION
Avatar of wdosanjos
wdosanjos
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
wdosanjos:
That's super close...

The T in the start date is the time
Can you point me in the correct place to get the time as startTime and EndTime?
wdosanjos:
never mind...I can to a right and/or left on my select to get the date and times seperated.

Way to go!

Points being awarded shortly
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey guys...both pretty amazing solutions and useful for short term work as well as long term applications
Any problem splitting points?
lrbrister,

>>Any problem splitting points?

None at all.  Glad to help :)

Patrick
>>Any problem splitting points?

No, that sounds fair enough.
Incredible job guys.  been using EE for many years(8+) and definately, this is in the top 3 of useful solutions.

Will reuse many times over I'm sure.

Thanks