Вопрос-ответ

Where's my invalid character (ORA-00911)

Где мой недопустимый символ (ORA-00911)

Я пытаюсь вставить CLOBs в базу данных (см. Связанный вопрос). Я не совсем могу понять, что не так. У меня есть список примерно из 85 блоков, которые я хочу вставить в таблицу. Даже при вставке только первого блока я получаюORA-00911: invalid character. Я не могу понять, как извлечь инструкцию из PreparedStatement перед ее выполнением, поэтому я не могу быть на 100% уверен, что это правильно, но если я все понял правильно, то это должно выглядеть точно так:

insert all
into domo_queries values ('select
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = ''CHQ PeopleSoft FS'''
)
select * from dual;

В конечном счете, в этом insert all операторе было бы много into символов, поэтому я просто не выполняю обычный insert оператор. Я не вижу там недопустимого символа, а вы? (О, и этот код выше работает нормально, когда я запускаю его в своем инструменте разработчика sql.) И я, если я удалю точку с запятой в PreparedStatement, это выдаст ORA-00933: SQL command not properly ended ошибку.

В любом случае, вот мой код для выполнения запроса (и значения переменных для примера выше).

public ResultSet executeQuery(String connection, String query, QueryParameter... params) throws DataException, SQLException {
// query at this point = "insert all
//into domo_queries values (?)
//select * from dual;"
Connection conn = ConnectionPool.getInstance().get(connection);
PreparedStatement pstmt = conn.prepareStatement(query);
for (int i = 1; i <= params.length; i++) {
QueryParameter param = params[i - 1];
switch (param.getType()) { //The type in the example is QueryParameter.CLOB
case QueryParameter.CLOB:
Clob clob = CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_SESSION);
clob.setString(i, "'" + param.getValue() + "'");
//the value of param.getValue() at this point is:
/*
* select
* substr(to_char(max_data),1,4) as year,
* substr(to_char(max_data),5,6) as month,
* max_data
* from dss_fin_user.acq_dashboard_src_load_success
* where source = ''CHQ PeopleSoft FS''
*/

pstmt.setClob(i, clob);
break;
case QueryParameter.STRING:
pstmt.setString(i, "'" + param.getValue() + "'");
break;
}
}
ResultSet rs = pstmt.executeQuery(); //Obviously, this is where the error is thrown
conn.commit();
ConnectionPool.getInstance().release(conn);
return rs;
}

Есть ли что-то, чего мне просто не хватает?

Переведено автоматически
Ответ 1

Если вы используете строковый литерал точно так, как вы нам показали, проблема заключается в ; символе в конце. Вы можете не включать его в строку запроса при вызовах JDBC.

Поскольку вы вставляете только одну строку, обычный INSERT должен быть в порядке вещей даже при вставке нескольких строк. Использование пакетного оператора, вероятно, в любом случае более эффективно. Нет необходимости в INSERT ALL. Кроме того, вам не нужен временный clob и все такое. Вы можете упростить свой метод до чего-то вроде этого (при условии, что я правильно определил параметры):

String query1 = "select substr(to_char(max_data),1,4) as year, " + 
"substr(to_char(max_data),5,6) as month, max_data " +
"from dss_fin_user.acq_dashboard_src_load_success " +
"where source = 'CHQ PeopleSoft FS'";

String query2 = ".....";

String sql = "insert into domo_queries (clob_column) values (?)";
PreparedStatement pstmt = con.prepareStatement(sql);
StringReader reader = new StringReader(query1);
pstmt.setCharacterStream(1, reader, query1.length());
pstmt.addBatch();

reader = new StringReader(query2);
pstmt.setCharacterStream(1, reader, query2.length());
pstmt.addBatch();

pstmt.executeBatch();
con.commit();
Ответ 2

Насколько я понимаю, вы не могли бы попробовать использовать оператор 'q' для строкового литерала

что-то вроде

insert all
into domo_queries values (q'[select
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = 'CHQ PeopleSoft FS']')
select * from dual;

Обратите внимание, что одинарные кавычки вашего предиката не экранированы, и строка находится между q'[...]'.

Ответ 3

Одной из причин может быть наличие в имени любого столбца таблицы символа подчеркивания (_) . JDBC считает это недопустимыми символами. Переименуйте столбец командой ALTER и измените в своем коде SQL , это исправит .

Ответ 4

Oracle предоставляет некоторое объяснение для ORA-00911. Вы можете получить это объяснение после выполнения SQL-запроса в Oracle SQL Developer.


ORA-00911. 00000 - "недопустимый символ" * Причина: идентификаторы не могут начинаться ни с какого символа ASCII, кроме букв и цифр. $ # _ также допускаются после первого символа. Идентификаторы, заключенные в двойные кавычки, могут содержать любой символ, отличный от двойной кавычки. Альтернативные кавычки (q'# ... #') не могут использовать пробелы, табуляцию или возврат каретки в качестве разделителей. Для всех других контекстов обратитесь к Справочному руководству по языку SQL


Но в вашем случае это, кажется, символ double

java jdbc