如何在SQL中将数字列格式化为电话号码

如何在SQL中将数字列格式化为电话号码,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,我在数据库中有一个带有电话号码列的表。数字如下所示: 123456789 123-456-789 CREATE FUNCTION [dbo].[fnFormatPhoneNumber](@PhoneNo VARCHAR(20)) RETURNS VARCHAR(25) AS BEGIN DECLARE @Formatted VARCHAR(25) IF (LEN(@PhoneNo) <> 10) SET @Formatted = @PhoneNo ELSE SE

我在数据库中有一个带有电话号码列的表。数字如下所示:

123456789
123-456-789
CREATE FUNCTION [dbo].[fnFormatPhoneNumber](@PhoneNo VARCHAR(20))
RETURNS VARCHAR(25)
AS
BEGIN
DECLARE @Formatted VARCHAR(25)

IF (LEN(@PhoneNo) <> 10)
    SET @Formatted = @PhoneNo
ELSE
    SET @Formatted = LEFT(@PhoneNo, 3) + '-' + SUBSTRING(@PhoneNo, 4, 3) + '-' + SUBSTRING(@PhoneNo, 7, 4)

RETURN @Formatted
END
GO
SELECT [dbo].[fnFormatPhoneNumber](PhoneNumber) AS PhoneNumber
FROM SomeTable
我想将其格式化为如下所示:

123456789
123-456-789
CREATE FUNCTION [dbo].[fnFormatPhoneNumber](@PhoneNo VARCHAR(20))
RETURNS VARCHAR(25)
AS
BEGIN
DECLARE @Formatted VARCHAR(25)

IF (LEN(@PhoneNo) <> 10)
    SET @Formatted = @PhoneNo
ELSE
    SET @Formatted = LEFT(@PhoneNo, 3) + '-' + SUBSTRING(@PhoneNo, 4, 3) + '-' + SUBSTRING(@PhoneNo, 7, 4)

RETURN @Formatted
END
GO
SELECT [dbo].[fnFormatPhoneNumber](PhoneNumber) AS PhoneNumber
FROM SomeTable
这应该做到:

UPDATE TheTable
SET PhoneNumber = SUBSTRING(PhoneNumber, 1, 3) + '-' + 
                  SUBSTRING(PhoneNumber, 4, 3) + '-' + 
                  SUBSTRING(PhoneNumber, 7, 4)
根据凯恩的建议,您可以在运行时计算电话号码的格式。一种可能的方法是为此目的使用标量函数(在SQL Server中工作):


我通常建议您将格式设置留给前端代码,只需按原样从SQL返回数据。然而,要在SQL中实现这一点,我建议您创建一个用户定义的函数来格式化它。大概是这样的:

123456789
123-456-789
CREATE FUNCTION [dbo].[fnFormatPhoneNumber](@PhoneNo VARCHAR(20))
RETURNS VARCHAR(25)
AS
BEGIN
DECLARE @Formatted VARCHAR(25)

IF (LEN(@PhoneNo) <> 10)
    SET @Formatted = @PhoneNo
ELSE
    SET @Formatted = LEFT(@PhoneNo, 3) + '-' + SUBSTRING(@PhoneNo, 4, 3) + '-' + SUBSTRING(@PhoneNo, 7, 4)

RETURN @Formatted
END
GO
SELECT [dbo].[fnFormatPhoneNumber](PhoneNumber) AS PhoneNumber
FROM SomeTable
它有一个保护措施,以防存储的电话号码不是预期的数字长,是空白的,空等-它不会出错


编辑:刚刚打卡,您想更新现有数据。与我的回答相关的主要一点是,您需要防止“不可靠的”/不完整的数据(即,如果某些现有值只有5个字符长该怎么办)

我不建议在数据库中保留坏数据,然后只在输出中更正它。我们有一个数据库,其中电话号码的输入方式多种多样:

  • (555)555-5555
  • 555+555+5555
  • 555.555.5555
  • (555)555-5555
  • 55555555
组织中的不同人员可能会编写不同的检索功能和数据库更新,因此很难设置适当的格式和检索规则。因此,我首先要更正数据库中的数据,然后设置适当的规则和表单验证,以保护数据库的完整性


我认为没有保留坏数据的理由,除非建议重复的列加上纠正的格式,并且保留原始数据以供冗余和引用,而且是的,我认为格式不良的数据是坏数据。这些解决方案非常基本,如果数据库具有不同的电话格式,例如:

(123)123-4564
123-456-4564
1234567989
etc
下面是一个更复杂的解决方案,可用于任何给定的输入:

