Oracle - выберите, где поле имеет символы нижнего регистра

У меня есть таблица пользователей в базе данных Oracle 9.2.0.6. Два поля имеют тип varchar — last_name и first_name.

Когда строки вставляются в эту таблицу, поля имени и фамилии должны быть в верхнем регистре, но каким-то образом некоторые значения в этих двух полях имеют смешанный регистр.

Я хочу запустить запрос, который покажет мне все строки в таблице, в которых есть имена или фамилии со строчными буквами.

Я искал в сети и нашел REGEXP_LIKE, но это должно быть для более новых версий оракула - у меня это не работает.

Еще я пытался перевести «abcde...z» в «$$$$$…$», а затем искать «$» в моем поле, но должен ли быть лучший способ?

Заранее спасибо!


person BrianH    schedule 25.11.2008    source источник


Ответы (6)


Как насчет этого:

select id, first, last from mytable
where first != upper(first) or last != upper(last);
person BQ.    schedule 25.11.2008

Я думаю, что SQL BQ и второй SQL Джастина будут работать, потому что в этом сценарии:

first_name        last_name
----------        ---------
bob               johnson
Bob               Johnson
BOB               JOHNSON

Я хочу, чтобы мой запрос возвращал первые 2 строки.

Я просто хочу убедиться, что это будет эффективный запрос — в моей таблице 500 миллионов строк.

Когда вы говорите upper(first_name) != first_name, всегда ли «first_name» относится к текущей строке, на которую смотрит оракул? Сначала я боялся использовать этот метод, потому что боялся, что в конечном итоге я присоединю эту таблицу к самой себе, но из-за того, что вы оба написали SQL, кажется, что проверка на равенство работает только на основе строки за строкой, что будет работать на меня.

person BrianH    schedule 25.11.2008
comment
Условие применяется построчно. Конечно, ваш запрос должен будет выполнить полное сканирование таблицы из 500 миллионов строк, чтобы обработать запрос, что будет медленным. Если это регулярное явление, может быть полезен функциональный индекс. - person Justin Cave; 25.11.2008
comment
Хорошая мысль, Джастин. Я просто собирался добавить предложение индекса на основе функций. Кроме того, если данные действительно должны быть в верхнем регистре, вы можете создать триггер для принудительной вставки. - person BQ.; 25.11.2008
comment
Брайан, не совсем уверен, что вы планируете делать, но обратите внимание, что вы также можете запустить update mytable set first_name=upper(first_name) and last_name=upper(last_name); чтобы нормализовать все ваши данные... вам не нужно извлекать их построчно и обновлять вне базы данных. - person BQ.; 25.11.2008
comment
Спасибо! Эти два столбца проиндексированы, поэтому запросы к ним выполняются довольно быстро, но мне также придется исследовать функциональный индекс. Это не будет регулярным явлением, мне это нужно для анализа, пока мы не исправим это. - person BrianH; 25.11.2008
comment
С обычным индексом запросы должны быть быстрыми только в том случае, если они выполняются для определенного регистра, хранящегося в индексе. См. мой комментарий по адресу stackoverflow.com/questions/291166/ для получения дополнительной информации о функциональном индексе. - person BQ.; 25.11.2008
comment
Если вы собираетесь запускать обновление, вам лучше включить предикаты для обновления только необходимых строк: ) != имя_имя - person David Aldridge; 25.11.2008
comment
@ Дэвид хорошая мысль. Опущено в моем комментарии выше из-за длины, но это поможет предотвратить некоторые ненужные операции ввода-вывода/блокировки. Тот же конечный результат с ним или без него. - person BQ.; 25.11.2008

Если вы ищете Oracle 10g или выше, вы можете использовать приведенный ниже пример. Учтите, что вам нужно найти строки, в которых любая буква в столбце является строчной.

Column1
.......
MISS
miss
MiSS

В приведенном выше примере, если вам нужно найти значения miss и MiSS, вы можете использовать приведенный ниже запрос.

SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[a-z]');
person Sarath KS    schedule 28.08.2016
comment
Хм, интересно, почему это не работает для меня на 12c. Запрос возвращает все три строки. Могут ли повлиять настройки NLS базы данных? - person Rubio; 13.03.2019

Попробуй это:

SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[a-z]','c'); => Miss, miss lower text
SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[A-Z]','c'); => Miss, MISS upper text
person Quyen ht    schedule 28.11.2017
comment
Рассмотрите возможность расширения вашего ответа. Пожалуйста, объясните, как этот код решает проблему. - person Tom Aranda; 28.11.2017

для SQL-сервера, где настройка сортировки БД нечувствительна к регистру, используйте следующее:

SELECT * FROM tbl_user WHERE LEFT(username,1) COLLATE Latin1_General_CS_AI <> UPPER(LEFT(username,1))
person Dave    schedule 01.12.2014

person    schedule
comment
Это не находит last_name с неправильным регистром и трижды попадает в таблицу. Почему это лучше, чем принятый ответ? - person Alex Poole; 01.08.2012