2009-10-15 52 views
5

我发现这个答案有用: Accent and case insensitive COLLATE equivalent in Oracle,但是我的问题是关于LIKE使用版本9的Oracle数据库进行搜索。在Oracle中使用LIKE对口音和大小写敏感的排序规则

我已经尝试了这样的查询:

SELECT column_name 
FROM table_name 
WHERE NLSSORT(column_name, 'NLS_SORT = Latin_AI') 
LIKE NLSSORT('%somethingInDB%', 'NLS_SORT = Latin_AI') 

但以往任何时候都没有返回结果。

我创建了一个小的Java文件来测试:

import org.apache.commons.dbcp.BasicDataSource; 
import java.sql.Connection; 
import java.sql.SQLException; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 

public class DbCollationTest 
{ 
public static void main(String[] args) throws SQLException 
{ 
    BasicDataSource dataSource = new BasicDataSource(); 
    dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); 
    dataSource.setUrl("url"); 
    dataSource.setUsername("usr"); 
    dataSource.setPassword("pass"); 

    Connection conn = null; 
    PreparedStatement createStatement = null; 
    PreparedStatement populateStatement = null; 
    PreparedStatement queryStatement = null; 
    PreparedStatement deleteStatement = null; 
    ResultSet rs = null; 

    try 
    { 
    conn = dataSource.getConnection(); 

    createStatement = conn.prepareStatement("CREATE TABLE CollationTestTable (Name varchar(255))"); 
    createStatement.execute(); 

    String[] names = { "pepe", "pépé", "PEPE", "MEME", "mémé", "meme" }; 
    int i = 1; 

    for (String name : names) 
    { 
    populateStatement = conn.prepareStatement("INSERT INTO CollationTestTable VALUES (?)"); 
    populateStatement.setString(1, name); 
    populateStatement.execute(); 
    } 

    queryStatement = conn.prepareStatement("SELECT Name FROM CollationTestTable WHERE NLSSORT(NAME, 'NLS_SORT = Latin_AI') LIKE NLSSORT('%pe%', 'NLS_SORT = Latin_AI')"); 
    rs = queryStatement.executeQuery(); 

    while (rs.next()) 
    { 
    System.out.println(rs.getString(1)); 
    } 

    deleteStatement = conn.prepareStatement("DROP TABLE CollationTestTable"); 
    deleteStatement.execute(); 
    } 
    finally 
    { 
    //DBTools.tidyUp(conn, null, rs); 
    //DBTools.tidyUp(createStatement); 
    //DBTools.tidyUp(populateStatement); 
    //DBTools.tidyUp(queryStatement); 
    //DBTools.tidyUp(deleteStatement); 
    } 
} 
} 

我没有任何成功的谷歌搜索,任何人有什么办法呢?

我想对部分名称执行搜索并返回使用大小写和不区分大小写的匹配结果。

回答

9

一个方法是修改会话参数NLS_SORTNLS_COMP

SQL> SELECT Name FROM CollationTestTable WHERE NAME LIKE '%pe%'; 

NAME 
-------------------------------------------------------------------------------- 
pepe 

SQL> alter session set nls_sort=Latin_AI; 

Session altered 

SQL> alter session set nls_comp=linguistic; 

Session altered 

SQL> SELECT Name FROM CollationTestTable WHERE NAME LIKE '%pe%'; 

NAME 
-------------------------------------------------------------------------------- 
pepe 
pépé 
PEPE 

another SO所示,您不能使用LIKE运算符NLSSORT(这是因为,NLSSORT returns a string of bytes将被用于排序,和LIKE只能和字符串一起使用)

更新:虽然设置NLS参数是我的第一选择,但您也可以使用内置函数来实现相同的结果吨。几个例子:

SQL> SELECT Name 
    2 FROM CollationTestTable 
    3 WHERE upper(convert(NAME, 'US7ASCII')) 
    4   LIKE upper(convert('%pe%', 'US7ASCII')); 

NAME 
-------------------------------------------------------------------------------- 
pepe 
pépé 
PEPE 

SQL> SELECT Name 
    2 FROM CollationTestTable 
    3 WHERE upper(translate(NAME, 'àâéèêìîòôùûÿ', 'aaeeeiioouuy')) 
    4   LIKE upper(translate('%pe%', 'àâéèêìîòôùûÿ', 'aaeeeiioouuy')); 

NAME 
----------------------------------- 
pepe 
pépé 
PEPE 
+0

感谢您的答案,有没有做到这一点,而不改变会议?同一会话中的其他查询可能需要原始NLS设置。干杯。 –

+0

@Ed:您可以在运行查询之前保存会话参数(select * from nls_session_parameters),然后将其放回查询之后。 –

+0

我一直在测试这个,所有的看起来不错,但现在我告诉NLS_SORT和NLS_COMP解决方案只在版本10 r2中受支持。我需要使用最低版本9来支持Oracle数据库。我可以执行大小写不区分重音搜索的唯一方法是使用函数吗? –