Существует несколько причин ошибки ORA-01745 («недопустимая ошибка имени переменной хоста / связывания») при использовании базы данных Oracle. Документация Oracle 9i об ошибках ORA-01500 — ORA-02098 содержит более подробную информацию о ORA-01745 . В нем говорится, что «причина» — это «двоеточие в переменной связывания или спецификация INTO, за которым следует неуместное имя, возможно, зарезервированное слово». В нем также говорится, что «Действие» означает «Изменить имя переменной и повторить операцию». В той же документации Oracle 12g , однако, нет описания «причины» или «действия» для ORA-01745, предположительно, потому что есть несколько причин и множество соответствующих действий, связанных с этим сообщением. В этом посте я остановлюсь на одной из, возможно, менее очевидных причин и соответствующих действий для этой причины.
Некоторые из распространенных причин для ORA-01745, на которых я НЕ буду фокусироваться в этом посте, включают использование зарезервированного имени базы данных Oracle ( зарезервированное слово ) в качестве идентификатора , посторонние или отсутствующие двоеточие или запятую , или попытки связать имена структур (а не переменные) для заполнителей .
В дополнение к только что перечисленным и вероятным в дополнение к другим потенциальным причинам ORA-01745, другая ситуация, которая может вызвать ошибку ORA-01745, использует слишком много ? заполнители в JDBC PreparedStatement с базой данных Oracle. Я продемонстрирую в этом посте, что число ? заполнители в PreparedStatement, которые вызывают это ORA-01745, являются 65536 ( 2 16 )
Ранее я писал в блоге об ошибке ORA-01795, которая возникает при попытке включить более 1000 значений в условие Oracle SQL IN . Существует несколько способов справиться с этим ограничением, и один из альтернативных подходов может заключаться в использовании нескольких OR для « OR » вместе более 1000 значений. Как правило, это будет реализовано с PreparedStatement и с ? заполнитель помещается в оператор SQL для каждого значения, которое OR . Этот PreparedStatement основе альтернативного подхода с использованием ? заполнители будут работать только до тех пор, пока количество объединяемых OR будет превышать 65536.
В приведенном ниже листинге кода показано, как можно сгенерировать SQL-запрос к схеме Oracle HR, чтобы упростить воспроизведение ошибки ORA-01745 при слишком большом количестве ошибок ? заполнители (полный список кодов доступен на GitHub ).
Создание подготовленного заявления с указанным количеством ? Заполнители
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
/** * Constructs a query using '?' for placeholders and using * as many of these as specified with the int parameter. * * @param numberPlaceholders Number of placeholders ('?') * to include in WHERE clause of constructed query. * @return SQL Query that has provided number of '?" placeholders. */private String buildQuery(final int numberPlaceholders){ final StringBuilder builder = new StringBuilder(); builder.append("SELECT region_id FROM countries WHERE "); for (int count=0; count < numberPlaceholders-1; count++) { builder.append("region_id = ? OR "); } builder.append("region_id = ?"); return builder.toString();} |
Следующий листинг кода демонстрирует построение PreparedStatement на основе запроса, созданного в последнем листинге кода, и установку его заполнителей с количеством последовательных целых чисел, которые соответствуют числу ? заполнители.
Конфигурирование PreparedStatement ‘s ? Заполнители
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/** * Execute the provided query and populate a PreparedStatement * wrapping this query with the number of integers provided * as the second method argument. * * @param query Query to be executed. * @param numberValues Number of placeholders to be set in the * instance of {@code PreparedStatement} used to execute the * provided query. */private void executeQuery(final String query, final int numberValues){ try (final Connection connection = getDatabaseConnection(); final PreparedStatement statement = connection.prepareStatement(query)) { for (int count = 0; count < numberValues; count++) { statement.setInt(count+1, count+1); } final ResultSet rs = statement.executeQuery(); while (rs.next()) { out.println("Region ID: " + rs.getLong(1)); } } catch (SQLException sqlException) { out.println("ERROR: Unable to execute query - " + sqlException); }} |
Следующий снимок экрана показывает ошибку ORA-01745, возникающую, когда число ? применяется заполнителей 65536.
Этот пример показывает, что существует максимальное количество ? заполнители, которые можно использовать в операторе Oracle SQL. К счастью, есть другие способы реализации этого типа функций, которые не имеют ограничения ORA-01475 65536 ? заполнители или предел 1000 IN элементов, который вызывает ошибку ORA-01795
| Опубликовано на Java Code Geeks с разрешения Дастина Маркса, партнера нашей программы JCG . См. Оригинальную статью здесь: Слишком много заполнителей PreparedStatement в Oracle JDBC
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |
