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