2009-10-15 17 views
5

Ta odpowiedź okazała się przydatna: Accent and case insensitive COLLATE equivalent in Oracle, ale moje pytanie dotyczy LIKE wyszukiwania w wersji 9 Oracle db.Sortowanie akcentujące i nie rozróżniające wielkości liter w Oracle z LIKE

Próbowałem kwerendy tak:

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

ale żadne wyniki nie wrócił.

stworzyłem mały plik Java Test:

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

nie miałem żadnych sukcesów googling, ktoś ma jakieś rozwiązanie?

Chcę przeprowadzić wyszukiwanie części nazwy i zwracać wyniki, które są dopasowane przy użyciu niewrażliwości na wielkość liter i akcentów.

Odpowiedz

9

jedna metoda byłoby zmodyfikować parametry sesji NLS_SORT i 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 

Jak pokazano na another SO, nie można użyć operatora LIKE z NLSSORT (to dlatego, NLSSORT returns a string of bytes które zostaną wykorzystane do sortowania, i LIKE działa tylko z łańcuchami znaków)

Aktualizacja: Podczas ustawiania parametrów NLS byłby mój pierwszy wybór, można również użyć wbudowanych funkcji, aby osiągnąć ten sam wynik t. Kilka przykładów:

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

Dzięki za odpowiedź, czy jest tak czy inaczej, nie zmieniając sesji? Inne zapytania w tej samej sesji mogą wymagać oryginalnych ustawień NLS. Twoje zdrowie. –

+0

@Ed: można zapisać parametry sesji przed uruchomieniem zapytania (wybierz * z nls_session_parameters), a następnie odkładając je po zapytaniu. –

+0

Testowałem to i wszystko wyglądało dobrze, ale teraz powiedziano mi, że rozwiązania NLS_SORT i NLS_COMP są obsługiwane tylko w wersji 10 r2. Muszę obsługiwać bazy danych Oracle w wersji min 9. Czy jedynym sposobem, w jaki mogę wykonać wyszukiwanie bez użycia znaków i akcentów, jest używanie funkcji? –