Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Server :opération de fractionnement

si vous ne pouvez pas utiliser les paramètres de valeur de table, consultez :"Arrays and Lists in SQL Server 2008 à l'aide de paramètres de table" par Erland Sommarskog , il existe de nombreuses façons de fractionner une chaîne dans SQL Server. Cet article couvre les avantages et les inconvénients de presque toutes les méthodes :

"Tableaux et listes dans SQL Server 2005 et versions ultérieures, lorsque les paramètres de valeur de table ne le font pas Coupez-le" par Erland Sommarskog

Vous devez créer une fonction de fractionnement. Voici comment une fonction de fractionnement peut être utilisée :

SELECT
    *
    FROM YourTable                               y
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value

Je préfère l'approche de la table numérique pour scinder une chaîne dans TSQL mais il existe de nombreuses façons de diviser des chaînes dans SQL Server, voir le lien précédent, qui explique les avantages et les inconvénients de chacun.

Pour que la méthode de la table des nombres fonctionne, vous devez effectuer cette configuration de table de temps unique, ce qui créera une table Numbers qui contient des lignes de 1 à 10 000 :

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

Une fois la table Numbers configurée, créez cette fonction de fractionnement :

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

Vous pouvez maintenant facilement diviser une chaîne CSV en une table et la joindre :

select * from dbo.FN_ListToTable(' ','stack over flow')

SORTIE :

ListValue
-------------------
stack
over
flow

(3 row(s) affected)