Вопрос

Я пытаюсь использовать предложение LIKE в инструкции SQL для соответствия определенному шаблону в Oracle.

Я хотел бы сделать что-то как таковое:

LIKE '[A-Z][A-Z][1-4]%'

..но Я не могу использовать регулярное выражение, потому что это на Oracle9i (поддержка регулярных выражений появилась в 10g).

Я пытаюсь сопоставить что-то, перед чем есть два символа, затем число от 1 до 4 и что-то еще за этим.Я пытался это сделать, но, похоже, это не сработало.Единственный способ, которым я смог заставить это работать, - это сделать:

WHERE ...
LIKE '%1__' OR 
LIKE '%2__' OR 
LIKE '%3__' OR 
LIKE '%4__'

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

Мы были бы очень признательны за любую помощь, которую вы могли бы оказать.

Это было полезно?

Решение

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

SELECT c1
FROM   t1
WHERE  substr(c1,1,1) IN ('A','B','C','D',
                          'E','F','G','H',
                          'I','J','K','L',
                          'M','N','O','P',
                          'Q','R','S','T',
                          'U','V','W','X',
                          'Y','Z')
       AND substr(c1,2,1) IN ('A','B','C','D',
                              'E','F','G','H',
                              'I','J','K','L',
                              'M','N','O','P',
                              'Q','R','S','T',
                              'U','V','W','X',
                              'Y','Z')
       AND substr(c1,3,1) IN ('1','2','3','4')
/

Если вы хотите также сопоставить нижние буквы, то примените функцию upper() к 2 первым substr():например.где верхний (substr(c1,1,1)) в ...

Производительность

Я протестировал производительность запроса с regexp_like и без.Как вы можете видеть, запрос без функции regexp_like был на 100% быстрее.(Примечание.Оба запроса выполнили мягкий синтаксический анализ)

SQL> select count(*) from t1;                                                                                                                     

  COUNT(*)
----------
    458752

Elapsed: 00:00:00.02
SQL> set timing off;                                                                                                                                  
SQL> select count(*) from t1;                                                                                                                     

  COUNT(*)
----------
    458752

SQL> set timing on;                                                                                                                                   
SQL> select count(*) from t1 where regexp_like(c1, '[A-Z][A-Z][1-4].*');                                                                       

  COUNT(*)
----------
     65536

Elapsed: 00:00:02.66
SELECT count(*)
FROM   t1
WHERE  substr(c1,1,1) IN ('A','B','C','D',
                          'E','F','G','H',
                          'I','J','K','L',
                          'M','N','O','P',
                          'Q','R','S','T',
                          'U','V','W','X',
                          'Y','Z')
       AND substr(c1,2,1) IN ('A','B','C','D',
                              'E','F','G','H',
                              'I','J','K','L',
                              'M','N','O','P',
                              'Q','R','S','T',
                              'U','V','W','X',
                              'Y','Z')
       AND substr(c1,3,1) IN ('1','2','3','4')
 18  /                                                                                                                                                

  COUNT(*)
----------
     65536

Elapsed: 00:00:01.15
SQL> 

Второй Способ

Получаем значения ascii A, Z, 1 и 4

SQL> select ascii('A') from dual;                                                                                                                     

ASCII('A')
----------
        65


SQL> select ascii('Z') from dual;                                                                                                                     

ASCII('Z')
----------
        90


SQL> select ascii('1') from dual;                                                                                                                     

ASCII('1')
----------
        49

SQL> select ascii('4') from dual;                                                                                                                     

ASCII('4')
----------
        52

Теперь вы можете написать свое заявление намного короче

SELECT count(* )
FROM   t1
WHERE  ascii(substr(c1,1,1)) BETWEEN 65 AND 90
       AND ascii(substr(c1,2,1)) BETWEEN 65 AND 90
       AND ascii(substr(c1,3,1)) BETWEEN 49 AND 52
/

Другие советы

Неуклюжий, но, возможно:

select *
  from <your_table>
 where TRANSLATE(SUBSTR(<blah>,1,3),'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234',
                                    'AAAAAAAAAAAAAAAAAAAAAAAAAA1111') = 'AA1';

может удовлетворить ваши потребности....

Редактировать:Включено предложение xlnt от @Hobo перевести подстроку, вместо того, чтобы брать подстроку переведенной строки...

Я рекомендую использовать ИНСТР:

INSTR(t.column, '1', 3, 1) > 0 OR 
INSTR(t.column, '2', 3, 1) > 0 OR
INSTR(t.column, '3', 3, 1) > 0 OR
INSTR(t.column, '4', 3, 1) > 0

Проблема с использованием подстановочного знака в LIKE заключается в том, что нет контроля над тем, где в значении столбца появится значение 1/2/3/4 / etc - это может быть в конце.

DCookie прав - этот ответ не делает имейте способ справиться, есть ли в этом месте числовые данные.Но это все равно лучше, чем использовать LIKE с подстановочными знаками.

Полная дикая карта, но я все равно предложу это.

Установлен ли в вашей базе данных 9i веб-инструментарий PL / SQL?Причина запроса заключается в том, что один из наших клиентов указал на ограниченную поддержку регулярных выражений при использовании одного из прилагаемых пакетов.

Пакет называется owa_pattern, и единственная ссылка 9i, которую я смог найти, это один

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

Если вы действительно хотите использовать reg exps, вы можете разработать хранимый на Java процесс и сопутствующую оболочку pl / sql.(Я предполагаю, что версия Java, поддерживаемая в Oracle 9, поддерживает reg exps, я не уверен на 100%).Вы можете вызвать этот хранимый в Java процесс через оболочку pl / sql в вашем операторе select.

Но проще и быстрее:

SELECT c1
FROM   t1
WHERE  substr(c1,1,1) between  'A' and 'Z'
AND    substr(c1,2,1) between  'A' and 'Z'
AND    substr(c1,3,1) IN ('1','2','3','4')

Вариант решения цюрихшнацлеца без использования функции ascci.

Я думаю, вы хотите использовать REGEXP_LIKE вместо like .

ГДЕ REGEXP_LIKE(имя_поля, '[A-Z]{2}[1-4]?.+',' i');

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top