192 votes

Tsql split string

J'ai une colonne SQL Server 2008 R2 contenant une chaîne que je dois diviser par une virgule. J'ai vu beaucoup de réponses sur stackoverflow mais aucune d'entre elles ne fonctionne dans R2. Je me suis assuré d'avoir des autorisations de sélection sur tous les exemples de fonctions divisées. Toute aide grandement appréciée.

293voto

Andy Robinson Points 2299

J'ai déjà utilisé ce SQL qui peut vous convenir: -

 CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX(',', @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(',', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END
 

et de l'utiliser: -

 SELECT * FROM dbo.splitstring('91,12,65,78,56,789')
 

80voto

Aaron Bertrand Points 116343

Au lieu de récursive d'expressions de table communes et les boucles while, a toute personne considérée comme un plus, basés sur l'approche?

CREATE FUNCTION [dbo].[SplitString]
    (
        @List NVARCHAR(MAX),
        @Delim VARCHAR(255)
    )
    RETURNS TABLE
    AS
        RETURN ( SELECT [Value] FROM 
          ( 
            SELECT 
              [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
              CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
            FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
              FROM sys.all_objects) AS x
              WHERE Number <= LEN(@List)
              AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim
          ) AS y
        );

Plus sur split fonctions, pourquoi (et la preuve) tandis que les boucles et les expressions cte n'est pas à l'échelle, et de meilleures alternatives, si le fractionnement des chaînes provenant de la couche application:

http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings

http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql

http://sqlblog.com/blogs/aaron_bertrand/archive/2010/07/07/splitting-a-list-of-integers-another-roundup.aspx

13voto

CorvetteGuru Points 11

J'avais besoin d'un moyen rapide pour me débarrasser des +4 d'un code postal .

 UPDATE #Emails 
  SET ZIPCode = SUBSTRING(ZIPCode, 1, (CHARINDEX('-', ZIPCODE)-1)) 
  WHERE ZIPCode LIKE '%-%'
 

Pas de proc ... pas de UDF ... juste une petite commande inline qui fait ce qu’elle doit. Pas chic, pas élégant.

Changez le délimiteur si nécessaire, etc., et cela fonctionnera pour n'importe quoi.

7voto

AviG Points 77

si vous remplacez

 WHILE CHARINDEX(',', @stringToSplit) > 0
 

avec

 WHILE LEN(@stringToSplit) > 0
 

vous pouvez éliminer cette dernière insertion après la boucle while!

 CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE LEN(@stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(',', @stringToSplit)


if @pos = 0
        SELECT @pos = LEN(@stringToSplit)


  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 RETURN
END
 

2voto

Une solution utilisant un CTE, si quelqu'un en avait besoin (mis à part moi qui en ai manifestement fait, c'est pourquoi je l'ai écrite).

 declare @StringToSplit varchar(100) = 'Test1,Test2,Test3';
declare @SplitChar varchar(10) = ',';

with StringToSplit as (
  select 
      ltrim( rtrim( substring( @StringToSplit, 1, charindex( @SplitChar, @StringToSplit ) - 1 ) ) ) Head
    , substring( @StringToSplit, charindex( @SplitChar, @StringToSplit ) + 1, len( @StringToSplit ) ) Tail

  union all

  select
      ltrim( rtrim( substring( Tail, 1, charindex( @SplitChar, Tail ) - 1 ) ) ) Head
    , substring( Tail, charindex( @SplitChar, Tail ) + 1, len( Tail ) ) Tail
  from StringToSplit
  where charindex( @SplitChar, Tail ) > 0

  union all

  select
      ltrim( rtrim( Tail ) ) Head
    , '' Tail
  from StringToSplit
  where charindex( @SplitChar, Tail ) = 0
    and len( Tail ) > 0
)
select Head from StringToSplit
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X