DB2 чувствительность к регистру - PullRequest
4 голосов
/ 11 октября 2010

Мне очень трудно делать запросы к DB2 (AS / 400) без учета регистра.

Например:

SELECT *
FROM NameTable
WHERE LastName = 'smith'

Не вернет результатов, но следующее возвращает 1000 результатов:

SELECT *
FROM NameTable
WHERE LastName = 'Smith'

Я читал о помещении SortSequence / SortType вваша строка подключения, но вам не повезло ... кто-нибудь испытал это?

Редактировать:

Вот хранимая процедура:

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 ;

Ответы [ 4 ]

6 голосов
/ 11 октября 2010

Почему бы не сделать это:

WHERE lower(LastName) = 'smith'

Если вы беспокоитесь о производительности (т. Е. В запросе не используется индекс), имейте в виду, что в DB2 есть индексы функций, которые вы можете прочитать о здесь . По сути, вы можете создать индекс для upper(LastName).

EDIT Чтобы сделать технику отладки, которую я обсуждал в комментариях, вы могли бы сделать что-то вроде этого:

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

Затем в вашем SP вы можете вставить сообщения в эту таблицу для целей отладки:

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

Затем, после запуска SP, вы можете выбрать из этой таблицы журнала, чтобы увидеть, что произошло.

3 голосов
/ 02 апреля 2014

Если вы хотите, чтобы в вашей процедуре учитывался регистр символов, попробуйте использовать в нем следующую опцию:

SET OPTION SRTSEQ = *LANGIDSHR ;

Вы также должны создать индекс для поддержки его производительности. Создайте индекс, если у вас есть *LANGIDSHR в качестве атрибута соединения, и индекс общего веса должен быть доступен для последующих заданий. (Существуют различные способы получения соответствующих настроек.)

*LANGIDSHR относится к идентификатору языка для ваших рабочих мест. Символам в наборе символов, которые могут рассматриваться как «равные», таким как «A» и «a» или «ü» и «u», следует присвоить одинаковые веса (разделить) и выбирать их вместе.

0 голосов
/ 08 ноября 2017

См .: https://stackoverflow.com/a/47181640/5507619

Настройка базы данных

Существует настройка конфигурации базы данных, которую вы можете установить на создание базы данных . Однако он основан на Unicode.

CREATE DATABASE yourDB USING COLLATE UCA500R1_S1

Алгоритм сортировки Unicode по умолчанию реализован ключевым словом UCA500R1 без каких-либо атрибутов. Поскольку UCA по умолчанию не может одновременно охватывать последовательность сортировки всех языков, поддерживаемых Unicode, необязательные атрибуты могут быть заданы для настройки порядка UCA. Атрибуты разделяются символом подчеркивания (_). Ключевое слово UCA500R1 и любые атрибуты образуют имя сопоставления UCA.

Атрибут Strength определяет, будет ли учитываться ударение или регистр при сопоставлении или сравнении текстовых строк. В письменных системах без регистра или акцента атрибут Strength контролирует аналогичные важные функции. Возможные значения: первичное (1), вторичное (2), третичное (3), четвертичное (4) и тождество (I). Игнорировать:

  • Акцент и кейс, использовать первичный уровень прочности
  • только для случая, используйте дополнительный уровень прочности
  • ни акцент, ни падеж, используйте третичный уровень прочности

Практически все персонажи можно различить по первым трем уровням силы, поэтому в большинстве локалей атрибут силы по умолчанию установлен на третичном уровне. Однако если для атрибута Alternate (описанного ниже) задано смещение, то уровень четвертичной силы можно использовать для разрыва связей между символами пробела, знаками препинания и символами, которые в противном случае игнорировались бы. Уровень прочности идентификатора используется для различения похожих символов, таких как символ МАТЕМАТИЧЕСКИЙ ЖИРНЫЙ МАЛЫЙ А (U + 1D41A) и МАТЕМАТИЧЕСКИЙ ИТАЛИЧЕСКИЙ МАЛЕНЬКИЙ символ А (U + 1D44E).

Установка атрибута Strength на более высокий уровень замедлит сравнение текстовых строк и увеличит длину ключей сортировки. Примеры:

  • UCA500R1_S1 будет сопоставлять "role" = "Role" = "rôle"
  • UCA500R1_S2 будет сопоставлять "role" = "Role" <"rôle" </li>
  • UCA500R1_S3 будет сопоставлять "роль" <"Роль" <"роль" </li>

Это сработало для меня. Как видите, ..._ S2 тоже игнорирует регистр.

При использовании более новой стандартной версии она должна выглядеть следующим образом:

CREATE DATABASE yourDB USING COLLATE CLDR181_S1

Ключевые слова для сопоставления :
UCA400R1 = Unicode Standard 4.0 = CLDR версия 1.2
UCA500R1 = Unicode Standard 5.0 = CLDR версия 1.5.1
CLDR181 = Unicode Standard 5.2 = CLDR версия 1.8.1

Если ваша база данных уже создана, должен быть способ изменить настройку .

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

У меня есть проблемы с выполнением этого, но, насколько я знаю, это должно сработать.

Строка сгенерированной таблицы

Другие варианты, например, генерация строки в верхнем регистре :

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.
0 голосов
/ 11 октября 2010

Я сделал что-то подобное, когда хотел поиск без учета регистра. Я использовал UPPER(mtfield) = 'SEARCHSTRING'. Я знаю, что это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...