CREATE FUNCTION [dbo].[ufn_FormatPhone] (@PhoneNumber VARCHAR(32))
RETURNS VARCHAR(32)
AS
BEGIN
    DECLARE @Phone CHAR(32)

    SET @Phone = @PhoneNumber

    -- cleanse phone number string
    WHILE PATINDEX('%[^0-9]%', @PhoneNumber) > 0
        SET @PhoneNumber = REPLACE(@PhoneNumber, SUBSTRING(@PhoneNumber, PATINDEX('%[^0-9]%', @PhoneNumber), 1), '')

    -- skip foreign phones
    IF (
            SUBSTRING(@PhoneNumber, 1, 1) = '1'
            OR SUBSTRING(@PhoneNumber, 1, 1) = '+'
            OR SUBSTRING(@PhoneNumber, 1, 1) = '0'
            )
        AND LEN(@PhoneNumber) > 11
        RETURN @Phone

    -- build US standard phone number
    SET @Phone = @PhoneNumber
    SET @PhoneNumber = '(' + SUBSTRING(@PhoneNumber, 1, 3) + ') ' + SUBSTRING(@PhoneNumber, 4, 3) + '-' + SUBSTRING(@PhoneNumber, 7, 4)

    IF LEN(@Phone) - 10 > 1
        SET @PhoneNumber = @PhoneNumber + ' X' + SUBSTRING(@Phone, 11, LEN(@Phone) - 10)

    RETURN @PhoneNumber
END

我发现,如果需要(123)-456-7890格式,这种方法是有效的

UPDATE table 
SET Phone_number =  '(' +  
                    SUBSTRING(Phone_number, 1, 3) 
                    + ') ' 
                    + '- ' +
                    SUBSTRING(Phone_number, 4, 3) 
                    + '-' +
                    SUBSTRING(Phone_number, 7, 4) 

为我的目的更新了@sqiller的函数

CREATE FUNCTION [toolbox].[FormatPhoneNumber] (
    @PhoneNumber VARCHAR(50),
    @DefaultIfUnknown VARCHAR(50)
)
RETURNS VARCHAR(50)
AS
BEGIN
    -- remove any extension
    IF CHARINDEX('x', @PhoneNumber, 1) > 0
        SET @PhoneNumber = SUBSTRING(@PhoneNumber, 1, CHARINDEX('x', @PhoneNumber, 1) - 1)

    -- cleanse phone number string
    WHILE PATINDEX('%[^0-9]%',@PhoneNumber) > 0
        SET @PhoneNumber = REPLACE(@PhoneNumber,
                SUBSTRING(@PhoneNumber,PATINDEX('%[^0-9]%',@PhoneNumber),1),'')

    -- Remove US international code if exists, i.e. 12345678900
    IF SUBSTRING(@PhoneNumber,1,1) = '1' AND LEN(@PhoneNumber) = 11
        SET @PhoneNumber = SUBSTRING(@PhoneNumber, 2, 10)

    -- any phone numbers without 10 characters are set to default
    IF LEN(@PhoneNumber) <> 10
        RETURN @DefaultIfUnknown

    -- build US standard phone number
    SET @PhoneNumber = '(' + SUBSTRING(@PhoneNumber,1,3) + ') ' +
                SUBSTRING(@PhoneNumber,4,3) + '-' + SUBSTRING(@PhoneNumber,7,4)

    RETURN @PhoneNumber
END
创建函数[工具箱].[FormatPhoneNumber](
@电话号码VARCHAR(50),
@DefaultIfUnknown VARCHAR(50)
)
返回VARCHAR(50)
作为
开始
--删除任何扩展
如果CHARINDEX('x',@PhoneNumber,1)>0
设置@PhoneNumber=SUBSTRING(@PhoneNumber,1,CHARINDEX('x',@PhoneNumber,1)-1)
--清除电话号码字符串
而PATINDEX(“%[^0-9]]”,@PhoneNumber)>0
设置@PhoneNumber=REPLACE(@PhoneNumber,
子字符串(@PhoneNumber,PATINDEX(“%[^0-9]”,@PhoneNumber),1),“”)
--删除美国国际代码(如果存在),即12345678900
如果子字符串(@PhoneNumber,1,1)='1'和LEN(@PhoneNumber)=11
设置@PhoneNumber=SUBSTRING(@PhoneNumber,2,10)
--任何不含10个字符的电话号码都将设置为默认值
如果LEN(@PhoneNumber)10
返回@DefaultIfUnknown
--建立美国标准电话号码
设置@PhoneNumber='('+子字符串(@PhoneNumber,1,3)+')”+
子字符串(@PhoneNumber,4,3)+'-'+子字符串(@PhoneNumber,7,4)
返回@PhoneNumber
结束

