Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 [SOLVED] SP Strings parsing

Author  Topic 

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 15:00:14
Hello everyone, I have this SP and can't get it to work on my SQL2000 server. I just can't seem to figure out what syntax error I am making.
(This works on my test SQL2005 server)


Truncate Table [SecurityEvents_Temp]

Insert Into SecurityEvents_Temp (
[BankNumber],
[UserName],
[DomainName],
[EventLog],
[RecordNumber],
[TimeGenerated],
[TimeWritten],
[EventID],
[EventType],
[EventTypeName],
[EventCategory],
[EventCategoryName],
[SourceName],
[Strings],
[ComputerName],
[SID],
[Message],
[Data]
)
Select
[BankNumber] = '001',

[UserName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 3)

[DomainName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 4),

[SecurityEvents].*
FROM [SecurityEvents]
JOIN [EventsToLog] on [SecurityEvents].[EventID] = [EventsToLog].[EventID]
WHERE [SID] NOT LIKE 'S-%'


Query Output:
quote:

Server: Msg 170, Level 15, State 1, Line 28
Line 28: Incorrect syntax near 'Strings'.
Server: Msg 170, Level 15, State 1, Line 30
Line 30: Incorrect syntax near 'Strings'.




Thank You,

John Fuhrman
http://www.titangs.com

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2006-12-11 : 15:09:53
You are missing a comma between the 2nd and 3rd columns in your SELECT statement.

Also, Strings is a parameter that you are passing to the function, right? Well you need single quotes around it instead of square brackets.

Select
[BankNumber] = '001',
[UserName] = (Select [Value] From [dbo].[fn_Split]('Strings','|') where idx = 3),
[DomainName] = (Select [Value] From [dbo].[fn_Split]('Strings','|') where idx = 4),
[SecurityEvents].*
FROM [SecurityEvents]

Tara Kizer
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 15:18:14
No, Strings is a column in the Table, which is why the brackets.


Select
[BankNumber] = '001',
[UserName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 3),
[DomainName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 4),
[SecurityEvents].*
FROM [SecurityEvents]


Code Output:
still:
Server: Msg 170, Level 15, State 1, Line 3
Line 3: Incorrect syntax near 'Strings'.
Server: Msg 170, Level 15, State 1, Line 4
Line 4: Incorrect syntax near 'Strings'.


Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2006-12-11 : 15:34:59
I've looked at your code more closely. You won't be able to split your string and put it into UserName column or DomainName column since the subquery will return more than one value. Plus you can't pass the column like you want to.

Check this out:
SELECT [Test] = (SELECT [Value] From [dbo].[fn_Split]('Tara|Kizer','|'))

And this:
SELECT [Value] From [dbo].[fn_Split]('Tara|Kizer','|')

Tara Kizer
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 15:41:41
Since they are subqueries, you must pass the FROM table in the subquery!


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 15:43:54
No, it returns only a single value. The function splits the strings column value into a Temp table you then referrence the Index to get the value you need from the string.

Referrence the where clause.

Select
[BankNumber] = '001',
[UserName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 3),
[DomainName] = (Select [Value] From [dbo].[fn_Split]([Strings],'|') where idx = 4),
[SecurityEvents].*
FROM [SecurityEvents]


Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 15:45:59
Using the function dbo.fnParseString from here http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033
You can write the query as this
Select	[BankNumber] = '001',
[UserName] = dbo.fnParseString([Strings], '|', 3),
[DomainName] = dbo.fnParseString([Strings], '|', 4),
[SecurityEvents].*
FROM [SecurityEvents]
JOIN [EventsToLog] on [SecurityEvents].[EventID] = [EventsToLog].[EventID]
WHERE [SID] NOT LIKE 'S-%'



Peter Larsson
Helsingborg, Sweden
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2006-12-11 : 15:47:21
Perhaps next time you should post the code of the function or at least a link to it, so I don't have to assume what it does. I use a different technique than fn_Split does to split strings, so I wasn't too familiar with it.

Please see Peso's post for why you can't pass the column name like you think. That's what I was referring to in my last post in the "Plus" part.

Tara Kizer
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 15:57:21

I was thinking it would be a relatively quick question since it works on one server ond not the other, the difference being the version of SQL Server, so I didn't think the code to the SP was needed.

