web-dev-qa-db-fra.com

Comment formater une colonne numérique en tant que numéro de téléphone en SQL

J'ai la table dans la base de données avec une colonne de numéro de téléphone. Les chiffres ressemblent à ceci:

123456789

Je veux formater cela pour ressembler à ceci:

123-456-789
22
avnic

Cela devrait le faire:

UPDATE TheTable
SET PhoneNumber = SUBSTRING(PhoneNumber, 1, 3) + '-' + 
                  SUBSTRING(PhoneNumber, 4, 3) + '-' + 
                  SUBSTRING(PhoneNumber, 7, 4)

Selon la suggestion de Kane, vous pouvez calculer le formatage du numéro de téléphone au moment de l'exécution. Une approche possible consisterait à utiliser des fonctions scalaires à cette fin (fonctionne dans 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
35
David Andres

Je vous recommande généralement de laisser la mise en forme au code frontal et de simplement renvoyer les données telles quelles à partir de SQL. Cependant, pour le faire en SQL, je vous recommanderais de créer une fonction définie par l'utilisateur pour le formater. Quelque chose comme ça:

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

Que vous pouvez ensuite utiliser comme ceci:

SELECT [dbo].[fnFormatPhoneNumber](PhoneNumber) AS PhoneNumber
FROM SomeTable

Il est protégé dans le cas où le numéro de téléphone stocké n'est pas le nombre de chiffres attendu, s'il est vide, vide, etc. - il ne commettra pas d'erreur.

EDIT: Vous venez de mettre à jour vos données existantes. Le principal élément de ma réponse est que vous devez vous protéger contre les données "douteuses"/incomplètes (c’est-à-dire si certaines valeurs existantes ne comportent que 5 caractères) 

15
AdaTheDev

Je ne recommande pas de conserver les données erronées dans la base de données et de les corriger uniquement à la sortie. Nous avons une base de données où les numéros de téléphone sont entrés de différentes manières:

  • (555) 555-5555
  • 555 + 555 + 5555
  • 555.555.5555
  • (555)555-5555
  • 5555555555

Différentes personnes au sein d'une organisation peuvent écrire diverses fonctions d'extraction et mises à jour dans la base de données. Il serait donc plus difficile de définir des règles de formatage et de récupération. Je corrige donc d'abord les données de la base de données, puis je mets en place des règles et des validations de formulaire qui protègent l'intégrité de cette base de données à l'avenir.

Je ne vois aucune justification pour conserver des données incorrectes à moins que, comme suggéré, une colonne en double soit ajoutée avec le formatage corrigé et les données d'origine conservées aux fins de redondance et de référence, et OUI je considère les données mal formatées comme des données BAD.

9
Daniel Byrne

Comme mentionné ci-dessus, ces solutions sont très basiques et ne fonctionneront pas si la base de données utilise différents formats de téléphone, comme:

Voici une solution plus complexe qui fonctionnera avec N'IMPORTE QUELLE entrée:

    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
9
Hiram

Les solutions qui utilisent SUBSTRING et la concaténation + sont presque indépendantes du SGBDR. Voici une solution courte spécifique à SQL Server:

declare @x int = 123456789
select stuff(stuff(@x, 4, 0, '-'), 8, 0, '-')
5
dasblinkenlight

Vous pouvez aussi essayer ceci:

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

fin

utiliser dessus sélectionner

(SELECT [dbo].[fn_FormatPhone](f.coffphone)) as 'Phone'

La sortie sera 

 enter image description here

2
atik sarker

Mise à jour de la fonction de @ sqiller pour mes besoins

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
1
Josh Jay

J'ai trouvé que cela fonctionne si vous voulez dans un format (123) - 456-7890. 

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

Vous pouvez utiliser FORMAT si votre colonne est un nombre. Syntaxe telle que FORMAT (valeur, format [ culture]) Utilisée comme FORMAT ( @d, 'D', 'en-US' ) ou FORMAT(123456789,'###-##-####') (Mais cela ne fonctionne que pour SQL SERVER 2012 et après

En cours d'utilisation similaire UPDATE TABLE_NAME SET COLUMN_NAME = FORMAT(COLUMN_NAME ,'###-##-####')

Et 

si votre colonne est Varchar ou Nvarchar, faites comme ceci CONCAT(SUBSTRING(CELLPHONE,0,4),' ',SUBSTRING(CELLPHONE,4,3),'',SUBSTRING(CELLPHONE,7,2) ,' ',SUBSTRING(CELLPHONE,9,2) )

Vous pouvez toujours obtenir de l'aide de 

https://msdn.Microsoft.com/en-us/library/hh213505.aspx

0
Toprak

Si vous souhaitez simplement formater la sortie, inutile de créer une nouvelle table ou une fonction. Dans ce scénario, l'indicatif régional figurait dans des champs distincts. J'utilise field1, field2 juste pour illustrer, vous pouvez sélectionner d'autres champs dans la même requête:

area  phone
213   8962102

Sélectionnez une déclaration:

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

Exemple de sortie:

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