我在一个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