2012-11-05 35 views
13

Tôi có một cơ sở dữ liệu lớn mà tôi muốn thực hiện tìm kiếm chuỗi một phần. Người dùng sẽ nhập các ký tự: JoeBloggs.Xóa số từ máy chủ chuỗi sql

Vì lý do, nếu tôi có tên Joe 23 Blo Ggs 4 trong cơ sở dữ liệu. Tôi muốn xóa mọi thứ trong tên khác với A-Z.

Tôi có chức năng REPLACE(Name, ' ','') để xóa không gian và chức năng UPPER() để viết hoa tên.

Có cách nào hiệu quả hơn có thể nhanh chóng bằng cách thay đổi regex để thay thế bất kỳ thứ gì ngoài A-Z. Tôi không thể thay đổi các giá trị trong cơ sở dữ liệu.

Cảm ơn trước

+0

Bạn nói rằng bạn không thể thay đổi dữ liệu. Bạn có thể thêm cột được tính vào bảng hiện tại không? Hoặc thêm một bảng mới với một khóa ngoại và giá trị tính toán của bạn? – Laurence

+0

@Laurence - Yea Tôi cho rằng tôi có thể làm điều này nhưng chúng ta có thể làm điều này trong một bảng tạm thời trong một thủ tục được lưu trữ không? Nếu không thì tôi có thể yêu cầu cột tính toán này, tất cả những gì tôi cần là chức năng để thay thế. Cảm ơn bạn đã phản hồi nhanh chóng – CR41G14

+0

Tôi không khuyên bạn nên sử dụng regexps nếu vấn đề hiệu suất. Cách bạn sử dụng là hiển nhiên nhưng vẫn tốt! – vyakhir

Trả lời

25

1 tùy chọn -

Bạn có thể lồng REPLACE() chức năng lên đến 32 cấp độ sâu. Nó chạy nhanh.

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

tùy chọn thứ 2 - làm điều ngược lại của -

Removing nonnumerical data out of a number + SQL

tùy chọn thứ 3 - nếu bạn muốn sử dụng regeex

sau đó http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=27205

-1

Không thử nghiệm, nhưng bạn có thể làm như sau:

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 

Điều quan trọng là sử dụng cột này làm cột được tính toán và lập chỉ mục. Nó không thực sự quan trọng như thế nào nhanh chóng bạn thực hiện chức năng này nếu cơ sở dữ liệu có để thực hiện nó chống lại mọi hàng trong bảng lớn của bạn mỗi khi bạn chạy truy vấn.

+0

giải pháp rất chậm, nhanh chóng được yêu cầu – CR41G14

+0

Nếu bạn nhấn mạnh vào làm 'Chọn tên từ thử nghiệm nơi dbo.AlphasOnly (name) = 'JoeBloggs'' sau đó điều này sẽ được làm chậm ngay cả khi chức năng mất 0 thời gian.Bạn vẫn phải trả chi phí đọc tất cả các hàng ra khỏi đĩa (giả sử khi bạn nói lớn bảng bạn có nghĩa là cơ sở dữ liệu của bạn không phù hợp trong bộ nhớ) Để làm cho nó nhanh chóng, bạn cần phải tìm một cách lập chỉ mục nó, đó là lý do tại sao tôi đề nghị một cột tính toán. – Laurence

12

một này làm việc cho tôi

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 

và bạn có thể sử dụng nó như vậy

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

Trích dẫn một phần của @Jatin câu trả lời với một số sửa đổi,

sử dụng này trong bản Tuyên Bố where của bạn :

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

Một cách tiếp cận khác bằng cách sử dụng CTE đệ quy ..

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

Hãy thử bên dưới cho truy vấn của bạn. trong đó val là tên chuỗi hoặc cột của bạn.

CASE WHEN PATINDEX('%[a-z]%', REVERSE(val)) > 1 
       THEN LEFT(val, LEN(val) - PATINDEX('%[a-z]%', REVERSE(val)) + 1) 
      ELSE '' END 
Các vấn đề liên quan