none
Resultado no esperado en patindex con expresiones regulares y collation case sensitive. ¿Ignora el case sensitive? RRS feed

  • Pregunta

  •  

    Trabajo con SQL Server 2005 sobre Windows XP

     

    Estoy teniendo un problema con expresiones regulares, patindex y collation.

    La idea es la siguiente: Uso patindex para buscar caracteres concretos, en este caso busco un carácter no minúscula
    1) mi expresión regular puede ser

              a)   [^a-z]
              b)   [^abcdefghijklmnopqrstuvwxyz]

    2) Uso un collation con case sensitive, por ejemplo: Modern_Spanish_CS_AS_KS_WS

    3) Si comparo con la 'A' la expresión regular (a) parece ignorar el case sensitive, pero la expresión regular (b) parece funcionar bien

     

    He encontrado una solución al elegir Modern_Spanish_BIN, pero no entiendo porque no funciona el caso anterior

     

    Os pongo unas consultas que me provocan este resultado inesperado

     

    select patindex(
    '%[^a-z]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'a'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --devuelve 0, lo esperado

     

    select patindex(
    '%[a-z]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'a'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --devuelve 1, lo esperado

     

    select patindex(
    '%[a-z]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'A'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --esto devuelve 1, pero por el case sensitive debería devolver 0

     

    select patindex(
    '%[^a-z]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'A'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --esto devuelve 0, pero por el case sensitive debería devolver 1

     

    select patindex(
    '%[abcdefghijklmnopqrstuvwxyz]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'A'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --devuelve 0, lo esperado. ¡Si pongo todos los caracateres en lugar de [a-z] si funciona

     

    select patindex(
    '%[^abcdefghijklmnopqrstuvwxyz]%'    collate Modern_Spanish_CS_AS_KS_WS
    ,'A'        collate Modern_Spanish_CS_AS_KS_WS
    )
    --devuelve 1, lo esperado. ¡Si pongo todos los caracateres en lugar de [^a-z] si funciona

     


     



    miércoles, 27 de julio de 2011 14:43

Respuestas

  • En este caso no tiene que ver con la intercalación (mayúsculas/minúsculas), sino con el rango que abarca la expresión "[a-z]", que como habrás adivinado por los últimos ejemplos que has puesto, es del tipo "[aAbB...zZ]". De hecho, verás resultados diferentes si usas el intervalo "[A-Z]"

    Funciona con la intercalación binaria (da igual la que pongas, lo importante es que sea binaria) porque ahí no hay margen de confusión.

    • Marcado como respuesta Ed_Madrid jueves, 28 de julio de 2011 14:51
    jueves, 28 de julio de 2011 10:15

Todas las respuestas

  • Prueba con una intercalación binaria. Mira estos resultados:

    SELECT PATINDEX(
    '%[a-z]%'   
    ,'A'    COLLATE Latin1_General_BIN
    )
    
    SELECT PATINDEX(
    '%[a-z]%'   
    ,'a'    COLLATE Latin1_General_BIN
    ) 
     
    SELECT PATINDEX(
    '%[^a-z]%'  
    ,'A'    COLLATE Latin1_General_BIN
    )
    SELECT PATINDEX(
    '%[^a-z]%'  
    ,'a'    COLLATE Latin1_General_BIN
    )
    
    


    miércoles, 27 de julio de 2011 15:45
  •  

    Gracias

    Con Modern_Spanish_BIN también funciona.

    Lo que no entiendo es porque no quiere funcionar con el case sensitive.

     

    miércoles, 27 de julio de 2011 22:07
  • ¿Que configuración regional tiene tu S.O.? Normalmente, se debe elegir un Collation de SQL Server que admita la configuración regional del sistema de Windows
     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008


    jueves, 28 de julio de 2011 9:16
  •  

    Efectivamente Norman, la intercalación que tengo es la que se sugería por defecto en la instalación y está deauerdo con la del sistema.

    Por defecto en SQL todas la bases de datos son: Modern_Spanish_CI_AI

     

    Lo que sigo sin comprender es porqué

    Modern_Spanish_BIN si funciona

    pero Modern_Spanish_CS_AS_KS_WS no funciona

     

     

    jueves, 28 de julio de 2011 9:53
  • En este caso no tiene que ver con la intercalación (mayúsculas/minúsculas), sino con el rango que abarca la expresión "[a-z]", que como habrás adivinado por los últimos ejemplos que has puesto, es del tipo "[aAbB...zZ]". De hecho, verás resultados diferentes si usas el intervalo "[A-Z]"

    Funciona con la intercalación binaria (da igual la que pongas, lo importante es que sea binaria) porque ahí no hay margen de confusión.

    • Marcado como respuesta Ed_Madrid jueves, 28 de julio de 2011 14:51
    jueves, 28 de julio de 2011 10:15
  • Las reglas que rigen la forma en que SQL Server ordena y compara los caracteres almacenados en los tipos de datos pueden ser diferentes para caracteres Unicode y no Unicode.
    Conceptos básicos de Unicode

    Las intercalaciones binarias ordenan datos según la secuencia de los valores codificados definidos por la configuración regional y los tipos de datos. Una intercalación binaria de SQL Server define la configuración regional de idioma y la página de códigos ANSI que se van a utilizar, aplicando un orden binario. Las intercalaciones binarias son útiles, gracias a su relativa simplicidad, para obtener un rendimiento mejorado de las aplicaciones. En tipos de datos no Unicode, las comparaciones de datos dependen de los puntos de código definidos en la página de códigos ANSI. En tipos de datos Unicode, las comparaciones de datos dependen de los puntos de código Unicode. En intercalaciones binarias de tipos de datos Unicode, la configuración regional no se tiene en cuenta a la hora de ordenar los datos


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008


    jueves, 28 de julio de 2011 13:19
  • Muchas gracias por todo

    Ahora sí lo he entendido.

    Tenía en mente el orden del ASCII, que efectivamente tiene las mayúsculas separadas de las minúsculas.

     

    Sólo me queda una pregunta.

    ¿Existe algún lugar dónde encontrar el detalle de las intercalaciones? (Para ver el orden y los caracteres equvalentes)

     

    jueves, 28 de julio de 2011 14:33
  • Yo, al menos, no conozco esa información tan específica. Normalmente cuando se escoge una intercalación es porque se sabe que es esa con la que tiene uno que trabajar, con lo que en principio ya conoce sus características (juego de caracteres, ordenación, etc.)

    Por cierto, si alguna de las respuestas te han ayudado para solucionar tu problema, deberías marcarlas como tal. De ese modo si alguien se encuentra en una situación similar a la tuya y busca en el foro, encontrará antes la solución.

    jueves, 28 de julio de 2011 14:49