2012-02-08 39 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