SQL标量函数的效率



我有一个三个数据库的应用程序(不是由我开发的),其中存储了许多电话号码,但它们的格式不一致(555-5555,(555)555-5555,5555555555,55555555,55555555等)在web方面,我希望它们总是像555-5555 -5555一样显示。我已经写了一个标量函数来清理它们,但是它会经常被调用,我担心它的效率。

你可以看一下,如果有更好的方法,请告诉我。

ALTER FUNCTION [dbo].[FormatPhone]
(
  @p AS VARCHAR(20)
) RETURNS VARCHAR(12) AS
BEGIN
DECLARE @ret AS VARCHAR(12) = ''
DECLARE @c AS CHAR
DECLARE @i AS INT
DECLARE @stop AS INT
-- loop to grab only digits from @p
SET @i = 1
SET @stop = LEN(@p)
WHILE @i <= @stop
BEGIN
    SET @c = SUBSTRING(@p, @i, 1)
    IF @c >= '0' AND @c <= '9' SET @ret = @ret + @c
    SET @i = @i + 1
END
IF LEN(@ret) = 7 SET @ret = '204' + @ret -- account for forgotten area code
SET @ret = LEFT(@ret, 3) + '-' + SUBSTRING(@ret, 4, 3) + '-' + RIGHT(@ret, 4)
RETURN @ret

谢谢!尼克。

您正在谈论的是数据清理。以我的经验来看(我有一个为期6个月的俄罗斯业务部门项目,其中90%的时间是在电话号码格式的问题上绞尽脑汁),这是一件非常痛苦的事情。

我的建议是只做一次,而且要做得正确;然后将系统放置到位,以防止脏数据在将来进入系统。

我们最后做的是让行政办公室的几个女孩手工完成!问题是,如果你做错了,你就会让数据变得无用。尝试一下自动解析,看看它能给你带来什么,但有时人胜过机器。

  • 替换除数字以外的所有字符
  • 转换成样品XXX-XXX-XXXX

使用子字符串,替换T-SQL

此函数查看数字/字符串以确定大小和格式,不循环

CREATE Function [dbo].[FormatPhone] (@PD varchar(50))
RETURNS Varchar(50)
As 
Begin
Declare @F1 As tinyint
Declare @F2 As tinyint
Declare @F3 As tinyint
Declare @F4 As tinyint
Declare @F5 As tinyint
Declare @F6 As tinyint
Declare @NPD As Varchar(50)
Declare @PDLen As tinyint
--Trim any space off the ends
SET @PD = RTRIM(LTRIM(@PD))
--Default just return the data, unless in proper foramt
SET @NPD = @PD
--Check for phone number that all ready has formatting, 
--we are only going to format a 'Pure' set of numbers.
--Check for formating, space 
SET @F1 = CHARINDEX('(', @PD)
SET @F2 = CHARINDEX(')', @PD)
SET @F3 = CHARINDEX('-', @PD)
SET @F4 = CHARINDEX('.', @PD)
SET @F5 = CHARINDEX(' ', @PD)
SET @F6 = @F1 +@F2 + @F3 + @F4 + @F5

IF @F6 = 0
--No formating, figure out the lenght
BEGIN
SET @PDLen = LEN(@PD)
    IF @PDLen = 10  SET @NPD = '('+SUBSTRING(@PD, 1, 3)+') '+SUBSTRING(@PD, 4, 3)+'-'+SUBSTRING(@PD, 7, 4)
    IF @PDLen = 11 AND SUBSTRING(@PD, 1, 1) = '1'  SET @NPD = '('+SUBSTRING(@PD, 2, 3)+') '+SUBSTRING(@PD, 5, 3)+'-'+SUBSTRING(@PD, 8, 4)
    IF @PDLen = 7  SET @NPD = '(   ) '+SUBSTRING(@PD, 1, 3)+'-'+SUBSTRING(@PD, 4, 4)
END
RETURN @NPD
END

最新更新