Comment faire pour Remplacer Plusieurs Caractères dans SQL?
Ceci est basé sur une question similaire Comment faire pour Remplacer Plusieurs Caractères dans l'Accès SQL?
J'ai écrit ce depuis sql server 2005 semble avoir une limite sur la fonction de remplacement() à 19 remplacements dans la clause where.
J'ai la tâche suivante: Besoin d'effectuer un match sur une colonne, et pour améliorer les chances d'un match de décapage de plusieurs nations unies nécessaire caractères à l'aide de replace() de la fonction
DECLARE @es NVarChar(1) SET @es = ''
DECLARE @p0 NVarChar(1) SET @p0 = '!'
DECLARE @p1 NVarChar(1) SET @p1 = '@'
---etc...
SELECT *
FROM t1,t2
WHERE REPLACE(REPLACE(t1.stringkey,@p0, @es), @p1, @es)
= REPLACE(REPLACE(t2.stringkey,@p0, @es), @p1, @es)
---etc
Si il y a >19 REPLACE() dans la clause where, il ne fonctionne pas. Donc la solution que j'ai trouvé est de créer une fonction sql appelé trimChars dans cet exemple (excuse de départ à @22
CREATE FUNCTION [trimChars] (
@string varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
DECLARE @es NVarChar(1) SET @es = ''
DECLARE @p22 NVarChar(1) SET @p22 = '^'
DECLARE @p23 NVarChar(1) SET @p23 = '&'
DECLARE @p24 NVarChar(1) SET @p24 = '*'
DECLARE @p25 NVarChar(1) SET @p25 = '('
DECLARE @p26 NVarChar(1) SET @p26 = '_'
DECLARE @p27 NVarChar(1) SET @p27 = ')'
DECLARE @p28 NVarChar(1) SET @p28 = '`'
DECLARE @p29 NVarChar(1) SET @p29 = '~'
DECLARE @p30 NVarChar(1) SET @p30 = '{'
DECLARE @p31 NVarChar(1) SET @p31 = '}'
DECLARE @p32 NVarChar(1) SET @p32 = ' '
DECLARE @p33 NVarChar(1) SET @p33 = '['
DECLARE @p34 NVarChar(1) SET @p34 = '?'
DECLARE @p35 NVarChar(1) SET @p35 = ']'
DECLARE @p36 NVarChar(1) SET @p36 = '\'
DECLARE @p37 NVarChar(1) SET @p37 = '|'
DECLARE @p38 NVarChar(1) SET @p38 = '<'
DECLARE @p39 NVarChar(1) SET @p39 = '>'
DECLARE @p40 NVarChar(1) SET @p40 = '@'
DECLARE @p41 NVarChar(1) SET @p41 = '-'
return REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
@string, @p22, @es), @p23, @es), @p24, @es), @p25, @es), @p26, @es), @p27, @es), @p28, @es), @p29, @es), @p30, @es), @p31, @es), @p32, @es), @p33, @es), @p34, @es), @p35, @es), @p36, @es), @p37, @es), @p38, @es), @p39, @es), @p40, @es), @p41, @es)
END
Cela peut ensuite être utilisé en plus de l'autre, de remplacer des chaînes
SELECT *
FROM t1,t2
WHERE trimChars(REPLACE(REPLACE(t1.stringkey,@p0, @es), @p1, @es)
= REPLACE(REPLACE(t2.stringkey,@p0, @es), @p1, @es))
J'ai créé avec quelques fonctions en plus pour faire la même en remplaçant comme trimChars(trimMoreChars(
SELECT *
FROM t1,t2
WHERE trimChars(trimMoreChars(REPLACE(REPLACE(t1.stringkey,@p0, @es), @p1, @es)
= REPLACE(REPLACE(t2.stringkey,@p0, @es), @p1, @es)))
Quelqu'un peut-il me donner une meilleure solution à ce problème en termes de performances et peut-être un nettoyant pour la mise en œuvre?
- Êtes-vous en mesure de désinfecter votre entrée avant de passer à la base de données?
- De quelle taille sont les tables t1 et t2? Est-il possible de faire le travail à l'extérieur de la base de données? Ressemble à un travail pour les expressions régulières.
Vous devez vous connecter pour publier un commentaire.
Je voudrais envisager sérieusement faire un CLR UDF au lieu de cela et en utilisant des expressions régulières (à la fois la chaîne et le modèle peuvent être passés en paramètres) pour faire une recherche complète et de le remplacer pour une plage de caractères. Il devrait facilement surpasser cette SQL UDF.
Une astuce utile dans SQL est la possibilité d'utiliser
@var = function(...)
à attribuer une valeur. Si vous avez plusieurs dossiers dans votre dossier, ensemble, votre var est attribuée à plusieurs reprises avec des effets secondaires:J'aime vraiment @Juliett la solution! Je voudrais juste utiliser une expression de table commune pour obtenir tous les caractères non valides:
Je vous suggère de créer un scalaire fonction définie par l'utilisateur. Ceci est un exemple (désolé à l'avance, parce que les noms de variable sont en espagnol):
Voici un exemple d'utilisation de cette fonction:
Et le résultat est: 7hiZ iZ 4 7eZ7.
Comme vous pouvez le voir, chaque caractère de la
@caracteresElim
paramètre est remplacé par le personnage dans la même position de la@caracteresReem
paramètre.J'ai eu une migration des données d'un problème où la source de données ne pouvait pas sortie correctement certains insolite/technique de caractères plus l'omniprésent supplémentaire des virgules dans CSVs.
Nous avons décidé que pour chaque caractère de la source de l'extrait doit remplacer par quelque chose qui était reconnaissable à la fois le système source et le Serveur SQL qui était en train de charger, mais qui ne serait pas dans les données.
Cela ne signifie pas cependant que dans les différentes colonnes à travers les différents tableaux de ces caractères de remplacement semble et je voudrais avoir à les remplacer. Imbrication de plusieurs de REMPLACER des fonctions mis le code d'importation sembler effrayant et sujettes à des erreurs de jugement erroné le placement et le nombre de supports de sorte que j'ai écrit la fonction suivante. Je sais qu'il peut traiter une colonne dans une table de 3 000 lignes en moins d'une seconde si je ne suis pas sûr de savoir comment rapidement il va évoluer jusqu'à plusieurs millions de ligne de tables.
Il fonctionne en soumettant à la fois la chaîne pour être évalués et ont des caractères de remplacement (@OriginalString) avec une chaîne de paires de caractères où le premier caractère doit être remplacé par le second, le troisième, le quatrième, cinquième, sixième, et ainsi de suite (@ReplaceTheseChars).
Ici est la chaîne de caractères que j'avais besoin de remplacer et de leurs remplaçants... [']"~,{Ø}°$±|¼¦¼ª½½^¾#✓
c'est à dire Un crochet d'ouverture dénote une apostrophe, une fermeture d'une double cotation. Vous pouvez voir qu'il y avait vulgaire fractions ainsi que les degrés et le diamètre des symboles de là.
Il y a un défaut @LengthOfReplacement qui est inclus comme un point de départ si quelqu'un avait besoin de remplacer des chaînes plus longues. J'ai joué un peu avec le fait que dans mon projet, mais que le seul caractère de remplacement est la fonction principale.
La condition de l'instruction de cas est important. Il assure qu'il ne remplace le personnage si il est trouvé dans votre @ReplaceTheseChars variable et que le personnage se retrouve dans une drôle de position numérotée (au moins 1 de charindex résultat assure que rien ne trouve PAS de retours négatifs modulo la valeur). j'.e si vous trouvez un tilde (~) dans la position 5-il va le remplacer par une virgule, mais si à la suite d'exécuter trouvé la virgule dans la position 6-il ne serait pas le remplacer par une accolade ({).
Cela peut être démontré par un exemple...
Ce sera le retour à la fois de la valeur après la première passe par le biais de la fonction et la deuxième fois, comme suit...
abc,def '¼ "'123 abc,def '¼ "'123
Une mise à jour de table serait juste
Enfin, me direz-vous!), bien que je n'ai pas eu accès à la fonction de traduction, je crois que cette fonction peut traiter l'exemple présenté dans la documentation assez facilement. La fonction de traduction de démo est
qui renvoie 2*(3+4)/(7-2) même si je comprends que ça ne fonctionne pas sur 2*[3+4]/[7-2] !!
Ma fonction d'approche comme suit cette liste chaque char à être remplacé, suivie par son remplacement [ --> (, { --> ( etc.
qui fonctionne également pour
J'espère que quelqu'un le trouve utile et si vous arrivez à tester ses performances contre les grandes tables faites-nous savoir d'une manière ou d'une autre!
Alors que cette question a été posée sur SQL Server 2005, il est intéressant de noter qu'à partir de Sql Server 2017, la demande peut être faite avec la nouvelle fonction de traduction.
https://docs.microsoft.com/en-us/sql/t-sql/functions/translate-transact-sql
J'espère que cette information aide les gens qui arrivent à cette page à l'avenir.
Une option est d'utiliser un nombre/tally table à conduire un processus itératif par l'intermédiaire d'un pseudo-défini en fonction de la requête.
L'idée générale de char de remplacement peut être démontré avec une simple table de caractères approche:
Alors vous pouvez apporter dans le décompte approche de table pour faire de la recherche sur chaque position de caractère dans la chaîne.
Je ne sais pas pourquoi Charles Bretana supprimé de sa réponse, je suis donc de le rajouter en tant que CW réponse, mais une colonne calculée persistante est une très bonne façon de gérer ces situations où vous avez besoin purifiés ou des données transformées presque tout le temps, mais besoin de conserver l'original des ordures. Sa suggestion est pertinente et appropriée, quelle que soit la façon dont vous décidez de nettoyer vos données.
Plus précisément, dans mon projet actuel, j'ai une colonne calculée persistante qui rogne tous les zéros (heureusement que c'est realtively faciles à manipuler des droites T-SQL) de certains identificateurs numériques stockées d'une manière incompatible avec les zéros non significatifs. Ce sont stockées dans des colonnes calculées persistantes dans les tableaux qui en ont besoin et indexés en raison conforme identifiant est souvent utilisé dans les jointures.
Voici les étapes
Voir code suivant:
Déployer votre fonction CLR
Maintenant le Tester
Voir code suivant: