Comme l'a mentionné Alon, vous avez besoin d'une fonction ou d'une requête pour diviser les valeurs en lignes dans une table. Une autre façon de le faire est avec une table de nombres qui peut être statique ou créé dans le cadre d'une expression de table commune:
Declare @Alist varchar(50);
Declare @Delimiter char(1);
Declare @DelimiterLength int;
Set @Delimiter = ' ';
Set @DelimiterLength = DataLength(@Delimiter);
Set @Alist = 'A1 A2 A3';
Set @Alist = @Delimiter + @Alist + @Delimiter;
With Numbers As
(
Select Row_Number() Over (Order By C1.object_id) As Value
From sys.columns As C1
Cross Join sys.columns As C2
)
Select CharIndex(@Delimiter, @Alist, N.Value) + @DelimiterLength As Position
, Substring (
@Alist
, CharIndex(@Delimiter, @Alist, N.Value) + @DelimiterLength
, CharIndex(@Delimiter, @Alist, N.Value + 1)
- (CharIndex(@Delimiter, @Alist, N.Value) + @DelimiterLength)
) As Value
From Numbers As N
Where N.Value Between 1 And (Len(@Alist) - 1)
And Substring(@Alist, N.Value, @DelimiterLength) = @Delimiter
Order By N.Value
Ici le délimiteur espace présente un petit problème. La fonction Len
ignore les espaces dans sa détermination, j'ai donc utilisé la fonction DataLength
et également m'assurer que @Delimiter
a été déclaré comme varchar
au lieu d'un nvarchar
.DataLength
renverra le nombre d'octets dans la chaîne qui sera deux fois le nombre de caractères en général pour un nvarchar
.
Le nombre CTE (ou il pourrait être une table statique) est juste une liste statique d'entiers séquentiels qui est très utile pour des situations comme celle-ci.
Ce type d'approche peut également être incorporée dans une requête générale où vous analysez chaque ligne dans une autre table comme ceci:
With Numbers As
(
Select Row_Number() Over (Order By C1.object_id) As Value
From sys.columns As C1
Cross Join sys.columns As C2
)
Select CharIndex(@Delimiter, A.List, N.Value) + @DelimiterLength
, Substring (
A.List
, CharIndex(@Delimiter, A.List, N.Value) + @DelimiterLength
, CharIndex(@Delimiter, A.List, N.Value + 1)
- (CharIndex(@Delimiter, A.List, N.Value) + @DelimiterLength)
)
From Numbers As N
Cross Join (Select A1.List From SomeTable) As A
Where N.Value Between 1 And (Len(A.List) - 1)
And Substring(A.List, N.Value, @DelimiterLength) = @Delimiter
Order By N.Value
question voulez-vous des déclarations distinctes pour chaque ou une procédure stockée qui vous permettra de retourner tous ces scénarios? –
Je dois écrire une procédure stockée qui nécessite un paramètre de chaîne et une table de sortie. Merci. –