我在一個SQL Server數據庫中有一個varchar
字段,它以許多不同的方式存儲電話號碼,但它們本質上都是電話號碼。使用正則表達式的SQL Server查詢?
實例:
8181234564
(818) 123 4564
818 - 123 - 4567
我希望我可以使用正則表達式來去掉所有非數字字符,然後執行類似的或「=」上..可以做呢?
忘記提及:我只有閱讀權限。
我在一個SQL Server數據庫中有一個varchar
字段,它以許多不同的方式存儲電話號碼,但它們本質上都是電話號碼。使用正則表達式的SQL Server查詢?
實例:
8181234564
(818) 123 4564
818 - 123 - 4567
我希望我可以使用正則表達式來去掉所有非數字字符,然後執行類似的或「=」上..可以做呢?
忘記提及:我只有閱讀權限。
如果您知道該字段包含某種有效表單中的電話號碼,那麼LIKE的下列非常醜陋的用法將與特定的號碼匹配。爲了找到818-123-4567:
select * from thetable where phonenum like ('%8%1%8%1%2%3%4%5%6%7%')
這,當然,將匹配無效的項目,以及(例如,有多餘的數字,字符,數字等)。而且這可能是一個相當昂貴的查詢,無法使用任何索引。
一個更現實的版本可能是這樣的:
select * from thetable where phonenum like ('%818%123%4567%')
這裏有一個類似的問題有答案:
How to strip all non-alphabetic characters from string in SQL Server?
答案之一展示瞭如何剝奪一切,但號碼的開出一個字符串。基本上你會創建一個UDF並使用正則表達式來清理你的非數字字符。然後你可以做你的比較。
如果你只有讀訪問,你可能斜面可以創建功能。
如果你可以創建一個功能,你可以使用一些現有的解決方案。如果沒有,這是醜陋的,但它適用於你的例子:
declare @string varchar(50)
set @string = '(818) 123 - 4564'
select replace(replace(replace(replace(@string,'(',''),' ',''),')',''),'-','')
這樣的事情在CLR或應用程序中更好做。但是如果你強烈需要在TSQL中這樣做,所以這裏是一個例子:
DECLARE @D TABLE (s NVARCHAR(1000), id INT)
INSERT INTO @D
(s, id)
VALUES ('8181234$564', 1),
('(818) 123 %&%%4564', 2),
('818 - 123 - 4567', 3) ;
WITH c (s, Char, pos, id, Out)
AS (SELECT d.s ,
SUBSTRING(d.s, 1, 1) ,
CAST(1 AS BIGINT) ,
d.id ,
CASE WHEN SUBSTRING(d.s, 1, 1) IN ('1', '2', '3', '4',
'5', '6', '7', '8',
'9', '0')
THEN CAST(SUBSTRING(d.s, 1, 1) AS NVARCHAR)
ELSE ''
END
FROM @d D
UNION ALL
SELECT d.s ,
SUBSTRING(d.s, c.pos + 1, 1) ,
c.pos + 1 ,
d.id ,
CASE WHEN SUBSTRING(d.s, c.pos + 1, 1) IN ('1', '2',
'3', '4', '5',
'6', '7', '8',
'9', '0')
THEN CAST(c.Out + SUBSTRING(d.s, c.pos + 1, 1) AS NVARCHAR)
ELSE c.Out
END
FROM @d D
JOIN C ON c.id = d.id
WHERE c.pos < LEN(c.s)
)
SELECT c.s [In] ,
c.Out
FROM c
JOIN (SELECT MAX(c2.pos) MaxPos ,
s
FROM c C2
GROUP BY C2.s
) CC ON cc.s = c.s
AND c.pos = cc.MaxPos
不幸的是,我還沒有找到這個線程呢;在VBA中有解決方案並將其修改爲SQL格式。以下是如何創建功能和如何使用示例。讓管理員添加功能最簡單快速的方式來解決您的問題。
我使用一個函數來清理電話號碼,這將修復所有電話號碼問題或清除該字段。返回NULL如果爲空(爲了防止錯誤)
Print'/*Fix Phone Numbers Call*/'
Update tblTemp
Set Phone = dbo.fnPhoneFix(tblTemp.Phone)
From tblTemp
要創建函數的恆等式使用下面的代碼:
CREATE FUNCTION [dbo].[fnPhoneFix](@PhoneOld VarChar(20))
Returns VarChar(10)
AS
Begin
Declare @iCnt Int = 0
Declare @PhoneNew VarChar(15) = ''
IF @PhoneOld IS NULL
RETURN NULL;
While @iCnt <= LEN(@PhoneOld)
Begin
IF Substring(@PhoneOld,@iCnt,1) >= '0' AND Substring(@PhoneOld,@iCnt,1) <= '9'
Begin
SET @PhoneNew = @PhoneNew + Substring(@PhoneOld,@iCnt,1)
End
Set @iCnt = @iCnt + 1
End
If LEN(@PhoneNew) > 10 and Left(@PhoneNew, 1) = '1'
Set @PhoneNew = RIGHT(@PhoneNew,10);
Else
Set @PhoneNew = Left(@PhoneNew,10);
Return @PhoneNew
End
太棒了。我將分叉版本並修改一下內聯表函數。有一天我會有機會完成它。感謝分享! – SheldonH 2016-07-11 17:05:06