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] splitting Strings

Author  Topic 

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-11-24 : 11:44:05
I everyone, I have been on the admin side of IT for the past 20 years and recently started to do some scripting (VBscript) and a little SQL.

I have developed a solution to meet the needs of some federal auditors, but not really met my needs yet.
What I have done is this.

I use MS Logparser to go out to 64 servers and copy the event logs into a DB on a SQL 2000 Ent. Server.

On the SQL server I have one StoredProcedure that parses out information from the security event log DB and put that info into a temp DB.


set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[stp_SecurityAuditReport]

AS

TRUNCATE TABLE SecurityEvents_Tmp

-- Parse Bank Number & UserName
INSERT INTO SecurityEvents_Tmp(DepartmentNumber, UserName, EventLog, RecordNumber, TimeGenerated, TimeWritten, EventID, EventType, EventTypeName, EventCategory, EventCategoryName, SourceName, Strings, ComputerName, SID, Message, Data)
SELECT
DepartmentNumber = '001',
UserName = CASE
WHEN Strings LIKE '[0-9][0-9][0-9]%'
THEN SUBSTRING(Strings,1,charindex('|',Strings,1)-1)
WHEN Strings LIKE '-|[0-9][0-9][0-9]%'
THEN SUBSTRING(Strings,3,charindex('|',Strings,3)-3)
WHEN Strings LIKE '-|[a-z]%'
THEN SUBSTRING(Strings,3,charindex('|',Strings,3)-3)
WHEN Strings LIKE 'Account Unlocked. |%'
THEN SUBSTRING(Strings,21,charindex('|',Strings,21)-21)
ELSE SUBSTRING(Strings,1,charindex('|',Strings,1)-1)
END,
Events.*
FROM Events
JOIN EventsToLog on Events.EventID = EventsToLog.EventID
WHERE SID NOT LIKE 'S-%'


-- Update blank usernames
UPDATE SecurityEvents_Tmp SET UserName = 'NO USERNAME'
WHERE UserName = '' OR UserName = '-'

-- Update DepartmentNumbers with zeros
UPDATE SecurityEvents_Tmp SET
DepartmentNumber = CASE
WHEN UserName LIKE '[0-9][0-9][0-9][a-z]%' OR
UserName LIKE '[0-9][0-9][0-9]#%' OR
UserName LIKE '[0-9][0-9][0-9]$%'
THEN SUBSTRING(UserName,1,3)
ELSE '001' END


As you can see, we use 3 didgit numeric prefixes on all Departmental employee accounts. This is later used to produce departmenntal user audit reports.

I then have this script in a DTS that exports the report to an excel spreadsheet. (All works well for this purpose!)


DECLARE @TimeGenerated datetime
SELECT @TimeGenerated = TimeGenerated FROM SecurityEvents_TimeGenerated

DECLARE @TimeGeneratedEnd datetime
SELECT @TimeGeneratedEnd = TimeGeneratedEnd FROM SecurityEvents_TimeGenerated

SELECT DepartmentName = CASE WHEN b.DepartmentName IS NULL
THEN 'All Department' ELSE b.DepartmentName END,
a.EventID,d.EventDescription,a.UserName, a.TimeGenerated,c.Email1,c.Email2,c.Email3,c.Email4
FROM SecurityEvents_Tmp a
LEFT JOIN DepartmentList b on a.DepartmentNumber = b.DepartmentNumber
LEFT JOIN EmailToList c on b.DepartmentNumber = c.DepartmentNumber
JOIN EventsToLog d on a.EventID = d.EventID
WHERE b.Departmentnumber in (select Departmentnumber from Departmentlist)
AND a.TimeGenerated BETWEEN @TimeGenerated AND @TimeGeneratedEnd
ORDER BY b.DepartmentNumber,a.EventID,a.TimeGenerated


This combination of utils and scripts does very good for producing generic security reports for branch officers.

But now I am getting requests to justify/explain what is in these reports. The problem I have is that the information needed to delve further into the event logs is in a field called Strings. This field not only changes in length and the amount of fields within this string, but the information in this field changes depending on the type of event record it came from.


This is the Strings field from a failed logon (529)
200jenil|DOMAIN|10|User32 |Negotiate|SERVER|SERVER$|DOMAIN|(0x0,0x3E7)|6920|-|10.190.12.10|48397

And this is from Event ID 642 which was an account being created.
-|381$cmiller|DOMAIN|%{S-1-5-21-3554868564-134719009-1577582102-7972}|Jmotta|DOMAIN|(0x0,0x58F635E)|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|%%1792|-|-

Now, my script does a good job of getting the first user name out but as in the 642 event the second users name would be useful as well. This is the person that created/modified the user account.

So what I was hoping was that I could use a function (or whatever) to automaticaly split the Strings value into it's individual components and put them into an auto-sizing temp table as something like Field1, Field2, Field3, and so on until the end of string.

I could then use a case to get the information needed.

HELP PLEASE!!



Thank You,

John Fuhrman
http://www.titangs.com

snSQL
Master Smack Fu Yak Hacker

1837 Posts

Posted - 2006-11-24 : 12:53:20
http://www.sqljunkies.com/WebLog/amachanic/articles/SplitString.aspx

or do it in application code when you load the data.
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-11-24 : 14:12:45
I have seen and tried to use many of the Sting2Table functions. I am just not sure how I would impliment the function.

