2012-02-08 43 views
0

例如,我有一個表名TEST_TABLE並有一個名爲column_A列具有值:如果我要選擇所有的數據逃避通配符之間和運營商

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

具有A_爲開端,我可以使用逃脫\像:

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

我想上面的一個,它沒有逃過_。如果我的條件後添加逃逸右像

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

我得到一個語法錯誤。

+1

使用比較運算符轉義字符沒有意義,因爲這些運算符不會將任何字符視爲特殊字符。 「BETWEEN」沒有通配符,因此不需要轉義它們。你希望你的查詢返回什麼,這真的不清楚。 – 2012-02-08 09:08:34

回答

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代替,一樣的東西:

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

(雖然我會高興地聽從他人的最佳方式來構建)。

+1

我不認爲'between'實際上是把%當作通配符。我相信它會返回這些結果,因爲數字值落在字符表中的百分號後面。這也解釋了爲什麼「B_1」等值不被返回。 – Allan 2012-02-09 17:04:43

+0

@Allan - 是的,當然是。 D'哦。我認爲它必須將它視爲通配符,因爲它仍然會找到記錄,但是你是對的,這是因爲'%'具有比字母數字低的ASCII(或unicode)值。感謝您指出了這一點。 – 2012-02-09 17:18:16

2

您不能使用比較運算符轉義字符,因爲這些運算符沒有通配符。我不認爲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