escape-символ между и оператором

Например, у меня есть таблица с именем test_table и столбец с именем column_A, который имеет значения:

A_1
A_2
A_3
A1
A2
A3
B_1
B_2
B_3
B1
B2
B3

Если я хочу выбрать все данные с A_ в начале, я могу использовать escape \, например:

select * from test_table where column_A like 'A\_*' escape '\';

так что _ не обрабатывается как односимвольный подстановочный знак. я могу получить A_1, A_2 и A_3.

Что делать, если я хочу использовать это в Между и оператором? как

select * from test_table where column_A between 'A_\*' and 'B_\*' 

Я попробовал вышеуказанный, он не ускользнул от _. если я добавлю escape сразу после условия вроде

select * from test_table 
 where column_A between 'A_\*' escape '\' and 'B_\*' escape '\'

or

select * from test_table 
 where column_A between 'A_\*' and 'B_\*' escape '\'

у меня синтаксическая ошибка.


person ArdenZhao    schedule 08.02.2012    source источник
comment
На самом деле нет смысла экранировать символы с помощью операторов сравнения, потому что эти операторы не рассматривают ЛЮБОЙ символ как особый. Подстановочные знаки с BETWEEN не используются, поэтому их не нужно экранировать. Что вы ожидаете от своего запроса, действительно не ясно.   -  person Vincent Malgrat    schedule 08.02.2012


Ответы (2)


BETWEEN, похоже, не разрешить экранирование подстановочных знаков с использованием этого синтаксиса; Я предполагаю, что вы получаете ORA-00933: команда SQL не завершена должным образом? (Всегда полезно на самом деле указать ошибку, которую вы видите). Тем не менее, он допускает альтернативный синтаксис:

select * from test_table
where column_A between 'A[_]%' and 'B[_]%';

Изменить. На самом деле, хотя синтаксис разрешен, он ничего не делает; BETWEEN в любом случае не рассматривает _ как подстановочный знак, хотя рассматривает % как единое целое.

Изменить 2. Как заметил @Allan, на самом деле % не рассматривается как подстановочный знак, это просто порядок работы символов.

Я не уверен, что вы действительно этого хотите, так как это даст вам A_1, A_2, A_3, B1, B2, B3 (по крайней мере, с моими параметрами NLS).

Если вы действительно хотите A_1, A_2, A_3, B_1, B_2, B_3, вы можете использовать REGEXP_LIKE < / a> вместо этого что-то вроде:

select * from test_table
where regexp_like(column_A, '^([AB])_';

(хотя я с радостью предоставлю помощь другим, чтобы найти лучший способ построить это).

person Alex Poole    schedule 08.02.2012
comment
Я не думаю, что between на самом деле рассматривает% как подстановочный знак. Я считаю, что он возвращает эти результаты, потому что числовые значения падают после знака процента в таблице символов. Это также объясняет, почему значения B_1 и т. Д. Не возвращаются. - person Allan; 09.02.2012
comment
@Allan - да, конечно. Ооо. Я думал, что он должен рассматривать его как подстановочный знак, потому что он все еще находил записи, но вы правы, потому что % имеет более низкое значение ASCII (или unicode), чем буквенно-цифровые. Спасибо что подметил это. - person Alex Poole; 09.02.2012

Вы не можете экранировать символы с помощью операторов сравнения, потому что в этих операторах нет подстановочных знаков. Я не думаю, что BETWEEN - подходящий оператор для этой задачи.

Кажется, вам нужны все строки, которые начинаются с буквы между A и B и сопровождаются _. Я бы посоветовал вам взглянуть на _3 _, который более гибок, чем оператор LIKE. Например, вы можете написать:

SQL> WITH test_table AS (
  2     SELECT 'A_1' column_A FROM dual
  3     UNION ALL SELECT 'A_2' FROM dual
  4     UNION ALL SELECT 'A_3' FROM dual
  5     UNION ALL SELECT 'A1' FROM dual
  6     UNION ALL SELECT 'A2' FROM dual
  7     UNION ALL SELECT 'A3' FROM dual
  8     UNION ALL SELECT 'B_1' FROM dual
  9     UNION ALL SELECT 'B_2' FROM dual
 10     UNION ALL SELECT 'B_3' FROM dual
 11     UNION ALL SELECT 'B1' FROM dual
 12     UNION ALL SELECT 'B2' FROM dual
 13     UNION ALL SELECT 'B3' FROM dual
 14  )
 15  SELECT * FROM test_table
 16   WHERE regexp_like (column_A, '^[A-B]_.*');

COLUMN_A
--------
A_1
A_2
A_3
B_1
B_2
B_3
person Vincent Malgrat    schedule 08.02.2012