【问题标题】:Remove all non-numeric characters from a field从字段中删除所有非数字字符
【发布时间】:2015-06-30 19:34:46
【问题描述】:

我有一个来自网络表单的结果集,其中包含每个集的电话号码。此电话号码的格式未强制执行(有些是 xxxxxxxxxx,有些是 (xxx)xxx-xxxx,有些是 xxx-xxx-xxxx)。这是短视的,现在我需要能够根据电话号码(视图暴露过滤器)获得结果。

对我来说解决这个问题的最佳方法是使用 sql 查询重新格式化该字段中的值,以便去除它们中的任何非数字值。我已经尝试了几个在类似问题上发现的函数,但似乎都没有工作(我正在使用 mysql 工作台并收到“函数不存在”错误)。这是我曾经做过的事情,正在寻找一个我可以运行的查询,它将去除所有非数字值。我只需要运行一次,因为我从这里开始验证电话号码是否为数字。

是否有一个 sql 查询可以满足我的需要?使用 PHP 就可以了

update table set data = preg_replace("/[^0-9]/", "", data) where condition

但我似乎找不到使用 SQL 执行此操作的方法。

【问题讨论】:

    标签: mysql drupal


    【解决方案1】:

    在 MySQL 中没有任何“内置”函数可以执行此操作。

    一种选择是创建您自己的存储函数(如果您对数据库有足够的权限)。

     DELIMITER $$
    
     DROP FUNCTION IF EXISTS `uf_only_digits`$$
    
     CREATE FUNCTION `uf_only_digits`(as_val VARCHAR(65535))
     RETURNS VARCHAR(65535)
     DETERMINISTIC
     BEGIN
       DECLARE retval VARCHAR(65535);
       DECLARE i INT;
       DECLARE strlen INT;
       -- shortcut exit for special cases
       IF as_val IS NULL OR as_val = '' THEN
         RETURN as_val;
       END IF;
       -- initialize for loop
       SET retval = '';
       SET i = 1;
       SET strlen = CHAR_LENGTH(as_val);
     do_loop:
       LOOP
         IF i > strlen THEN
           LEAVE do_loop;
         END IF;
         IF SUBSTR(as_val,i,1) IN ('0','1','2','3','4','5','6','7','8','9') THEN
           SET retval = CONCAT(retval,SUBSTR(as_val,i,1));
         END IF;
         SET i = i + 1;
       END LOOP do_loop;
       RETURN retval;
     END$$
    
     DELIMITER ;
    

    并确保在使用 UPDATE 语句之前对其进行测试

     SELECT t.foo
          , uf_only_digits(t.foo)
       FROM ( SELECT '' AS foo
              UNION ALL SELECT ' x'
              UNION ALL SELECT 'a1b2'
              UNION ALL SELECT '1-888-555-1212 ext 213'
              UNION ALL SELECT '1-800-FLOWERS'
            ) t
    

    返回:

     foo                     uf_only_digits(t.foo)  newlen  
     ----------------------  ---------------------  --------
                                                           0
      x                                                    0
     a1b2                    12                            2
     1-888-555-1212 ext 213  18885551212213               14
     1-800-FLOWERS           1800                          4
    

    (最后两行可能会让我们停下来重新考虑我们真正想要实现的目标。如果是我,我会创建一个新列,并在执行 UPDATE 之前将现有值保存在其中。)

     -- new column same size as `phone` column
     ALTER TABLE mytable ADD COLUMN orig_phone VARCHAR(40) NULL 
       COMMENT 'original phone value, before update to all digits';
    
     UPDATE mytable t
        SET t.orig_phone = t.phone ;
    
     UPDATE mytable t
        SET t.phone = uf_only_digits(t.phone) ;
    

    【讨论】:

      【解决方案2】:

      虽然不好看,但是……

      UPDATE table
      SET data =
       CONCAT(
          IF (SUBSTRING(data, 01, 1) REGEXP '[0-9]', SUBSTRING(data, 01, 1), '')
      ,   IF (SUBSTRING(data, 02, 1) REGEXP '[0-9]', SUBSTRING(data, 02, 1), '')
      ,   IF (SUBSTRING(data, 03, 1) REGEXP '[0-9]', SUBSTRING(data, 03, 1), '')
      ,   IF (SUBSTRING(data, 04, 1) REGEXP '[0-9]', SUBSTRING(data, 04, 1), '')
      ,   IF (SUBSTRING(data, 05, 1) REGEXP '[0-9]', SUBSTRING(data, 05, 1), '')
      ,   IF (SUBSTRING(data, 06, 1) REGEXP '[0-9]', SUBSTRING(data, 06, 1), '')
      ,   IF (SUBSTRING(data, 07, 1) REGEXP '[0-9]', SUBSTRING(data, 07, 1), '')
      ,   IF (SUBSTRING(data, 08, 1) REGEXP '[0-9]', SUBSTRING(data, 08, 1), '')
      ,   IF (SUBSTRING(data, 09, 1) REGEXP '[0-9]', SUBSTRING(data, 09, 1), '')
      ,   IF (SUBSTRING(data, 10, 1) REGEXP '[0-9]', SUBSTRING(data, 10, 1), '')
      ,   IF (SUBSTRING(data, 11, 1) REGEXP '[0-9]', SUBSTRING(data, 11, 1), '')
      ,   IF (SUBSTRING(data, 12, 1) REGEXP '[0-9]', SUBSTRING(data, 12, 1), '')
      ,   IF (SUBSTRING(data, 13, 1) REGEXP '[0-9]', SUBSTRING(data, 13, 1), '')
      ,   IF (SUBSTRING(data, 14, 1) REGEXP '[0-9]', SUBSTRING(data, 14, 1), '')
      ,   IF (SUBSTRING(data, 15, 1) REGEXP '[0-9]', SUBSTRING(data, 15, 1), '')
      ,   IF (SUBSTRING(data, 16, 1) REGEXP '[0-9]', SUBSTRING(data, 16, 1), '')
      )
      WHERE condition
      

      您可能需要多次复制连接的 IF 函数,具体取决于字段的长度和输入的格式。

      SQLFiddle查看实际查询

      【讨论】:

      • 此方法也不需要任何外部工具或函数创建。
      • 或者你可以做data = REPLACE(REPLACE(...REPLACE(data, '0', '')..., '8', ''), '9', '')。仍然不漂亮,但更加简洁和可扩展。
      • 目标是获取所有数字,而不是删除它们。
      【解决方案3】:

      在 MySQL 8.0+ 上,有一个名为 REGEXP_REPLACE 的新本地函数。这个问题的一个干净的解决方案是:

      update table set data = REGEXP_REPLACE(data, '[^0-9]+', "") where condition
      

      【讨论】:

        【解决方案4】:

        这可能有效,但有点乏味:

        从表格中获取数字列表

        $result = mysql_query("Select ID, number from Table"); 
        

        在每个值上

        while ($row = mysql_fetch_array($result)) { 
        $ID = $row["ID"]; 
        $NUM = $row["number"]; 
        

        然后执行一个正则表达式模式并将该值更新为 ID

        $NUM = eregi_replace("whateverregex","",$NUM); 
        
        $sql = mysql_query("Update Table set number = $NUM where ID = $ID"); 
        } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-30
          • 2011-10-19
          • 1970-01-01
          • 1970-01-01
          • 2010-11-17
          • 2010-12-04
          相关资源
          最近更新 更多