ORA-01461: может связывать значение LONG только для вставки в столбцы LONG. Происходит при запросе

Когда я пытаюсь запросить объекты, я получаю следующую ошибку:

ORA-01461: can bind a LONG value only for insert into a LONG column

Может ли кто-нибудь помочь мне в решении проблемы и решении проблемы?

Ответ 1

Хорошо, ну, так как вы не показывали никакого кода, я сделаю несколько предположений здесь.

Основываясь на ошибке ORA-1461, кажется, что вы указали тип данных LONG в выражении select? И вы пытаетесь привязать его к выходной переменной? Это правильно? Ошибка довольно проста. Вы можете привязать значение LONG для вставки в столбцы LONG.

Не уверен, что еще сказать. Ошибка довольно понятна.

В целом, неплохо отойти от LONG-типа данных к CLOB. CLOB намного лучше поддерживаются, и LONG-типы данных действительно существуют только для обратной совместимости.

Здесь список ограничений типа LONG

Надеюсь, что это поможет.

Ответ 2

Это также может случиться с столбцами varchar2. Это довольно воспроизводимо с помощью PreparedStatements через JDBC просто

  • создание таблицы с столбцом varchar2 (20 или произвольной длины) и
  • вставка в приведенную выше таблицу со строкой, содержащей более 20 символов

Так, как указано выше, это может быть неправильно с типами или превышением ширины столбца.

Также обратите внимание, что поскольку varchar2 допускает max 4k, реальный предел будет 2k для двухбайтовых символов

Надеюсь, что это поможет

Ответ 3

Эта ошибка возникает, когда вы пытаетесь использовать переменную varchar длиной более 4000 байтов в инструкции SQL. PL/SQL позволяет использовать varchars до 32767 байт, но предел для таблиц базы данных и языка SQL - 4000. Вы не можете использовать переменные PL/SQL, которые SQL не распознает в SQL-операторах; исключение, как поясняет сообщение, является прямой вставкой в ​​столбце длинного типа.

create table test (v varchar2(10), c clob);


declare
  shortStr varchar2(10) := '0123456789';
  longStr1 varchar2(10000) := shortStr;
  longStr2 varchar2(10000);
begin
  for i in 1 .. 10000
  loop
    longStr2 := longStr2 || 'X';
  end loop;

  -- The following results in ORA-01461
  insert into test(v, c) values(longStr2, longStr2);

  -- This is OK; the actual length matters, not the declared one
  insert into test(v, c) values(longStr1, longStr1);

  -- This works, too (a direct insert into a clob column)
  insert into test(v, c) values(shortStr, longStr2);

  -- ORA-01461 again: You can't use longStr2 in an SQL function!
  insert into test(v, c) values(shortStr, substr(longStr2, 1, 4000));
end;

Ответ 4

Колледж меня и я узнали следующее:

Когда мы используем драйвер Microsoft.NET Oracle для подключения к базе данных oracle (System.Data.OracleClient.OracleConnection)

И мы пытаемся вставить строку длиной от 2000 до 4000 символов в поле CLOB или NCLOB с использованием параметра базы данных

oraCommand.CommandText = "INSERT INTO MY_TABLE (NCLOB_COLUMN) VALUES (:PARAMETER1)";
// Add string-parameters with different lengths
// oraCommand.Parameters.Add("PARAMETER1", new string(' ', 1900)); // ok
oraCommand.Parameters.Add("PARAMETER1", new string(' ', 2500));  // Exception
//oraCommand.Parameters.Add("PARAMETER1", new string(' ', 4100)); // ok
oraCommand.ExecuteNonQuery();
  • любая строка длиной до 2000 символов не будет генерировать это исключение
  • любая строка длиной более 4000 символов не будет генерировать это исключение
  • только строки длиной от 2000 до 4000 символов будут вызывать это исключение

Мы открыли билет в microsoft для этой ошибки много лет назад, но она по-прежнему не исправлена.

Ответ 5

Я столкнулся с той же проблемой и разрешил ее, просто заменив VARCHAR на CLOB. Эта ссылка помогла мне.

Ответ 6

Приложения, использующие JDBC 10.1, получили ошибку (Doc ID 370438.1) и могут вызывать одно и то же исключение ORA-01461 при работе с базой символов UTF8, даже если вставленные символы меньше максимального размера столбца.

Рекомендуемое решение: - Используйте 10gR2 JDBC-драйверы или выше в этом случае.

НТН

Ответ 7

Kiran ответ - это, безусловно, ответ для моего случая.

В части кода я разделяю строку на 4000 строк char и пытаюсь поместить их в db.

Взрывается с этой ошибкой.

Причиной ошибки является использование символов utf, количество которых равно 2 байтам. Даже я обрезаю до 4000 символов в коде (например, String.Take(4000)), oracle считает 4001, когда строка содержит "ö" или любой другой неинтер (не ascii, если быть точным, которые представлены двумя или байтами в utf8).

Ответ 8

У меня была такая же проблема с базой данных Entity Framework во всех столбцах CLOB.

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