declare @Strings as varchar(50)

select @Strings = ('1|W|WS|D|D|C|S|DF|DF|DX|CV|X|CX|XCV')

Select * from SplitString(@Strings,'|')

1
W
WS
D
D
C
S
DF
DF
DX
CV
X
CX
XCV

I can't seem to figure out how to select individual parts of the output.



Thank You,

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

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-11-24 : 14:22:00
Read here http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

snSQL
Master Smack Fu Yak Hacker

1837 Posts

Posted - 2006-11-24 : 14:28:06
You wouldn't want it to just automatically generate a table because you'd have no way of knowing what the table structure was - how many columns would it have and what would the 1st or the 5th or the 13th column actually be.

So you probably want to adapt that function to take another parameter to ask for the nth string, and then create your table with the specifc columns you actually want.

You might also find these useful
How To Use SQL Server to Analyze Web Logs
http://support.microsoft.com/kb/296085
SQL Server 2005 Report Pack for Microsoft Internet Information Services (IIS)
http://www.microsoft.com/downloads/details.aspx?FamilyID=d81722ce-408c-4fb6-a429-2a7ecd62f674&DisplayLang=en
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-11-24 : 14:31:42
select * from dbo.Split('1|W|WS|D|D|C|S|DF|DF|DX|CV|X|CX|XCV', '|') where id = 6

to get the item C from the list


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-11-24 : 14:46:41
Peter, the
Where ID = 6 gives error invalid column name


BEGIN
SET @LeftSplit = @Delimiter + SUBSTRING(@List, @SplitStart, @SplitEnd - @SplitStart) + @Delimiter

INSERT @ReturnTbl (OutParam)
SELECT LTRIM(RTRIM(SUBSTRING(@LeftSplit, Number + 1,
CHARINDEX(@Delimiter, @LeftSplit, Number + 1) - Number - 1)))
AS Value
FROM dbo.Numbers
WHERE Number <= LEN(@LeftSplit) - 1
AND SUBSTRING(@LeftSplit, Number, 1) = @Delimiter
AND SUBSTRING(@LeftSplit, Number + 1,
CHARINDEX(@Delimiter, @LeftSplit, Number + 1) - Number - 1) <> ''

SET @SplitStart = @SplitEnd + 1
SET @SplitEnd = @SplitEnd + 7998

SELECT @SplitEnd = MAX(Number) + @SplitStart
FROM dbo.Numbers
WHERE (SUBSTRING(@List, Number + @SplitStart, 1) = @Delimiter
OR Number+@SplitStart = DATALENGTH(@List) + 1)
AND Number BETWEEN 1 AND @SplitEnd - @SplitStart
END


Is there a way to add a numbered column to the function?



Thank You,

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

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-11-24 : 14:50:03
If you use the function which I provided a link for, there will be no error.
I am not familiar with the function above, but if you declare the @returntbl with a RowID SMALLINT IDENTITY(1, 1) too, the result will be two columns of which one will be RowID.
Then you do

select * from <yourfunctionname here>(<your string to split here>) where rowid = 6



Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-11-24 : 14:56:48
This is the closest I could get to getting it working.

declare @Strings as varchar(50)

select @Strings = ('1|W|WS|D|D|C|S|DF|DF|DX|CV|X|CX|XCV')

Select * from SplitString(@Strings,'|') where OutParam = 6

Msg 245, Level 16, State 1, Line 5
Conversion failed when converting the varchar value 'W' to data type int.

declare @Strings as int

select @Strings = ('1|W|WS|D|D|C|S|DF|DF|DX|CV|X|CX|XCV')

Select * from SplitString(@Strings,'|') where OutParam = 6

Msg 206, Level 16, State 2, Line 5
Operand type clash: int is incompatible with text


Any ideas??



Thank You,

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

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-11-24 : 14:58:51
yes, redesign the @returntbl as varchar(100). do not Use int for this.
It would REALLY help if you posted the function here so we sould not have to guess.

Or, just simply use the function for which I gave a link. It is timetested and works!


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2006-11-24 : 15:02:54
Peter, Thanks!!

declare @Strings as varchar(1024)

select @Strings = ('1|W|WS|D|D|C|S|DF|DF|DX|CV|X|CX|XCV')

Select * from Split(@Strings,'|') where id = 6

That worked!!

Now the real work begins.... Now to modify my current scripts to use the split function.

Thanks for the assistance!!

Thank You,

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

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2010-12-24 : 03:25:02
Why did you edit your old post? If you have any questions post it as a new post

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2010-12-24 : 04:59:54
Changed title to include "[SOLVED]" (I think)
Go to Top of Page

AndrewMurphy
Master Smack Fu Yak Hacker

2916 Posts

Posted - 2010-12-24 : 05:07:41
Or Promoting a website signature???
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2010-12-24 : 05:28:16
Can't see that the signature has changed (later posts don't show modification, but have the same signature)

More modern forum software would show history of edits - which makes attribution of misbehaviour easier to establish of course ...
Go to Top of Page

SparkByte
Yak Posting Veteran

60 Posts

Posted - 2011-01-03 : 09:49:59
Set the title to show SOLVED as noted above by Kristen.

Sorry for the confuion it caused.

Thank You,

John
Go to Top of Page
   

- Advertisement -