Wie kann ich nicht numerische Zeichen aus einer Zeichenfolge entfernen?

10

Benutzer geben einen Suchbegriff in ein Feld ein, und dieser Wert wird an eine gespeicherte Prozedur übergeben und mit einigen verschiedenen Feldern in der Datenbank verglichen. Diese Felder haben nicht immer den gleichen Datentyp.

Ein Feld (Telefonnummer) besteht aus allen Zahlen. Wenn Sie es aktivieren, werden alle nicht numerischen Zeichen mithilfe einer .Net CLR-Funktion aus der Zeichenfolge entfernt.

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

Das Problem ist, dass diese Funktion gelegentlich abrupt mit dem folgenden Fehler nicht mehr funktioniert:

Nachricht 6533, Ebene 16, Status 49, Zeile 2
AppDomain MyDBName.dbo [Laufzeit] .1575 wurde durch eine Eskalationsrichtlinie entladen, um sicherzustellen, dass 
Konsistenz Ihrer Anwendung. Beim Zugriff auf eine kritische Ressource ist nicht genügend Speicher vorhanden.
System.Threading.ThreadAbortException: Ausnahme vom Typ 
'System.Threading.ThreadAbortException' wurde ausgelöst.
System.Threading.ThreadAbortException: 

Ich habe die auf MSDN veröffentlichten Vorschläge für diesen Fehler ausprobiert, erhalte aber immer noch das Problem. Derzeit ist ein Wechsel zu einem 64-Bit-Server für uns keine Option.

Ich weiß, dass ein Neustart des Servers den darin enthaltenen Speicher freigibt, aber das ist in einer Produktionsumgebung keine praktikable Lösung.

Gibt es eine Möglichkeit, nicht numerische Zeichen in SQL Server 2005 nur mit T-SQL aus einer Zeichenfolge zu entfernen?

Rachel
quelle

Antworten:

14

Ich habe diese T-SQL-Funktion in SO gefunden, mit der nicht numerische Zeichen aus einer Zeichenfolge entfernt werden können.

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
quelle
Meine Frage war nach einer T-SQL-Alternative zur Verwendung der CLR-Funktion. Ich habe die zusätzlichen CLR-Daten nur veröffentlicht, weil Sie in den Kommentaren danach gefragt haben, und ich dachte, Sie wüssten, wie Sie das Problem beheben können. Ich würde es vorziehen, die CLR-Methode zu korrigieren, aber meine Untersuchungen haben gezeigt, dass das "Update" darin besteht, auf einen 64-Bit-Server zu aktualisieren, was für mich derzeit keine verfügbare Option ist. Mir ist jetzt klar, dass alle CLR-Informationen in der Frage irreführend sein können, deshalb habe ich sie vollständig aus meiner Frage entfernt.
Rachel
Ich dachte, dass die Methode, mit der Sie die Assembly bereitgestellt oder die Funktion erstellt haben, möglicherweise einen Hinweis liefert. "Eskalationsrichtlinie" ließ mich denken, dass dies etwas mit Sicherheit oder sicherem / unsicherem Zugriff zu tun haben könnte. Es tut mir leid, ich kann Ihnen nicht weiterhelfen, aber auf einem 32-Bit-Server ist es möglicherweise am besten, stattdessen T-SQL zu verwenden.
Aaron Bertrand
@AaronBertrand Kein Problem, danke für die Eingabe :) Wir hoffen, in den nächsten ein oder zwei Jahren auf einen 64-Bit-Server umsteigen zu können. Hoffentlich sollte dies den CLR-Fehler vollständig beheben.
Rachel
0

Ich bin ziemlich zuversichtlich in diese Lösung. Ich bin mir über die Leistung nicht sicher, aber Meinungen zu diesem Ansatz sind auf jeden Fall willkommen! Grundsätzlich gilt für jedes Zeichen in der Zeichenfolge @String, dass der ASCII-Wert des Zeichens zwischen den ASCII-Werten '0' und '9' liegt, andernfalls wird er durch ein Leerzeichen ersetzt.

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
quelle