Comment puis-je supprimer des caractères non numériques d'une chaîne?

10

Les utilisateurs entrent un terme de recherche dans une boîte et cette valeur est transmise à une procédure stockée et vérifiée par rapport à quelques champs différents dans la base de données. Ces champs ne sont pas toujours du même type de données.

Un champ (numéro de téléphone) se compose de tous les numéros, donc lors de la vérification, il supprime tous les caractères non numériques de la chaîne à l'aide d'une fonction .Net CLR.

SELECT dbo.RegexReplace('(123)123-4567', '[^0-9]', '')

Le problème est que cette fonction cesse brusquement de fonctionner à l'occasion avec l'erreur suivante:

Msg 6533, niveau 16, état 49, ligne 2
AppDomain MyDBName.dbo [runtime] .1575 a été déchargé par la stratégie d'escalade pour garantir la 
cohérence de votre candidature. Une mémoire insuffisante s'est produite lors de l'accès à une ressource critique.
System.Threading.ThreadAbortException: exception de type 
'System.Threading.ThreadAbortException' a été levé.
System.Threading.ThreadAbortException: 

J'ai essayé les suggestions publiées sur MSDN pour cette erreur, mais j'obtiens toujours le problème. Pour le moment, le passage à un serveur 64 bits n'est pas une option pour nous.

Je sais que le redémarrage du serveur libère la mémoire qu'il contient, mais ce n'est pas une solution viable dans un environnement de production.

Existe-t-il un moyen de supprimer des caractères non numériques d'une chaîne dans SQL Server 2005 à l'aide de T-SQL uniquement?

Rachel
la source

Réponses:

14

J'ai trouvé cette fonction T-SQL sur SO qui fonctionne pour supprimer les caractères non numériques d'une chaîne.

CREATE Function [fnRemoveNonNumericCharacters](@strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
    WHILE PATINDEX('%[^0-9]%', @strText) > 0
    BEGIN
        SET @strText = STUFF(@strText, PATINDEX('%[^0-9]%', @strText), 1, '')
    END
    RETURN @strText
END
Rachel
la source
Ma question demandait une alternative T-SQL à l'utilisation de la fonction CLR. Je n'ai publié les données CLR supplémentaires que parce que vous les aviez demandées dans les commentaires, et je pensais que vous connaissiez un moyen de résoudre le problème. Je préférerais corriger la méthode CLR, mais mes recherches ont montré que le "correctif" consiste à passer à un serveur 64 bits, ce qui n'est pas une option disponible pour moi pour le moment. Je me rends compte maintenant que toutes les informations CLR dans la question peuvent être trompeuses, alors je les ai entièrement supprimées de ma question.
Rachel
J'ai pensé que peut-être la méthode que vous avez utilisée pour déployer l'assembly ou créer la fonction pourrait donner un indice. La «politique d'escalade» m'a fait penser que cela pourrait avoir quelque chose à voir avec la sécurité ou l'accès sûr / dangereux. Désolé, je ne peux pas vous être plus utile, mais sur un serveur 32 bits, il vaut mieux utiliser T-SQL à la place.
Aaron Bertrand
@AaronBertrand Pas de problème, merci pour l'entrée :) Nous espérons passer à un serveur 64 bits dans un an ou deux, donc j'espère que cela devrait éliminer complètement l'erreur CLR.
Rachel
0

Je suis assez confiant dans cette solution. Je ne suis pas certain de la performance mais tout avis sur cette approche est vraiment le bienvenu! Fondamentalement, pour chaque caractère de la chaîne @String si la valeur ASCII du caractère se situe entre les valeurs ASCII de «0» et «9», conservez-la, sinon remplacez-la par un blanc.

CREATE FUNCTION [dbo].[fnStripNonNumerics](
             @String VARCHAR(500))
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE
          @n INT = 1,
          @Return VARCHAR(100) = ''

    WHILE @n <= LEN(@String)
       BEGIN
          SET @Return = @Return + CASE
                             WHEN ASCII(SUBSTRING(@String, @n, 1)) BETWEEN ASCII('0') AND ASCII('9')
                                THEN SUBSTRING(@String, @n, 1)
                                ELSE ''
                             END
          SET @n = @n + 1
       END

    RETURN CASE
         WHEN @Return = ''
            THEN NULL
            ELSE @Return
         END
END
mateoc15
la source