【问题标题】:SQL: Add some validation steps for phone numberSQL:为电话号码添加一些验证步骤
【发布时间】:2019-10-24 17:30:40
【问题描述】:

我有一段相当简单的 SQL 代码,它将三个字段截断为一个名为“phone_number”的字段:

选择 pp.country_code_number||pp.area_code||pp.phone_number AS 电话号码

我想做的是:

  1. 删除数据中的所有非数值(例如,某些值具有“07111-245 123”,我想将其转换为“07111245123”

  2. 如果国家代码 = “44”,则只返回 pp.phone_number AS phone_number ELSE 返回 "+" 和 pp.country_code_number||pp.area_code||pp.phone_number AS phone_number

【问题讨论】:

  • (1) 用您正在使用的数据库标记您的问题。 (2) 样本数据和期望结果在文本表中是显示数据的首选方式。
  • 请参阅here,了解有关如何创建漂亮表格的一些技巧,如formatted text
  • 因此,如果我尝试插入“0sdg7esry1*^%H$1nN(#*12__4r5rtre12sdr3s”,那么“07111245123”将作为有效数字插入而不是引发某种错误?

标签: sql oracle


【解决方案1】:

简介

考虑到我不知道数据库,我在 Oracle、PostgresSql 和 MySQL 中实现了这个。 以下是(根据我的经验)最常使用 || 进行连接的 3 个数据库(请参阅:https://www.databasestar.com/sql-concatenate/)。

你需要两件事

  • 删除所有非数字字符的字符串操作函数。在我的示例中,我使用了存储过程。也许像 Forpas 示例这样的替换也很好(取决于您的要求)。在 oracle 中,您还可以使用 REGEXP_REPLACE,请参阅 Oracle: Replacing non-numeric chars in a string
  • Case 表达式或(oracle 中的解码也可以)。

示例(Oracle SQL)

WITH pp AS (

  select '30' as country_code_number, '1234' as area_code, '1234567-555' as phone_number from dual
  UNION
  select '44' as country_code_number, '1234' as area_code, '1234567-555' as phone_number from dual
)


SELECT CONCAT(CASE
                WHEN pp.country_code_number = 44 THEN ' '
                ELSE concat('+', pp.country_code_number)
                END, REGEXP_REPLACE(CONCAT (pp.area_code, pp.phone_number), '[^0-9]+', '')) AS phone_number
FROM pp;

示例(Postgres)

select 

CONCAT(
CASE WHEN pp.country_code_number <> '44' then  concat('+',pp.country_code_number)
  ELSE ' ' 
  END
,

regexp_replace( concat (  pp.area_code , pp.phone_number ) , '[^0-9]+', '', 'g')
 )  as phone_number from

 pp;

链接:https://www.db-fiddle.com/f/p6ziyWyWCGXTCiyiYSSyS8/2

示例(MySQL)

  SELECT CONCAT(CASE
                  WHEN pp.country_code_number = 44 THEN " "
                  ELSE concat('+', pp.country_code_number)
              END, STRIP_NON_DIGIT(CONCAT (pp.area_code, pp.phone_number))) AS phone_number
FROM pp;

DDL

create table pp(

  country_code_number varchar(10),
  area_code varchar(10),
  phone_number varchar(20)
);

insert into pp values('30','210','123-456-789');
insert into pp values('44','210','123-456-789');

DROP FUNCTION IF EXISTS STRIP_NON_DIGIT;
DELIMITER $$
CREATE FUNCTION STRIP_NON_DIGIT(input VARCHAR(255))
   RETURNS VARCHAR(255)
BEGIN
   DECLARE output   VARCHAR(255) DEFAULT '';
   DECLARE iterator INT          DEFAULT 1;
   WHILE iterator < (LENGTH(input) + 1) DO
      IF SUBSTRING(input, iterator, 1) IN ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
         SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
      END IF;
      SET iterator = iterator + 1;
   END WHILE;
   RETURN output;
END
$$

链接:https://www.db-fiddle.com/f/p6ziyWyWCGXTCiyiYSSyS8/1

【讨论】:

  • 非常感谢 Menelaos,您是对的,它是 Oracle。我正在尝试使用 HCM(人力资本管理)数据库在 Oracle BI 中构建报告。非常感谢您提供非常彻底的答案。
  • @Phil07952 你能接受答案,并在问题中添加标签 oracle 吗?谢谢!
  • 这个位是什么意思.. '[^0-9]+' 是在说任何不是零到九的东西? ^ 是做什么的? + 有什么用?
【解决方案2】:

您可以使用CASE 来检查国家/地区代码是否为 44,并使用函数 REPLACE()(在大多数数据库中都可以使用)来删除空格和破折号:

select 
  replace(replace(case pp.country_code
    when '44' then pp.phone_number
    else '+' || pp.country_code_number || pp.area_code || pp.phone_number 
  end, ' ', ''), '-', '') AS phone_number
from phones pp

对于 Oracle 和 PostgreSQL,您可以使用 regexp_replace() 删除 所有 非数字字符
PostgreSQL

select 
  case pp.country_code
    when '44' then regexp_replace(pp.phone_number, '[^0-9]+', '', 'g')
    else '+' || regexp_replace(pp.country_code_number || pp.area_code || pp.phone_number, '[^0-9]+', '', 'g') 
  end AS phone_number
from phones pp

甲骨文

select 
  case pp.country_code
    when '44' then regexp_replace(pp.phone_number, '[^0-9]+', '')
    else '+' || regexp_replace(pp.country_code_number || pp.area_code || pp.phone_number, '[^0-9]+', '') 
  end AS phone_number
from phones pp

【讨论】:

  • @forpas:这实际上很有帮助,而且似乎已经成功了,我只需要重新排序其中的一些:'case when pp.country_code_number = '44'' then。 .. 非常感谢 :)
猜你喜欢
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多