Ответ 9

В моем конкретном случае я пытался хранить файл с кодировкой Base64 в поле BLOB таблицы, используя Mybatis.

Итак, в моем xml у меня было:

<insert id="save..." parameterType="...DTO">
    <selectKey keyProperty="id" resultType="long" order="BEFORE">
        SELECT SEQ.nextVal FROM DUAL
    </selectKey>
    insert into MYTABLE(
        ID,
        ...,
        PDF
    ) values (
        #{id, jdbcType=VARCHAR},
        ...,
        #{tcPdf, jdbcType=BLOB},
    )
</insert>

и в моем DTO:

String getPdf(){
    return pdf;
}

Это приводит к угрозе Mybatis, как если бы это была последовательность String char и пыталась сохранить ее как Varchar. Поэтому мое решение было следующим:

В моем DTO:

Byte[] getPdf(){
    return pdf.getBytes();
}

И работал.

Я надеюсь, что это может помочь кому угодно.

Ответ 10

Я столкнулся с той же проблемой, используя Siebel REXPIMP (импорт реестра) при использовании последнего драйвера Instant Client. Чтобы устранить проблемы, вместо этого используйте Siebel вместо Data Direct. DLL SEOR823.DLL

Ответ 11

Добавление другого варианта использования, когда я нашел это. Я использовал приложение ADF Fusion, а используемый тип столбца был varchar2 (4000), который не смог разместить текст и, следовательно, эту ошибку.

Ответ 12

Я столкнулся с этим сообщением об ошибке при попытке вставить String в столбец XMLTYPE.

В частности, используя Java PreparedStatement следующим образом:

ps.setString('XML', document);

где XML здесь определяется как XMLTYPE.

Ответ 13

У меня есть решение для Java/JPA/eclipselink/oracle, когда вставьте длинную строку xml ( > 4000) в столбец XMLTYPE в Вставьте XML с более чем 4000 символами в Oracle Столбец XMLTYPE. Для ясности, включите то же содержимое здесь, если ссылка не работает

Вам нужно сначала преобразовать строку xml для более 4000 символов в тип SQLXML.

Окружающая среда: jpa 2.1.0, eclipselink 2.5.2, oracle db 11gr2

SQL:

CREATE TABLE "XMLTEST"
( "ID" NUMBER(10,0) NOT NULL ENABLE, 
  "DESCRIPTION" VARCHAR2(50 CHAR) NOT NULL ENABLE, 
  "XML_TXT" "XMLTYPE" NOT NULL ENABLE
);

INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (101, 'XML DATA', '<data>TEST</data>');
COMMIT;

DROP TABLE "XMLTEST";

Код Java

String sql = "INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (?, ?, ?)";
String xmlDataStr = "<data>test...</data>"; // a long xml string with length > 4000 characters
Connection con = getEntityManager().unwrap(Connection.class);
SQLXML sqlXml = con.createSQLXML();
sqlXml.setString(xmlDataStr);

Java-код - используйте PreparedStatement

PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setLong(1, 201);
pstmt.setLong(2, "Long XML Data");
pstmt.setSQLXML(3, sqlXml);
pstmt.execute();

Java-код - используйте собственный запрос вместо PreparedStatement

Query query = getEntityManager().createNativeQuery(sql);
query.setParameter(1, 301);
query.setParameter(2, "Long XML Data");
query.setParameter(3, sqlXml);
query.executeUpdate();

Ответ 14

У меня была такая же проблема с использованием PHP и подготовленных операторов в столбце VARCHAR2. Моя строка не превышала размер VARCHAR2. Проблема заключалась в том, что я использовал -1 как maxlength для привязки, но содержимое переменной позже изменилось.

В примере:

$sMyVariable = '';
$rParsedQuery = oci_parse($rLink, 'INSERT INTO MyTable (MyVarChar2Column) VALUES (:MYPLACEHOLDER)');
oci_bind_by_name($rParsedQuery, ':MYPLACEHOLDER', $sMyVariable, -1, SQLT_CHR);

$sMyVariable = 'a';
oci_execute($rParsedQuery, OCI_DEFAULT);
$sMyVariable = 'b';
oci_execute($rParsedQuery, OCI_DEFAULT);

Если вы замените -1 максимальной шириной столбца (например, 254), то этот код работает. С -1 oci_bind_by_param использует текущую длину содержимого переменной (в моем случае 0) как максимальную длину для этого столбца. Это приводит к выполнению ORA-01461.

Ответ 15

Этот ORA-01461 не возникает только при вставке в длинный столбец. Эта ошибка может возникнуть при связывании длинной строки для вставки в столбец VARCHAR2 и чаще всего происходит, когда проблема с символом множественного байта (означает, что один символ может принимать более одного байта в oracle).

Если база данных UTF-8, то из-за того, что каждый символ может принимать до 3 байтов, преобразование 3 применяется для проверки и поэтому фактически ограничено использованием 1333 символов для вставки в varchar2 (4000).

Другим решением будет изменение типа данных из varchar2 (4000) в CLOB.