Peso, I will try your example. Thanks

Here is the code to the function in question.


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_Split](@sText varchar(8000), @sDelim varchar(20) = ' ')
RETURNS @retArray TABLE (idx smallint Primary Key, value varchar(8000))
AS
BEGIN
DECLARE @idx smallint,
@value varchar(8000),
@bcontinue bit,
@iStrike smallint,
@iDelimlength tinyint

IF @sDelim = 'Space'
BEGIN
SET @sDelim = ' '
END

SET @idx = 0
SET @sText = LTrim(RTrim(@sText))
SET @iDelimlength = DATALENGTH(@sDelim)
SET @bcontinue = 1

IF NOT ((@iDelimlength = 0) or (@sDelim = 'Empty'))
BEGIN
WHILE @bcontinue = 1
BEGIN

--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.

IF CHARINDEX(@sDelim, @sText)>0
BEGIN
SET @value = SUBSTRING(@sText,1, CHARINDEX(@sDelim,@sText)-1)
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END

--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET @iStrike = DATALENGTH(@value) + @iDelimlength
SET @idx = @idx + 1
SET @sText = LTrim(Right(@sText,DATALENGTH(@sText) - @iStrike))

END
ELSE
BEGIN
--If you can’t find the delimiter in the text, @sText is the last value in
--@retArray.
SET @value = @sText
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END
--Exit the WHILE loop.
SET @bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE @bcontinue=1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(@sText)>1
BEGIN
SET @value = SUBSTRING(@sText,1,1)
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END
SET @idx = @idx+1
SET @sText = SUBSTRING(@sText,2,DATALENGTH(@sText)-1)

END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT @retArray (idx, value)
VALUES (@idx, @sText)
SET @bcontinue = 0
END
END

END

RETURN
END


Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 16:05:35
Peso, your example function returns this error.

Server: Msg 245, Level 16, State 1, Line 3
Syntax error converting the varchar value '204ggarr|LXOLCDAPP03|%{S-1-5-21-3554868564-134719009-1577582102-1755}|LXOLAD01$|COREBANKS|(0x0,0x3E7)|-' to a column of data type smallint.
could you help?

Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 16:15:09
Yes, I rearranged the columns for the function.
Select	[BankNumber] = '001',
[UserName] = dbo.fnParseString(3, '|', [Strings]),
[DomainName] = dbo.fnParseString(4, '|', [Strings]),
[SecurityEvents].*
FROM [SecurityEvents]
JOIN [EventsToLog] on [SecurityEvents].[EventID] = [EventsToLog].[EventID]
WHERE [SID] NOT LIKE 'S-%'


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 16:19:52
Peso, If I follow your example correctly, the largest text string that can be parsed is 8000 characters correct?
(This should be plenty for anything I will do, but just wanted to clarify because I am studying via the school of HardKnox.)

Thanks once again Peso!!

Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 16:25:58
If you are using SQL2005, you can replace VARCHAR(8000) with VARCHAR(MAX), which will give you strings with a max length of 2 gig+ characters.


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 16:39:54
I have noticed something ODD. The function seems to parse the string in reverse order.

select dbo.fnParseString(1,'|','John|corebanks|dsjhfksjd|lskjdflkjsd|slkjdflks')

Output
slkjdflks

(1 row(s) affected)

I realy need it to parse the other direction.

And thankx for the tip on SQL2005.

Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 16:42:00
Yes. As the link says, it is a replacement of PARSENAME function.
Just write -3 instead of 3, and -4 instead of 4.

Negative values are for left-to-right numbering, and positive values are for right-to-left numbering.


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-12-11 : 16:44:15
Cool thanks!!



Thank You,

John Fuhrman
http://www.titangs.com
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-12-11 : 16:46:34
[code]Select [BankNumber] = '001',
[UserName] = dbo.fnParseString(-3, '|', [Strings]),
[DomainName] = dbo.fnParseString(-4, '|', [Strings]),
[SecurityEvents].*
FROM [SecurityEvents]
JOIN [EventsToLog] on [SecurityEvents].[EventID] = [EventsToLog].[EventID]
WHERE [SID] NOT LIKE 'S-%'[/code]

Peter Larsson
Helsingborg, Sweden
Go to Top of Page
   

- Advertisement -