db2 ibm-midrange

Sensibilidad de la caja de DB2



ibm-midrange (4)

¿Por qué no hacer esto?

WHERE lower(LastName) = ''smith''

Si le preocupa el rendimiento (es decir, la consulta que no utiliza un índice), tenga en cuenta que DB2 tiene índices de función, que puede leer aquí . Entonces, esencialmente, puedes crear un índice en la parte upper(LastName) .

EDITAR Para hacer la técnica de depuración que discutí en los comentarios, podrías hacer algo como esto:

create table log (msg varchar(100, dt date);

Luego, en su SP, puede insertar mensajes en esta tabla para fines de depuración:

insert into log (msg, dt) select ''inside the SP'', current_date from sysibm.sysdummy1;

Luego, después de que se ejecuta el SP, puede seleccionar de esta tabla de registro para ver qué sucedió.

Tengo grandes dificultades para hacer que mis consultas a DB2 (AS / 400) sean insensibles.

Por ejemplo:

SELECT * FROM NameTable WHERE LastName = ''smith''

No devolverá resultados, pero el siguiente devuelve 1000 de resultados:

SELECT * FROM NameTable WHERE LastName = ''Smith''

He leído acerca de poner SortSequence / SortType en su cadena de conexión, pero no he tenido suerte ... ¿Alguien tiene alguna relación con esto?

Editar:

Aquí está el procedimiento almacenado:

BEGIN DECLARE CR CURSOR FOR SELECT T . ID , T . LASTNAME , T . FIRSTNAME , T . MIDDLENAME , T . STREETNAME || '' '' || T . ADDRESS2 || '' '' || T . CITY || '' '' || T . STATE || '' '' || T . ZIPCODE AS ADDRESS , T . GENDER , T . DOB , T . SSN , T . OTHERINFO , T . APPLICATION FROM ( SELECT R . * , ROW_NUMBER ( ) OVER ( ) AS ROW_NUM FROM CPSAB32.VW_MYVIEW WHERE R . LASTNAME = IFNULL ( @LASTNAME , LASTNAME ) AND R . FIRSTNAME = IFNULL ( @FIRSTNAME , FIRSTNAME ) AND R . MIDDLENAME = IFNULL ( @MIDDLENAME , MIDDLENAME ) AND R . DOB = IFNULL ( @DOB , DOB ) AND R . STREETNAME = IFNULL ( @STREETNAME , STREETNAME ) AND R . CITY = IFNULL ( @CITY , CITY ) AND R . STATE = IFNULL ( @STATE , STATE ) AND R . ZIPCODE = IFNULL ( @ZIPCODE , ZIPCODE ) AND R . SSN = IFNULL ( @SSN , SSN ) FETCH FIRST 500 ROWS ONLY ) AS T WHERE ROW_NUM <= @MAXRECORDS OPTIMIZE FOR 500 ROW ; OPEN CR ; RETURN ;


Hice algo similar cuando quería una búsqueda insensible a mayúsculas y minúsculas. Utilicé UPPER(mtfield) = ''SEARCHSTRING'' . Sé que esto funciona


Si desea distinguir entre mayúsculas y minúsculas en su procedimiento, intente utilizar esta opción en él:

SET OPTION SRTSEQ = *LANGIDSHR ;

También debe crear un índice para respaldarlo para el rendimiento. Cree el índice cuando tenga *LANGIDSHR como atributo de conexión, y el índice de peso compartido debería estar disponible para trabajos posteriores. (Hay varias maneras de poner en práctica la configuración adecuada).

*LANGIDSHR relaciona con la identificación del idioma para sus trabajos. Los personajes en el conjunto de caracteres que podrían considerarse "iguales", como ''A'' y ''a'' o ''ü'' y ''u'', deberían tener pesos iguales (compartidos) y seleccionarlos juntos.


Ver: https://.com/a/47181640/5507619

Configuración de la base

Hay una configuración de configuración de base de datos que puede establecer en la creación de la base de datos . Sin embargo, está basado en Unicode.

CREATE DATABASE yourDB USING COLLATE UCA500R1_S1

El algoritmo de intercalación Unicode predeterminado se implementa mediante la palabra clave UCA500R1 sin ningún atributo. Dado que el UCA predeterminado no puede abarcar simultáneamente la secuencia de clasificación de todos los idiomas admitidos por Unicode, se pueden especificar atributos opcionales para personalizar el ordenamiento de UCA. Los atributos están separados por el carácter de subrayado (_). La palabra clave UCA500R1 y los atributos forman un nombre de intercalación de UCA.

El atributo Strength determina si se tiene en cuenta acento o caso al cotejar o comparar cadenas de texto. Al escribir sistemas sin caso o acento, el atributo de Fortaleza controla características de importancia similar. Los valores posibles son: primario (1), secundario (2), terciario (3), cuaternario (4) e identidad (I). Ignorar:

  • acento y caso, usa el nivel de fuerza principal
  • solo caso, use el nivel de fuerza secundario
  • ni acento ni caso, use el nivel de fuerza terciaria

Casi todos los caracteres se pueden distinguir por los primeros tres niveles de intensidad, por lo tanto, en la mayoría de las configuraciones regionales, el atributo de Fuerza predeterminado se establece en el nivel terciario. Sin embargo, si el atributo Alternativo (descrito a continuación) está configurado para desplazarse, entonces el nivel de fuerza cuaternario se puede usar para romper relaciones entre caracteres de espacios en blanco, signos de puntuación y símbolos que de otra manera serían ignorados. El nivel de intensidad de identidad se usa para distinguir entre caracteres similares, como el carácter MATEMÁTICO NEGRITA PEQUEÑA A (U + 1D41A) y el carácter MATEMÁTICO ITALICO PEQUEÑO A (U + 1D44E).

Establecer el atributo Strength en un nivel superior ralentizará las comparaciones de cadenas de texto y aumentará la longitud de las claves de clasificación. Ejemplos:

  • UCA500R1_S1 intercalará "role" = "Role" = "rôle"
  • UCA500R1_S2 clasificará "role" = "Role" <"rôle"
  • UCA500R1_S3 clasificará "role" <"Role" <"rôle"

Esto funcionó para mí. Como puede ver, ..._ S2 ignora el caso, también.

Usando una versión estándar más nueva , debería verse así:

CREATE DATABASE yourDB USING COLLATE CLDR181_S1

Palabras clave de intercalación :
UCA400R1 = Estándar Unicode 4.0 = Versión 1.2 de CLDR
UCA500R1 = Unicode Standard 5.0 = CLDR versión 1.5.1
CLDR181 = Estándar Unicode 5.2 = Versión CLDR 1.8.1

Si su base de datos ya está creada, se supone que hay una forma de cambiar la configuración .

CALL SYSPROC.ADMIN_CMD( ''UPDATE DB CFG USING DB_COLLNAME UCA500R1_S1 '' );

Tengo problemas para ejecutar esto, pero por lo que sé, se supone que debe funcionar.

Fila de la tabla generada

Otras opciones son, por ejemplo, generar una fila en mayúscula :

CREATE TABLE t ( id INTEGER NOT NULL PRIMARY KEY, str VARCHAR(500), ucase_str VARCHAR(500) GENERATED ALWAYS AS ( UPPER(str) ) )@ INSERT INTO t(id, str) VALUES ( 1, ''Some String'' )@ SELECT * FROM t@ ID STR UCASE_STR ----------- ------------------------------------ ------------------------------------ 1 Some String SOME STRING 1 record(s) selected.