T-SQL scinde une chaîne
J'ai un Serveur SQL server 2008 R2 colonne contenant une chaîne que j'ai besoin de les séparer par une virgule. J'ai vu beaucoup de réponses sur StackOverflow mais aucun d'entre eux travaille dans R2. J'ai fait en sorte que j'ai de sélectionner les autorisations sur toute fonction de répartition exemples. Toute aide grandement appréciée.
- C'est l'un des millions de réponses que j'aime stackoverflow.com/a/1846561/227755
- Que voulez-vous dire "aucune de ces travaux"? Pouvez-vous être plus précis?
- Andy ne me pointer dans la bonne direction, car j'ai été l'exécution de la fonction incorrecte. C'est pourquoi aucun de l'autre pile réponses travaillé. De ma faute.
- double possible de scinde une chaîne en SQL
- Il y a un
mdq.RegexSplit
fonction dans le "Master Data Services" add-on, ce qui peut aider. Certainement qui mérite d'être examiné.
Vous devez vous connecter pour publier un commentaire.
J'ai utilisé ce SQL avant ce qui peut travailler pour vous:-
et de l'utiliser:-
select * from dbo.splitstring('')
Au lieu de récursive d'expressions de table communes et les boucles while, a toute personne considérée comme une série de plus, l'approche basée?
Si vous voulez éviter la limitation de la longueur de la chaîne en cours <= le nombre de lignes dans
sys.all_columns
(9,980 dansmodel
dans SQL Server 2017; beaucoup plus élevés dans vos propres bases de données utilisateur), vous pouvez utiliser d'autres méthodes pour calculer les nombres, tels que la construction de votre propre tableau de nombres. Vous pouvez également utiliser une expression de table commune récursive dans le cas où vous ne pouvez pas utiliser les tables système ou créer votre propre:Mais vous aurez à ajouter
OPTION (MAXRECURSION 0)
(ouMAXRECURSION <longest possible string length if < 32768>
) de la requête externe afin d'éviter les erreurs de la récursivité pour cordes > 100 caractères. Si c'est pas une bonne solution de rechange alors voir cette réponse comme l'a souligné dans les commentaires.Plus sur les fonctions split, 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
https://sqlblog.org/2010/07/07/splitting-a-list-of-integers-another-roundup
sys.all_objects
est moins que le nombre de caractères dans la chaîne d'entrée, puis il va tronquer la chaîne et les valeurs portés disparus. Depuissys.all_objects
est tout simplement être utilisé comme un peu un hack pour générer des lignes, puis il ya de meilleures façons de le faire, par exemple, cette réponse.SELECT [Value] FROM (SELECT [Value] = ... FROM ...)
, donc il semble que l'extérieurSELECT [Value] FROM
est redondante. Est-il un facteur de performance, je ne vois pas?declare @x varchar; set @x = '123'; print @x;
et ensuite de lire cet article.Enfin, l'attente est terminée dans SQL Server 2016 ils ont introduit Split fonction de chaîne :
STRING_SPLIT
Toutes les autres méthodes pour diviser la chaîne XML, Cadre de tableau, tandis que la boucle, etc.. a été emporté par ce
STRING_SPLIT
fonction.Voici un excellent article avec comparaison des performances : Performances Surprises et Hypothèses : STRING_SPLIT
La meilleure façon de le faire est par l'utilisation de
XML
format.1. La conversion de la chaîne de lignes sans table
REQUÊTE
RÉSULTAT
2. La conversion de lignes d'une table qui ont un ID pour chaque CSV ligne
TABLE SOURCE
REQUÊTE
RÉSULTAT
@String
contient des caractères interdits... je viens de poster réponse pour résoudre ce problème.J'ai besoin d'un moyen rapide de se débarrasser de la
+4
à partir d'un code postal.Pas de proc... pas de UDF... juste un peu serré inline commande qui fait ce qu'il doit. Pas de fantaisie, pas élégant.
Changer le séparateur en tant que de besoin, etc, et il va travailler pour rien.
si vous remplacez
avec
vous pouvez éliminer ce dernier insérer, après la boucle while!
+1
àSELECT @pos = LEN(@stringToSplit)
semble aborder cette question. Cependant, laSELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
sera de retourInvalid length parameter passed to the LEFT or SUBSTRING function
, sauf si vous ajoutez+1
le troisième paramètre de sous-CHAÎNE ainsi. ou vous pouvez remplacer cette tâche avecSET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) --MAX len of nvarchar is 4000
Toutes les fonctions de la chaîne de fractionnement qui utilisent un type de Boucle-ing (itérations) ont une mauvaise performance. Ils doivent être remplacés avec un set à base de solution.
Ce code s'exécute excellent.
@List
contient des caractères interdits... je viens de poster réponse pour résoudre ce problème.Je devais écrire quelque chose comme cela récemment. Voici la solution que j'ai trouvé. Il est généralisée pour n'importe quel délimiteur de chaîne et je pense qu'il serait d'effectuer un peu mieux:
Une solution à l'aide d'un CTE, si quelqu'un devrait avoir besoin que (en dehors de moi, qui n'ont évidemment, c'est pourquoi je l'ai écrit).
Il y a une version correcte ici, mais j'ai pensé qu'il serait bien d'ajouter un peu de tolérance aux pannes dans le cas où ils ont une virgule ainsi que de faire en sorte que vous pourriez utiliser, non comme une fonction, mais comme faisant partie d'un grand morceau de code. Juste au cas où vous êtes seulement en utilisant une fois de temps et n'avez pas besoin d'une fonction. C'est aussi pour les entiers (ce dont j'ai besoin) de sorte que vous pourriez avoir à changer vos types de données.
SET @StringToSeperate = @StringToSeperate+','
immédiatement avant leWHILE
boucle je pense que vous pourriez être en mesure d'éliminer le "ajouter la dernière valeur" bloc. Voir aussi mon sol'n githubJ'ai modifié +Andy Robinson fonction un peu. Maintenant, vous pouvez sélectionner uniquement la partie nécessaire de retourner le tableau:
SELECT Name FROM dbo.splitstring('ELIS.YD.CRP1.1.CBA.MDSP.T389.BT') WHERE numOrder=5
Si vous avez besoin d'un rapide ad-hoc de la solution pour la plupart des cas, avec un minimum de code, alors cette expression de table commune récursive deux-liner doit le faire:
Soit utiliser comme un stand-alone déclaration ou simplement ajouter le au-dessus d'expressions de table communes à toutes vos requêtes et vous serez en mesure de rejoindre la table résultante
b
avec les autres pour une utilisation dans toutes les autres expressions.modifier (par Shnugo)
Si vous ajoutez un compteur, vous obtiendrez un index de position ainsi que la Liste:
Le résultat:
ici est une version qui peut se diviser sur un motif à l'aide patindex, une simple adaptation de la post ci-dessus. J'ai eu un cas où j'ai besoin de découper une chaîne qui contient de nombreux séparateur de caractères.
résultat ressemble à ceci
stringa
stringb
x
y
z
Personnellement, j'utilise cette fonction :
J'ai développé une double Séparateur (Prend deux caractères) comme demandé Ici. Pourrait être de quelque valeur dans ce fil, voyant son le plus cité pour les requêtes relatives à la chaîne de fractionnement.
Utilisation:
Usage Possible (deuxième valeur de chaque division):
Souvent utilisé avec les éléments XML les pauses dans le cas des caractères interdits. C'est une approche de l'utilisation de cette méthode avec tout type de personnage, même avec le point-virgule comme séparateur.
Le truc, c'est, d'abord à utiliser
SELECT SomeString AS [*] FOR XML PATH('')
pour obtenir tous les caractères interdits échappées. C'est la raison pour laquelle j'ai remplacer le délimiteur à un valeur magique pour éviter les ennuis avec;
comme délimiteur.Le résultat
C'est plus étroitement adaptées. Quand je fais cela, j'ai habituellement une liste séparée par des virgules d'identifiants uniques (INT ou BIGINT), de laquelle je veux jeté comme une table à utiliser comme une jointure interne à une autre table possède une clé primaire de type INT ou BIGINT. Je veux une fonction table retourné afin que j'ai le plus efficace de se joindre possible.
Exemple d'utilisation serait:
J'ai volé l'idée de http://sqlrecords.blogspot.com/2012/11/converting-delimited-list-to-table.html, le changer pour être dans la ligne de table et jeté comme INT.
Vous pouvez Utiliser cette fonction:
Voici un exemple que vous pouvez utiliser en tant que fonction ou vous aussi, vous pouvez mettre la même logique dans la procédure.
--SELECT * from [dbo].fn_SplitString ;
@vCSV
contient des caractères interdits... je viens de poster réponse pour résoudre ce problème./*
``
*/
/*
``
Cas de Test: voir URL référencée comme "la meilleure fonctionnalité" ci-dessus
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,b')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, ')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, c ')
*/
Une expression de table commune récursive solution basée sur
Avec tout le respect dû à @AviG c'est le bug de la version gratuite de la fonction deviced par lui de retourner tous les jetons dans son intégralité.
Ceci est basé sur Andy Robertson réponse, j'avais besoin d'un séparateur d'autres que par des virgules.
Et de l'utiliser:
(Testé sur SQL Server 2008 R2)
EDIT: correction d'un code de test
La façon la plus simple:
Il fonctionne même dans l'express édition :).