Возникла такая странная проблема. Выполняю на Oracle Database какой-нибудь запрос с ORDER BY, например:
1 2 3 |
SELECT ID, NAME FROM DICT1 ORDER BY NAME; |
Если выполнять его через SQL Developer, то всё выполняется корректно. Но при выполнении этого запроса через JDBC из клиента Java записи возвращаются в совершенно неправильном порядке.
После долгих рысканий по интернету нашёл причину проблемы. Она заключается в том, что JDBC берёт языковые настройки для сортировки из JVM. Проблема с неправильной сортировкой возникает при отличии языковых настроек в системе, на которой запускается Java-клиент, и установленных на другом компьютере в Oracle Database.
Узнать текущее значение языка для сортировки в Oracle можно с помощью SQL-команды:
1 |
SELECT parameter, value FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER IN ('NLS_LANGUAGE','NLS_SORT', 'NLS_COMP'); |
Для исправления проблемы есть два более менее нормальных способа.
Способ 1.
Создать триггер, который будет устанавливать свойства сортировки и языка для сессии:
1 2 3 4 5 6 7 8 9 |
CREATE OR REPLACE trigger set_nls_onlogon AFTER LOGON ON SCHEMA DECLARE BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_SORT=''BINARY'''; EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_COMP=''BINARY'''; EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_LANGUAGE=''AMERICAN'''; END set_nls_logon; |
Способ 2.
Драйвер JDBC берёт настройки для сессии из java.util.Locale, поэтому мы можем установить локаль по умолчанию для JVM:
1 |
Locale.setDefault(Locale.<your locale here>); |
Либо с помощью параметров JVM:
1 |
-Duser.language=<lang> -Duser.country=<2-char-ISO-country-code> |