2011-05-17 35 views
6

Tengo un campo varchar en una base de datos de SQL Server que almacena números de teléfono de muchas maneras diferentes, pero todos son básicamente números de teléfono.consulta de SQL Server con expresiones regulares?

Ejemplos:

8181234564 
(818) 123 4564 
818 - 123 - 4567 

Tenía la esperanza de que pueda usar expresiones regulares que se deben eliminar todos los caracteres no numéricos y luego realizar una similar o "=" on .. puedo hacer eso?

se olvidó de mencionar: solo tengo acceso de lectura.

Respuesta

1

Si sabe que el campo contiene un número de teléfono en algún tipo de formulario válido, entonces el siguiente uso realmente feo de LIKE coincidiría con un número específico. Para encontrar 818-123-4567:

select * from thetable where phonenum like ('%8%1%8%1%2%3%4%5%6%7%') 

Esto, por supuesto, se correspondería con entradas no válidas, así (por ejemplo, los números que tenían los dígitos adicionales, personajes, etc.). Y probablemente sería una consulta bastante costosa que no puede usar ningún índice.

Una versión más realista podría ser la siguiente: el acceso

select * from thetable where phonenum like ('%818%123%4567%') 
2

Si sólo ha leído probablemente no puede crear funciones tampoco.

Si puede crear una función, puede usar algunas de las soluciones existentes. Si no, esto es feo, pero funcionaría para sus ejemplos:

declare @string varchar(50) 
set @string = '(818) 123 - 4564' 

select replace(replace(replace(replace(@string,'(',''),' ',''),')',''),'-','') 
1

Este tipo de cosas es mejor que hacer en CLR o en la aplicación. Pero si necesita hacer esto en TSQL, este es un ejemplo:

DECLARE @D TABLE (s NVARCHAR(1000), id INT) 
INSERT INTO @D 
     (s, id) 
VALUES ('8181234$564', 1), 
     ('(818) 123 %&%%4564', 2), 
     ('818 - 123 - 4567', 3) ; 
WITH c (s, Char, pos, id, Out) 
      AS (SELECT d.s , 
         SUBSTRING(d.s, 1, 1) , 
         CAST(1 AS BIGINT) , 
         d.id , 
         CASE WHEN SUBSTRING(d.s, 1, 1) IN ('1', '2', '3', '4', 
                  '5', '6', '7', '8', 
                  '9', '0') 
          THEN CAST(SUBSTRING(d.s, 1, 1) AS NVARCHAR) 
          ELSE '' 
         END 
       FROM  @d D 
       UNION ALL 
       SELECT d.s , 
         SUBSTRING(d.s, c.pos + 1, 1) , 
         c.pos + 1 , 
         d.id , 
         CASE WHEN SUBSTRING(d.s, c.pos + 1, 1) IN ('1', '2', 
                   '3', '4', '5', 
                   '6', '7', '8', 
                   '9', '0') 
          THEN CAST(c.Out + SUBSTRING(d.s, c.pos + 1, 1) AS NVARCHAR) 
          ELSE c.Out 
         END 
       FROM  @d D 
         JOIN C ON c.id = d.id 
       WHERE c.pos < LEN(c.s) 
      ) 
    SELECT c.s [In] , 
      c.Out 
    FROM c 
      JOIN (SELECT MAX(c2.pos) MaxPos , 
          s 
        FROM  c C2 
        GROUP BY C2.s 
       ) CC ON cc.s = c.s 
         AND c.pos = cc.MaxPos 
+0

fantástico. Bifurcaré la versión y la modificaré un poco para una función de tabla en línea. Se publicará algún día cuando tenga la oportunidad de resolverlo. ¡gracias por compartir! – SheldonH

0

Lamentablemente no he encontrado este hilo todavía; tenía la solución en VBA y la modificó en formato SQL. A continuación se muestra cómo crear una función y una muestra de cómo usarla. Obtenga Administrador para agregar la forma más rápida y fácil de resolver su problema.

Utilizo una función para limpiar los números de teléfono que solucionará todos los problemas con el número de teléfono o borra el campo. Devuelve un valor nulo si en blanco (para evitar errores)

Print'/*Fix Phone Numbers Call*/' 
Update tblTemp 
    Set Phone = dbo.fnPhoneFix(tblTemp.Phone) 
From tblTemp 

para crear el Fuction utilice el siguiente código:

CREATE FUNCTION [dbo].[fnPhoneFix](@PhoneOld VarChar(20)) 
    Returns VarChar(10) 
AS 
    Begin 
    Declare @iCnt Int = 0 
    Declare @PhoneNew VarChar(15) = '' 

    IF @PhoneOld IS NULL 
     RETURN NULL; 

    While @iCnt <= LEN(@PhoneOld) 
     Begin 
      IF Substring(@PhoneOld,@iCnt,1) >= '0' AND Substring(@PhoneOld,@iCnt,1) <= '9' 
      Begin 
       SET @PhoneNew = @PhoneNew + Substring(@PhoneOld,@iCnt,1) 
      End 
      Set @iCnt = @iCnt + 1 
     End 

    If LEN(@PhoneNew) > 10 and Left(@PhoneNew, 1) = '1' 
     Set @PhoneNew = RIGHT(@PhoneNew,10); 
    Else 
     Set @PhoneNew = Left(@PhoneNew,10); 

    Return @PhoneNew 
End 
Cuestiones relacionadas