2012-11-05 27 views
13

Ich habe eine große Datenbank, in der ich eine Teilzeichenfolge suchen möchte. Der Benutzer gibt Zeichen ein: JoeBloggs.Entfernen Sie Zahlen von String sql Server

Für Argumente willen, wenn ich einen Namen Joe 23 Blo Ggs 4 in der Datenbank hatte. Ich möchte alles im Namen außer A-Z entfernen.

Ich habe die REPLACE(Name, ' ','') Funktion zum Entfernen von Leerzeichen und die UPPER() Funktion, um den Namen zu aktivieren.

Gibt es eine effizientere schnelle Möglichkeit, vielleicht durch Begriffe der Regex, um etwas anderes als A-Z zu ersetzen. Ich kann die Werte in der Datenbank nicht ändern.

Vielen Dank im Voraus

+0

Sie sagen, dass Sie die Daten nicht ändern können. Können Sie der vorhandenen Tabelle eine berechnete Spalte hinzufügen? Oder fügen Sie eine neue Tabelle mit einem Fremdschlüssel und Ihrem berechneten Wert hinzu? – Laurence

+0

@Laurence - Ja, ich nehme an, dass ich das kann, aber können wir das in einer temporären Tabelle in einer gespeicherten Prozedur tun? Wenn nicht, dann kann ich diese berechnete Spalte anfordern, alles, was ich brauche, ist die Funktion zum Ersetzen. Vielen Dank für Ihre schnelle Antwort – CR41G14

+0

Ich würde nicht empfehlen, Regexps zu verwenden, wenn die Leistung wichtig ist. Die Art, wie Sie verwenden, ist offensichtlich, aber immer noch eine gute! – vyakhir

Antwort

25

erste Option -

Sie REPLACE() Funktionen bis tief zu 32 Ebenen verschachtelt werden. Es läuft schnell.

REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE 
(REPLACE (@str, '0', ''), 
'1', ''), 
'2', ''), 
'3', ''), 
'4', ''), 
'5', ''), 
'6', ''), 
'7', ''), 
'8', ''), 
'9', '') 

zweite Option - tun das Gegenteil von -

Removing nonnumerical data out of a number + SQL

3. Option - wenn Sie regeex

dann http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=27205

-1

Nicht getestet verwenden möchten, aber Sie können so etwas tun:

Create Function dbo.AlphasOnly(@s as varchar(max)) Returns varchar(max) As 
Begin 
    Declare @Pos int = 1 
    Declare @Ret varchar(max) = null 
    If @s Is Not Null 
    Begin 
    Set @Ret = '' 
    While @Pos <= Len(@s) 
    Begin 
     If SubString(@s, @Pos, 1) Like '[A-Za-z]' 
     Begin 
     Set @Ret = @Ret + SubString(@s, @Pos, 1) 
     End 
     Set @Pos = @Pos + 1 
    End 
    End 
    Return @Ret 
End 

Der Schlüssel ist, dies als eine berechnete Spalte zu verwenden und sie zu indizieren. Es spielt keine Rolle, wie schnell Sie diese Funktion ausführen, wenn die Datenbank sie bei jeder Ausführung der Abfrage für jede Zeile in Ihrer großen Tabelle ausführen muss.

+0

sehr langsame Lösung, schnell ist erforderlich – CR41G14

+0

Wenn Sie darauf bestehen, '' Namen aus dem Test zu wählen, wo dbo.AlphasOnly (name) = 'JoeBloggs'', dann wird das langsam sein, auch wenn die Funktion 0 Zeit dauert. Sie zahlen immer noch die Kosten für das Lesen aller Zeilen von der Festplatte (vorausgesetzt, Sie sagen Sie große Tabelle, dass Ihre Datenbank nicht in den Speicher passt). Um es schnell zu machen, müssen Sie eine Möglichkeit finden, es zu indizieren, weshalb ich eine berechnete Spalte vorschlage. – Laurence

12

Dieses funktioniert für mich

CREATE Function [dbo].[RemoveNumericCharacters](@Temp VarChar(1000)) 
Returns VarChar(1000) 
AS 
Begin 

    Declare @NumRange as varchar(50) = '%[0-9]%' 
    While PatIndex(@NumRange, @Temp) > 0 
     Set @Temp = Stuff(@Temp, PatIndex(@NumRange, @Temp), 1, '') 

    Return @Temp 
End 

und Sie es wie so

SELECT dbo.[RemoveNumericCharacters](Name) FROM TARGET_TABLE 
0

Zitiert Teil @Jatin Antwort mit einigen Modifikationen,

Verwendung dieses

in Ihrer where Anweisung verwenden :

SELECT * FROM .... etc. 
     Where 
     REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE 
     (REPLACE (Name, '0', ''), 
     '1', ''), 
     '2', ''), 
     '3', ''), 
     '4', ''), 
     '5', ''), 
     '6', ''), 
     '7', ''), 
     '8', ''), 
     '9', '') = P_SEARCH_KEY 
2

Ein weiterer Ansatz rekursive CTE ..

declare @string varchar(100) 
set @string ='te165st1230004616161616' 

;With cte 
as 
(
select @string as string,0 as n 
union all 
select cast(replace(string,n,'') as varchar(100)),n+1 
from cte 
where n<9 
) 
select top 1 string from cte 
order by n desc 


**Output:** 
    test 
0

unten für Ihre Abfrage Versuchen. Dabei ist val der Name Ihrer Zeichenfolge oder Spalte.

CASE WHEN PATINDEX('%[a-z]%', REVERSE(val)) > 1 
       THEN LEFT(val, LEN(val) - PATINDEX('%[a-z]%', REVERSE(val)) + 1) 
      ELSE '' END