2011-10-28 4 views
4

Je ne trouve pas de moyen de le faire et à cause de certaines restrictions, il doit être codé sans l'utilisation de variables, mais je peux appeler une fonction. Quoi qu'il en soit, je dois renvoyer un jeu de résultats à partir d'une requête Select et l'une des lignes est une chaîne délimitée par un tuyau.Chaîne délimitée par l'analyse SQL

Ainsi, il retournera quelque chose comme:

id| Name  | Message | 
--------------------- 
1 | Some Name | 'Here is my | delimited | message' 

Et je besoin d'être

id| Name  | Message1  | Message2 | Message3 
------------------------------------------------------ 
1 | Some Name | 'Here is my' | 'delimited' | 'message' 

Je pensais à quelque chose comme Parsename('','|',1), où vous pouvez passer dans le séparateur au lieu de toujours être une période mais je ne connais pas la meilleure façon d'y parvenir.

EDIT: J'ai essayé des variantes de ceci mais bien sûr c'est très déroutant. Il pourrait y avoir 4 ou plus |

SELECT Field1, 
Field2 AS Originalvalue, 
--1 
SUBSTRING(Field2,0,CHARINDEX('|',Field2)) AS Msg1, 
--2 
LEFT(SUBSTRING(Field2,CHARINDEX('|',Field2)+1 ,LEN(Field2)),CHARINDEX('|',SUBSTRING(Field2,CHARINDEX('|',Field2)+1 ,LEN(Field2)))-1) 
AS ExtractedValue 
FROM Table1 T1 JOIN Table2 T2 
ON T1.Id = T2.Id 
WHERE T1.Id = 12 
+3

Pourquoi les gens [continuer à faire ce] (http://stackoverflow.com/search?q=sql+delimited) ?! – Phil

+4

les champs délimités par des canalisations font mourir les fées SQL – scrappedcola

+0

Hmm, est-ce que les gens ne répondent pas aux questions sur ce site? Il semble y avoir beaucoup de 'allez regarder google'. Je cherche depuis plus d'une heure et je n'ai pas trouvé exactement ce que je cherchais. – user204588

Répondre

8

Vous pouvez écrire une fonction sql comme suit.

create Function dbo.fn_Parsename(@Message Varchar(1000), @delimiter char(1), @index int) 
Returns Varchar(1000) 
As 
Begin 
    Declare 
     @curIndex int = 0, 
     @pos int = 1, 
     @prevPos int = 0, 
     @result varchar(1000) 

    while @pos > 0 
    Begin 

     set @pos = CHARINDEX(@delimiter, @Message, @prevPos); 

     if(@pos > 0) 
     begin-- get the chars between the prev position to next delimiter pos 
      set @result = SUBSTRING(@message, @prevPos, @[email protected]) 
     end 
     else 
     begin--get last delim message 
      set @result = SUBSTRING(@message, @prevPos, LEN(@message)) 
     end 

     if(@index = @curIndex) 
     begin 
      return @result 
     end 

     set @prevPos = @pos + 1 
     set @curIndex = @curIndex + 1; 

    end 
    return ''--not found 
End 

Et vous pouvez l'appeler comme ci-dessous:

select dbo.fn_Parsename('Here is my | delimited | message','|', 0) 
select dbo.fn_Parsename('Here is my | delimited | message','|', 1) 
select dbo.fn_Parsename('Here is my | delimited | message','|', 2) 
+1

génial! Merci beaucoup. J'apprécie vraiment cela. – user204588

Questions connexes