使用
子字符串和串联
+
的解决方案几乎独立于RDBMS。下面是一个针对SQL Server的简短解决方案:

CREATE FUNCTION FormatPhoneNumber(@phoneNumber VARCHAR(10))
RETURNS VARCHAR(12)
BEGIN
    RETURN SUBSTRING(@phoneNumber, 1, 3) + '-' + 
           SUBSTRING(@phoneNumber, 4, 3) + '-' + 
           SUBSTRING(@phoneNumber, 7, 4)
END
declare @x int = 123456789
select stuff(stuff(@x, 4, 0, '-'), 8, 0, '-')
您也可以尝试以下方法:

CREATE  function [dbo].[fn_FormatPhone](@Phone varchar(30)) 
returns varchar(30)
As
Begin
declare @FormattedPhone varchar(30)

set     @Phone = replace(@Phone, '.', '-') --alot of entries use periods instead of dashes
set @FormattedPhone =
    Case
      When isNumeric(@Phone) = 1 Then
        case
          when len(@Phone) = 10 then '('+substring(@Phone, 1, 3)+')'+ ' ' +substring(@Phone, 4, 3)+ '-' +substring(@Phone, 7, 4)
          when len(@Phone) = 7  then substring(@Phone, 1, 3)+ '-' +substring(@Phone, 4, 4)
          else @Phone
        end
      When @phone like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]' Then '('+substring(@Phone, 1, 3)+')'+ ' ' +substring(@Phone, 5, 3)+ '-' +substring(@Phone, 8, 4)
      When @phone like '[0-9][0-9][0-9] [0-9][0-9][0-9] [0-9][0-9][0-9][0-9]' Then '('+substring(@Phone, 1, 3)+')'+ ' ' +substring(@Phone, 5, 3)+ '-' +substring(@Phone, 9, 4)
      When @phone like '[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]' Then '('+substring(@Phone, 1, 3)+')'+ ' ' +substring(@Phone, 5, 3)+ '-' +substring(@Phone, 9, 4)
      Else @Phone
    End
return  @FormattedPhone
结束

在它上面使用选择

(SELECT [dbo].[fn_FormatPhone](f.coffphone)) as 'Phone'
输出将是


如果只想格式化输出,无需创建新表或函数。在这种情况下,区号位于单独的字段上。我使用
field1
field2
只是为了说明您可以在同一查询中选择其他字段:

area  phone
213   8962102
Select语句:

Select field1, field2,areacode,phone,SUBSTR(tablename.areacode,1,3) + '-' + SUBSTR(tablename.phone,1,3) + '-' + SUBSTR(tablename.areacode,4,4) as Formatted Phone from tablename
样本输出:

columns: FIELD1, FIELD2, AREA, PHONE, FORMATTED PHONE
data:    Field1, Field2, 213,  8962102,  213-896-2102

如果列是数字语法,则可以使用格式 正在使用的格式(值、格式[、区域性])与
格式(@d,'d,'en-US')
格式(123456789,###############)
(但这只适用于SQL SERVER 2012及之后的

在使用中就像
updatetable_NAME SET COLUMN_NAME=FORMAT(COLUMN_NAME,###-#-#-##-##)

如果您的列是Varchar或Nvarchar,请这样做
CONCAT(子串(手机,0,4),'',子串(手机,4,3),'
,子串(手机,7,2),'',子串(手机,9,2))

你总是可以从别人那里得到帮助


您想用SQL或您的客户端显示代码(ASP、WinForms、XML等)对它们进行格式化吗?到SQL-换言之,更新到新格式如果您想保留原始值并使用新格式,您可以添加一个计算列(使用类似于上面@David的答案),该列应该是
返回varchar(12)和最后的<代码>子串< /代码>需要是“代码>子串(@ PosiNeNobe,7, 4)< /Calp>”Serj Sagan:谢谢,我已经更新了代码作为注意事项。您可能需要考虑更新代码示例来检查,以查看长度10字符是否是这个上下文中最小的有效数字。加上前缀,它将是11个字符。else语句也是如此。你想把这些组分为3位数字+ 3位数字+ 4位数字,我不确定我是否会考虑这个问题的电话号码示例格式不正确。有时,尤其是在大型组织中,数据源不在您的控制范围内,只能在输出时更正。电话号码不能使用数字格式,因为前导零是相关的!可以。选择格式(5553274153,‘000-000-0000’)