2009-10-15 5 views
5

J'ai trouvé cette réponse utile: Accent and case insensitive COLLATE equivalent in Oracle, mais ma question concerne LIKE recherche avec une version 9 Oracle db.Accent et le classement insensible à la casse dans Oracle avec LIKE

J'ai essayé une requête comme ceci:

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

mais aucun résultat ne jamais retourné.

J'ai créé un petit fichier Java à tester:

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); 
    } 
} 
} 

Je n'ai pas eu de succès googler, quelqu'un a des solutions?

Je souhaite effectuer une recherche sur une partie d'un nom et renvoyer des résultats correspondant à l'insensibilité à la casse et à l'accentuation.

Répondre

9

une méthode serait de modifier vos paramètres de session NLS_SORT et NLS_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 

Comme le montre another SO, vous ne pouvez pas utiliser l'opérateur LIKE avec NLSSORT (c'est parce que, NLSSORT returns a string of bytes qui sera utilisé pour le tri, et LIKE fonctionne uniquement avec les chaînes de caractères)

Mise à jour: Bien que la définition des paramètres NLS soit mon premier choix, vous pouvez également utiliser les fonctions intégrées pour obtenir le même résultat t. Un couple d'exemples:

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

Merci pour la réponse, est-il de toute façon de le faire sans altérer la session? D'autres requêtes dans la même session peuvent nécessiter les paramètres NLS d'origine. À votre santé. –

+0

@Ed: vous pouvez sauvegarder les paramètres de la session avant d'exécuter la requête (sélectionnez * from nls_session_parameters) puis les remettre après la requête. –

+0

Je l'ai testé et tout a l'air bien, mais on me dit maintenant que la solution NLS_SORT et NLS_COMP est seulement pris en charge dans la version 10 r2. J'ai besoin de soutenir les bases de données Oracle avec la version min 9. Est-ce que la seule façon que je peux effectuer le cas et la recherche insensible à l'accent utilise des fonctions? –

Questions connexes