Получение исключения ORA-00942: таблица или представление не существует - при вставке в существующую таблицу
Я получаю ниже исключения, при попытке вставить пакет строк в существующую таблицу
ORA-00942: таблица или представление не существует
Я могу подтвердить, что таблица существует в БД, и я могу вставить данные в эту таблицу с помощью oracle sql developer. Но когда я пытаюсь вставить строки с использованием подготовленного состояния в java, в его метательной таблице не существует ошибки.
Пожалуйста, найдите след стека ошибки ниже
java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1889)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout>>(OracleStatement.java:2709)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at quotecopy.DbConnection.insertIntoDestinationDb(DbConnection.java:591)
at quotecopy.QuoteCopier.main(QuoteCopier.java:72)
Кто-нибудь может подсказать причины этой ошибки?
Обновление: проблема решена
Не было проблем со свойствами соединения с базой данных или с именем таблицы или представления. Решение проблемы было очень странным. Один из столбцов, которые я пытался вставить, был типа Clob. Так как у меня было много проблем с обработкой данных clob в oracle db, я попробовал, заменив установщик clob временным установщиком строк и выполнив тот же код без проблем, и все строки были правильно вставлены!!!.
то есть. peparedstatement.setClob(columnIndex, clob)
был заменен на
peparedstatement.setString(columnIndex, "String")
Почему существует таблица ошибок или представление, ошибка выдает ошибку при вставке данных clob. Может ли кто-нибудь из вас объяснить, пожалуйста?
Большое спасибо за ваши ответы и комментарии.
9 ответов
Не было проблем со свойствами соединения с базой данных или с именем таблицы или представления. Решение проблемы было очень странным. Один из столбцов, которые я пытался вставить, был типа Clob. Так как у меня было много проблем с обработкой данных clob в oracle db, я попробовал, заменив установщик clob временным установщиком строк и выполнив тот же код без проблем, и все строки были правильно вставлены!!!.
то есть. peparedstatement.setClob(columnIndex, clob)
был заменен на
peparedstatement.setString(columnIndex, "String")
Oracle также сообщит об этой ошибке, если таблица существует, но у вас нет никаких прав на нее. Так что, если вы уверены, что таблица есть, проверьте гранты.
Кажется, есть некоторая проблема с setCLOB(), которая вызывает ORA-00942 при некоторых обстоятельствах, когда целевая таблица существует и имеет правильные привилегии. У меня возникла именно эта проблема, я могу заставить ORA-00942 уйти, просто не привязав CLOB к той же таблице.
Я пробовал setClob() с java.sql.Clob и setCLOB() с oracle.jdbc.CLOB, но с тем же результатом.
Как вы говорите, если вы связываете как строку, проблема исчезает - но это ограничивает размер ваших данных до 4k.
Из тестирования это, кажется, срабатывает, когда транзакция открыта в сеансе до привязки CLOB. Я вернусь, когда решу это... проверю поддержку Oracle.
Я нашел, как решить эту проблему, не используя метод setString () JDBC, который ограничивает данные 4K.
Что вам нужно сделать, это использовать подготовленный State.tatement.setClob(int parameterIndex, Reader Reader). По крайней мере, это то, что у меня сработало. Кажется, что драйверы Oracle преобразуют данные в символьный поток для вставки. Или что-то конкретное, вызывающее ошибку.
Использование CharacterStream, кажется, работает для меня. Я читаю таблицы из одного БД и пишу в другой, используя jdbc. И я получаю таблицу не найдена ошибка, как это упоминалось выше. Так вот как я решил проблему:
case Types.CLOB: //Using a switch statement for all columns, this is for CLOB columns
Clob clobData = resultSet.getClob(columnIndex); // The source db
if (clobData != null) {
preparedStatement.setClob(columnIndex, clobData.getCharacterStream());
} else {
preparedStatement.setClob(columnIndex, clobData);
}
clobData = null;
return;
Все хорошо сейчас.
@unbeli прав. Отсутствие соответствующих грантов на столе приведет к этой ошибке. Для чего это стоит, я недавно испытал это. У меня возникла именно та проблема, которую вы описали, я мог выполнить оператор вставки через sql developer, но при использовании hibernate произошел сбой. Я наконец понял, что мой код делает больше, чем просто вставка. Вставка в другие таблицы, которые не имели соответствующих грантов. Регулирование привилегий гранта решило это для меня.
Примечание: не имейте репутацию, чтобы комментировать, иначе это мог быть комментарий.
Мы столкнулись с этой проблемой в столбце BLOB. На случай, если кто-то еще столкнется с этим вопросом при обнаружении этой ошибки, вот как мы решили эту проблему:
Мы начали с этого:
preparedStatement.setBlob(parameterIndex, resultSet.getBlob(columnName)); break;
Мы решили проблему, изменив эту строку следующим образом:
java.sql.Blob blob = resultSet.getBlob(columnName);
if (blob != null) {
java.io.InputStream blobData = blob.getBinaryStream();
preparedStatement.setBinaryStream(parameterIndex, blobData);
} else {
preparedStatement.setBinaryStream(parameterIndex, null);
}
Предоставляет ли ваш сценарий имя схемы или вы полагаетесь на пользователя, вошедшего в базу данных для выбора схемы по умолчанию?
Возможно, вы не называете схему и выполняете пакет с системным пользователем вместо пользователя схемы, что приводит к неверному контексту выполнения для сценария, который будет работать нормально, если выполняется пользователем, для которого целевая схема установлена как схема по умолчанию. Лучше всего включить имя схемы в операторы вставки:
INSERT INTO myschema.mytable (mycolums) VALUES ('myvalue')
обновление: вы пытаетесь связать имя таблицы в качестве связанного значения в подготовленном утверждении? Это не сработает.
Возможно ли, что вы делаете
INSERT
за
VARCHAR
но делая
INSERT
затем
UPDATE
за
CLOB
?
Если да, вам необходимо предоставить
UPDATE
разрешения на таблицу в дополнение к
INSERT
.
Меня устраивает:
Clob clob1;
while (rs.next()) {
rs.setString(1, rs.getString("FIELD_1"));
clob1 = rs.getClob("CLOB1");
if (clob1 != null) {
sta.setClob(2, clob1.getCharacterStream());
} else {
sta.setClob(2, clob1);
}
clob1 = null;
sta.setString(3, rs.getString("FIELD_3"));
}
Здесь я получил решение вопроса. Проблема на стеклянной рыбе, если вы ее используете. При создании имени JNDI убедитесь, что имя пула правильное, а имя пула - это имя созданного вами пула соединений.