экранирование между оператором и оператором - PullRequest
0 голосов
/ 08 февраля 2012

Например, у меня есть имя таблицы 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.

Как мне поступить, если я хочу использовать это в Between и operator? как

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 '\'

или

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

Я получил синтаксическую ошибку.

Ответы [ 2 ]

2 голосов
/ 08 февраля 2012

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 вместо этого, например:

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

(хотя я с удовольствием расскажу другим о том, как лучше это построить).

2 голосов
/ 08 февраля 2012

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

Вы, похоже, хотите, чтобы все строки начинались с буквы между A и B и сопровождались _.Я бы посоветовал вам взглянуть на regexp_like, который является более гибким, чем оператор 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
...