2009-10-15 6 views
5

Ho trovato questa risposta utile: Accent and case insensitive COLLATE equivalent in Oracle, ma la mia domanda riguarda la ricerca LIKE con una versione 9 Oracle db.Confronto accento e maiuscolo/minuscolo in Oracle con LIKE

ho cercato una query come questa:

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

ma i risultati non sono mai tornato.

ho creato un file Java poco a prova:

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

non ho avuto alcun successo googling, qualcuno ha qualche soluzione?

Desidero eseguire una ricerca su parte di un nome e restituire risultati corrispondenti a caso e insensibilità all'accento.

risposta

9

un metodo sarebbe quello di modificare i parametri di sessione NLS_SORT e 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 

Come mostrato nella another SO, non è possibile utilizzare l'operatore LIKE con NLSSORT (questo è perché, NLSSORT returns a string of bytes che verrà utilizzato per l'ordinamento, e LIKE funziona solo con le stringhe charater)

Aggiornamento: Mentre impostare i parametri NLS sarebbe la mia prima scelta, potresti anche utilizzare le funzioni incorporate per ottenere lo stesso risultato t. Un paio di esempi:

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

Grazie per la risposta, c'è comunque di farlo senza alterare la sessione? Altre query nella stessa sessione potrebbero richiedere le impostazioni NLS originali. Saluti. –

+0

@Ed: è possibile salvare i parametri di sessione prima di eseguire la query (selezionare * da nls_session_parameters), quindi reinserirli dopo la query. –

+0

L'ho provato e tutto sembra a posto, ma ora mi viene comunicato che la soluzione NLS_SORT e NLS_COMP è supportata solo nella versione 10 r2. Devo supportare i database Oracle con la versione min 9. L'unico modo in cui posso eseguire il caso e la ricerca con accento insensibile sta usando le funzioni? –