【问题标题】:Accent and case insensitive collation in Oracle with LIKE带有 LIKE 的 Oracle 中的重音和不区分大小写的排序规则
【发布时间】:2009-10-15 14:02:53
【问题描述】:

我发现这个答案很有用: Accent and case insensitive COLLATE equivalent in Oracle,但我的问题是关于使用版本 9 Oracle db 进行 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);
  }
 }
}

我在谷歌上搜索没有任何成功,有人有任何解决方案吗?

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

【问题讨论】:

    标签: java database oracle sql-like case-insensitive


    【解决方案1】:

    一种方法是修改会话参数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
    

    【讨论】:

    • 感谢您的回答,有没有在不改变会话的情况下这样做?同一会话中的其他查询可能需要原始 NLS 设置。干杯。
    • @Ed:您可以在运行查询之前保存会话参数(从 nls_session_parameters 中选择 *),然后在查询之后将它们放回。
    • 我一直在对此进行测试,一切看起来都不错,但现在我被告知 NLS_SORT 和 NLS_COMP 解决方案仅在版本 10 r2 中受支持。我需要支持最低版本 9 的 Oracle 数据库。我可以执行不区分大小写和重音搜索的唯一方法是使用函数吗?
    • @Ed: NLS_SORT=linguistic 似乎是 10g 的功能。您仍然可以在 9i 中使用第二种方法(SQL 函数)。
    猜你喜欢
    • 2011-11-28
    • 2011-06-01
    • 2011-05-11
    • 2011-05-23
    • 2019-06-19
    • 2012-01-12
    • 2014-05-10
    • 1970-01-01
    相关资源
    最近更新 更多