ORA-01461: может связывать значение LONG только для вставки в столбец LONG-Происходит при запросе - PullRequest
61 голосов
/ 06 февраля 2012

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

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

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

Ответы [ 15 ]

174 голосов
/ 24 января 2013

Это также может произойти с колонками varchar2. Это довольно воспроизводимо с PreparedStatements через JDBC просто

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

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

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

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

32 голосов
/ 18 сентября 2013

Эта ошибка возникает при попытке использовать переменную 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;
15 голосов
/ 06 февраля 2012

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

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

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

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

Вот список ограничений типа данных LONG

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

7 голосов
/ 14 апреля 2015

Я и мой коллега узнали следующее:

Когда мы используем драйвер Oracle для Microsoft .NET для подключения к базе данных 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 на эту ошибку много лет назад, но она до сих пор не исправлена.

4 голосов
/ 04 декабря 2018

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

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

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

4 голосов
/ 19 февраля 2014

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

3 голосов
/ 17 октября 2016

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

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

НТН

2 голосов
/ 17 сентября 2014

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

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

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

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

1 голос
/ 03 апреля 2017

В моем конкретном случае я пытался сохранить файл в кодировке 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>

и вmy DTO:

String getPdf(){
    return pdf;
}

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

В моем DTO:

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

И сработало.

Надеюсь, это может кому-нибудь помочь.

1 голос
/ 12 октября 2015

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...