Compte tenu d'une table:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Split]') and xtype in (N'FN', N'IF', N'TF')) drop function [dbo].Split
go
CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(@sep, @s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
go
declare @inputtable table (
name varchar(200) not null,
hobbies varchar(200) not null
)
declare @outputtable table (
name varchar(200) not null,
hobby varchar(200) not null
)
insert into @inputtable values('Joe', 'Eating,Running,Golf')
insert into @inputtable values('Dafydd', 'Swimming,Coding,Gaming')
select * from @inputtable
declare inputcursor cursor for
select name, hobbies
from @inputtable
open inputcursor
declare @name varchar(255), @hobbiescsv varchar(255)
fetch next from inputcursor into @name, @hobbiescsv
while(@@FETCH_STATUS <> -1) begin
insert into @outputtable
select @name, splithobbies.s
from dbo.split(',', @hobbiescsv) splithobbies
fetch next from inputcursor into @name, @hobbiescsv
end
close inputcursor
deallocate inputcursor
select * from @outputtable
4 Réponses :
Utilisez une fonction d'analyse de chaîne comme celle trouvée ici . La clé est d'utiliser Cross Appliquer pour exécuter la fonction pour chaque ligne de votre table de base .
CREATE FUNCTION [dbo].[fnParseStringTSQL] (@string NVARCHAR(MAX),@separator NCHAR(1))
RETURNS @parsedString TABLE (string NVARCHAR(MAX))
AS
BEGIN
DECLARE @position int
SET @position = 1
SET @string = @string + @separator
WHILE charindex(@separator,@string,@position) <> 0
BEGIN
INSERT into @parsedString
SELECT substring(@string, @position, charindex(@separator,@string,@position) - @position)
SET @position = charindex(@separator,@string,@position) + 1
END
RETURN
END
go
declare @MyTable table (
Name char(10),
Hobbies varchar(100)
)
insert into @MyTable
(Name, Hobbies)
select 'Joe', 'Eating,Running,Golf'
union all
select 'Dafydd', 'Swimming,Coding,Gaming'
select t.Name, p.String
from @mytable t
cross apply dbo.fnParseStringTSQL(t.Hobbies, ',') p
DROP FUNCTION [dbo].[fnParseStringTSQL]
Créez cette fonction dans votre DB:
Select t.Name,
s.items as 'Hobby'
from dbo.MyTable as t
Cross Apply dbo.Split(t.Hobbies,',') as s
Nopers. Vous devez être applicable ou externe appliquer un TVF.
@Denis - Merci Denis. J'ai oublié que je traitais avec la table de table là-bas. Mise à jour ma réponse maintenant.
Merci, cross s'appliquer code> est ce que j'étais après! Fera encore une lecture sur cela maintenant
Faites simplement ce qui suit:
select *
from @inputtable
outer apply dbo.split(',', hobbies) splithobbies
Il n'y a pas de fonction native "Split" dans SQL Server (qui aspire).
@Philip La réponse est donnée dans le contexte de la question. Avez-vous vu qu'il y a déjà une fonction de scission mise en œuvre au tout début de la question? Donc, ça va.
est correct, l'application extérieure est la partie dont je devais savoir afin que cette réponse soit parfaitement valide.
Assez juste. Je viens de lire l'intro impliquant qu'il s'agissait d'une solution de boucle à base de curseur typique, a vu les fonctions de scission postées par tous les autres, et supposait que c'était comme toutes les autres questions d'analyse de la chaîne publiées. Hélas, les votes (bas ou autrement) ne peuvent pas être inversés à moins que la réponse originale soit modifiée; Si vous (ajoutez un espace, changez de ponctuation), je vais l'inverser.
Je préfère généralement utiliser et le suivant article pour plus de techniques montrant comment faire cela. Ensuite, il vous suffit d'utiliser la clause code> appliquer code> pour appliquer la fonction. P> p> xml code> pour scinder la liste CSV sur le format de la valorisation de la table. Vous pouvez vérifier cette fonction:
Même si dans votre exemple, chaque personne a exactement trois hobbies, je suppose que chaque personne peut réellement avoir 1 hobbies ou plus?
@LittlebbobbobbobbobbobbobbobbobbobbyTables Oui, j'aurais dû mentionner la liste des passe-temps peut être de longueur arbitraire