Solved

TSQL for Table-Valued Function

Posted on 2015-01-19
8
248 Views
Last Modified: 2015-01-20
What does the following part ctually perform ??

#1  
  WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )

#2
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),

#3
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)


------------------------------------------------------
CREATE FUNCTION [dbo].[Split]
(
    @String NVARCHAR(4000),
    @Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
    WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
    FROM Split
)
GO
0
Comment
Question by:AXISHK
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
8 Comments
 
LVL 24

Expert Comment

by:Phillip Burton
ID: 40557700
#1 is a CTE. It splits the first string into separate rows based on the second string, and gives the position of the start of the split and the end.

#2 identifies the row number. The OVER(ORDER BY (SELECT 1)) is because you have to put something in the OVER, and that just means "I don't care about the order".

#3 converts the positions identified in #1 and creates the actual strings based on those positions.
0
 

Author Comment

by:AXISHK
ID: 40557747
Tks, still have problem,

Function name is "Split', select table name is 'Split'. Is the function calling itself recursively ??

Tks
0
 
LVL 24

Expert Comment

by:Phillip Burton
ID: 40557753
No - Split is different to dbo.split.

You could change

 WITH Split(stpos,endpos)
...
            FROM Split
...
    FROM Split

Open in new window


to

 WITH Hello(stpos,endpos)
...
            FROM Hello
...
    FROM Hello

Open in new window


and still get the right answer.

The fact that the function is called dbo.Split doesn't make any difference.
0
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 
LVL 49

Expert Comment

by:PortletPaul
ID: 40559150
>>"#1 is a CTE" (?)

a CTE is a "Common Table Expression"
Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, or DELETE statement.
http://msdn.microsoft.com/en-AU/library/ms175972.aspx

No points please.
0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 40559158
>>" Is the function calling itself recursively ??"

The function is not being called recursively, but the CTE is calling itself recursively (which is allowed)
... A common table expression can include references to itself. This is referred to as a recursive common table expression.
http://msdn.microsoft.com/en-AU/library/ms175972.aspx

No points please.
0
 

Author Comment

by:AXISHK
ID: 40559185
I can't get the idea  in #1

select 0 as stops, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo') AS endpos       

it will return :
stops     endpos
0             8
About the second one, how does it iterate from the Split  ? can I stimulate it in Management Studio ? Tks
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
             FROM Split
             WHERE endpos > 0
0
 
LVL 24

Assisted Solution

by:Phillip Burton
Phillip Burton earned 200 total points
ID: 40559368
0
 
LVL 49

Accepted Solution

by:
PortletPaul earned 300 total points
ID: 40559398
?... Typically one introduces the full name then resorts to the abbreviation.
---------------
For this recursive CTE:

{+edit} Don't forget that the CHARINDEX() function uses the optional third parameter to establish where to start from. This increases at each iteration.

On the first iteration
select 0 as stops, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo') AS endpos      
it will return :
stops     endpos
0             8
It then enters the second iteration
SELECT endpos+1, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo',endpos+1) AS endpos  
which returns
stops     endpos
9             17           -- the comma after Cornfed
It then enters the third iteration
SELECT endpos+1, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo',endpos+1) AS endpos  
which returns
stops     endpos
18             23           -- the comma after Ajax
It then enters the fourth iteration
SELECT endpos+1, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo',endpos+1) AS endpos  
which returns
stops     endpos
24             32           -- the comma after Charles
It then enters the fifth iteration
SELECT endpos+1, CHARINDEX(',' , 'Duckman, Cornfed, Ajax, Charles, Mambo',endpos+1) AS endpos  
which returns
stops     endpos
33             0           -- there is no comma after position 33 of the string
Now the endpos is zero the iterations stop due to the where clause:

             WHERE endpos > 0

You can run this as a query to see the effect.
declare @String NVARCHAR(4000) = 'Duckman, Cornfed, Ajax, Charles, Mambo'
declare @Delimiter NCHAR(1) = ','

    ;WITH Split(stpos,endpos)
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
            FROM Split
            WHERE endpos > 0
    )
    SELECT
        'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
      , stpos
      , endpos
    FROM Split

Open in new window

which produces:
| ID |     DATA | STPOS | ENDPOS |
|----|----------|-------|--------|
|  1 |  Duckman |     0 |      8 |
|  2 |  Cornfed |     9 |     17 |
|  3 |     Ajax |    18 |     23 |
|  4 |  Charles |    24 |     32 |
|  5 |    Mambo |    33 |      0 |

Open in new window

0

Featured Post

The Eight Noble Truths of Backup and Recovery

How can IT departments tackle the challenges of a Big Data world? This white paper provides a roadmap to success and helps companies ensure that all their data is safe and secure, no matter if it resides on-premise with physical or virtual machines or in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Composite queries are used to retrieve the results from joining multiple queries after applying any filters. UNION, INTERSECT, MINUS, and UNION ALL are some of the operators used to get certain desired results.​
This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question