Reputation: 479
Let me try to make this as easy to understand as possible. I have a table with a column that is called 'Script_Text'. This column contains a script. Like, a really long script with class name, function name, the whole drill. I am trying to find the function names on all these scripts. I don't want to go through every one of them individually.
This is NOT what I am looking for:
select * from table where script_text like '%function%'
Script or query, doesn't matter. Want it for SQL Server. My database has not more than 200 tables. Don't care about efficiency. Thanks
EDIT 1: My assumption on what the query would look like might throw you off, just ignore it. I might be plain stupid on how I think this would work.
Also, all functions start with Function
keyword. For instance: Function GetUserName()
. I want my query to return GetUserName()
.
EDIT 2: I know this is confusing to follow. It is confusing to articulate it in words in MY head. Let me give more examples.
One of the tables I am working with is ObjectSymbol
. This table has 3 columns. SymbolName
, Description
, Script_Text
.
Contents of the Script_Text column for one particular symbolname is this
Function PostSearch() As Long
' Delete any @DFLT or @T records from the search results
DO something
' Do more things
End Function
A successful query would return PostSearch() for that particular symbolname.
EDIT 3:
imports System
imports System.Diagnostics
Imports System.XML
Imports System.Data
Imports Microsoft.VisualBasic
Class HookScript
Inherits FcProcFuncSetEvent
Function presave() as long
Do stuff here
End Function
Function IngrPostRowUpdate() as Long
Do more stuff here
RETURN 1
End Function
Function postsave() As Long
Do some more stuff here
End Function
Private Function GetValue(val as Object) as String
If IsDBNull(val) Then
GetValue = ""
Else
GetValue = CStr(val)
End If
End Function
End Class
GetValue
is what is being returned by the query.
Upvotes: 1
Views: 144
Reputation: 67291
What about this?
First I declare a table variable to mock-up a test scenario.
DECLARE @YourTable TABLE(ID INT IDENTITY,SomeScript NVARCHAR(MAX));
INSERT INTO @YourTable VALUES
(
N'Do something here
blah
blah
private function HereIsAFunctionName(){
Some body
}
public function SomeOtherFunction(){blah}
private function OneMore(){
Body
}
')
,(
N'Do something here
blah
blah
private function ThisIsAFunction(){
Some body
}
');
The first part (a CTE) will use a string-split-trick to create XML chunks by replacing the word function
(with blanks) by </x><x>
. Then you can read the beginning of each chunk up to the opening (
. You might read to the closing )
to get the paramter's list.
WITH Casted AS
(
SELECT ID
,CAST(N'<x>' + REPLACE((SELECT SomeScript AS [*] FOR XML PATH('')),N' function ',N'</x><x>') + N'</x>' AS XML) AS SplitMe
FROM @YourTable
)
SELECT Casted.ID
,LEFT(x.value(N'.',N'nvarchar(max)'),CHARINDEX('(',x.value(N'.',N'nvarchar(max)'))-1) AS Part
FROM Casted
OUTER APPLY Casted.SplitMe.nodes(N'x[position()!=1]') AS A(x)
The result
ID Part
1 HereIsAFunctionName
1 SomeOtherFunction
1 OneMore
2 ThisIsAFunction
WITH Casted AS
(
SELECT ID
,CAST(N'<x>' + REPLACE((SELECT REPLACE(SomeScript,'end function','') AS [*] FOR XML PATH('')),N' function ',N'</x><x>') + N'</x>' AS XML) AS SplitMe
FROM @YourTable
)
SELECT Casted.ID
,LEFT(x.value(N'.',N'nvarchar(max)'),CHARINDEX(')',x.value(N'.',N'nvarchar(max)'))) AS Part
FROM Casted
OUTER APPLY Casted.SplitMe.nodes(N'x[position()!=1]') AS A(x)
Your problem was caused by line breaks, where I expected blanks...
Try this:
DECLARE @YourTable TABLE(ID INT IDENTITY,SomeScript NVARCHAR(MAX));
INSERT INTO @YourTable VALUES
(
N'Do something here
blah
blah
private function HereIsAFunctionName(){
Some body
}
public function SomeOtherFunction(){blah}
private function OneMore(){
Body
}
')
,(
N'imports System
imports System.Diagnostics
Imports System.XML
Imports System.Data
Imports Microsoft.VisualBasic
Class HookScript
Inherits FcProcFuncSetEvent
Function presave() as long
Do stuff here
End Function
Function IngrPostRowUpdate() as Long
Do more stuff here
RETURN 1
End Function
Function postsave() As Long
Do some more stuff here
End Function
Private Function GetValue(val as Object) as String
If IsDBNull(val) Then
GetValue = ""
Else
GetValue = CStr(val)
End If
End Function
End Class
');
--The query
WITH Casted AS
(
SELECT ID
,CAST(N'<x>' + REPLACE((SELECT REPLACE(REPLACE(REPLACE(SomeScript,'end function',''),CHAR(13),' '),CHAR(10),' ') AS [*] FOR XML PATH('')),N' function ',N'</x><x>') + N'</x>' AS XML) AS SplitMe
FROM @YourTable
)
SELECT Casted.ID
,LEFT(x.value(N'.',N'nvarchar(max)'),CHARINDEX(')',x.value(N'.',N'nvarchar(max)'))) AS Part
FROM Casted
OUTER APPLY Casted.SplitMe.nodes(N'x[position()!=1]') AS A(x);
Upvotes: 2