Значение ORA-12899 слишком велико для столбца, несмотря на одинаковую длину

Я запускаю следующий запрос. Но получение ORA-12899. Хотя длина строки, которую я пытаюсь вставить, равна 30.

INSERT INTO TABLE1 SELECT * FROM temp_Table1 where LENGTH(column1)=30;

SQL Error: ORA-12899:value too large for column "TABLE1"."column1" (actual: 31, maximum: 30)


select column1 from temp_Table1 where LENGTH(column1)=30;

Testing  - HLC/TC Design Corre

Desc temp_Table1

column1 VARCHAR2(30)

Desc Table1

column1 VARCHAR2(30)

person Shitu    schedule 09.09.2016    source источник
comment
column1 может содержать максимум 30 символов, вы передаете 31 символ.   -  person Gehan Fernando    schedule 09.09.2016
comment
Может быть, эта тема поможет вам ORA-12899: значение слишком велико для столбца   -  person AlexSmet    schedule 09.09.2016


Ответы (4)


Вы видите разницу между семантикой длины символов и байтов< /а>:

Вы должны указать максимальную длину столбца VARCHAR2. Этот максимум должен быть не менее 1 байта, хотя фактическая сохраняемая строка может быть строкой нулевой длины (''). Вы можете использовать квалификатор CHAR, например, VARCHAR2(10 CHAR), чтобы указать максимальную длину в символах, а не в байтах. Символ технически является кодовой точкой набора символов базы данных. Вы можете использовать квалификатор BYTE, например, VARCHAR2(10 BYTE), чтобы явно указать максимальную длину в байтах. Если явный квалификатор не включен в определение столбца или атрибута при создании объекта базы данных с этим столбцом или атрибутом, то семантика длины определяется значением параметра NLS_LENGTH_SEMANTICS сеанса, создающего объект.

Если ваш сеанс использует семантику байтов, тогда столбец в вашей таблице по умолчанию будет таким:

select value from nls_session_parameters where parameter = 'NLS_LENGTH_SEMANTICS';

VALUE                                  
----------------------------------------
BYTE                                    

create table t42(text varchar2(5));

Table T42 created.

select char_used from user_tab_columns where table_name = 'T42' and column_name = 'TEXT';

C
-
B

Это то же самое, что и явное выполнение:

create table t42(text varchar2(5 byte));

Если ваши исходные данные состоят из пяти символов, но содержат многобайтовые символы, количество байтов превысит пять:

insert into t42 (text) values ('Hello');

1 row inserted.

insert into t42 (text) values ('Señor');

SQL Error: ORA-12899: value too large for column "SCHEMA"."T42"."TEXT" (actual: 6, maximum: 5)

Что вы и видите. Когда вы вставляете значения из другой таблицы, вы фильтруете длину значений, но length() считает символы, а не байты. Существует функция lengthb(), которая считает байты. Если вы проверите длину в байтах 30-символьного значения, которое вы выбираете, вы увидите, что на самом деле оно составляет 31 байт, поэтому один из этих символов является многобайтовым.

with t42 (text) as (
  select 'Hello' from dual
  union all select 'Señor' from dual
  union all select 'Testing  - HLC/TC Design Corre' from dual
)
select text, length(text) as chars, lengthb(text) as bytes, dump(text, 16) as hex
from t42;

TEXT                            CHARS BYTES HEX                                                                                                      
------------------------------- ----- ----- ----------------------------------------------------------------------------------------------------------
Hello                               5     5 Typ=1 Len=5: 48,65,6c,6c,6f                                                                               
Señor                               5     6 Typ=1 Len=6: 53,65,c3,b1,6f,72                                                                            
Testing  - HLC/TC Design Corre     30    31 Typ=1 Len=31: 54,65,73,74,69,6e,67,c2,a0,20,2d,20,48,4c,43,2f,54,43,20,44,65,73,69,67,6e,20,43,6f,72,72,65

Из значений dump() видно, что после Testing (54,65,73,74,69,6e,67) и перед пробелом и тире (20,2d) у вас есть c2,a0, что равно многобайтовый неразрывный пробел UTF-8. (Вы часто видите это, наряду с фигурными кавычками и другими символами, не входящими в диапазон ASCII, в тексте, который был скопирован, скажем, из документа Word).

Вы можете изменить свою вставку на фильтрацию по LENGTHB(column1)=30 (что исключит строку, которую вы сейчас находите), или изменить определение столбца на 30 символов вместо 30 байтов:

drop table t42;

Table T42 dropped.

create table t42(text varchar2(5 char));

Table T42 created.

select char_used from user_tab_columns where table_name = 'T42' and column_name = 'TEXT';

C
-
C

insert into t42 (text) values ('Hello');

1 row inserted.

insert into t42 (text) values ('Señor');

1 row inserted.

Или замените любые неожиданные многобайтовые символы однобайтовыми эквивалентами, если это возможно и имеет смысл для ваших данных; в этом случае обычный пробел может работать, но с любой заменой вы уничтожаете информацию, которая может быть действительно важной.

person Alex Poole    schedule 09.09.2016

Попробуйте изменить свою таблицу, как

ALTER TABLE1 MODIFY column1 VARCHAR2(30 CHAR)

В ошибке указано, что ваш столбец 1 может хранить максимум 30 символов, и вы передаете в него более 30 символов, что приводит к ошибке.

Вы также можете сослаться на эту статью: База данных Oracle — байты или символы для VARCHAR2 и CHAR

person Rahul Tripathi    schedule 09.09.2016

ORA-12899

Часто, когда наши компании растут и развиваются в ответ на расширение клиентской базы, персонала, прибыли или рынков, данные, связанные с этим ростом, также будут меняться. Системы данных, такие как Oracle, обладают врожденной способностью оставаться достаточно гибкими в отношении работы с такой разницей в информации. Тем не менее, даже самые универсальные системы баз данных требуют обслуживания и усовершенствования в условиях увеличения трафика данных. Эта работа необходима для учета любых ограничений памяти или необходимых переопределений параметров. Ошибка ORA-12899 представляет собой случай, когда скачок данных или ошибка пользователя вынуждают Oracle останавливаться во время запрошенного действия.

ПРОБЛЕМА

ORA-12899 — это ошибка Oracle, которая возникает, когда значение, введенное в строку столбца, слишком велико. Это означает, что пользователь предпринял попытку обновить или вставить столбец со значением, которое слишком велико для целевого столбца. Будет указано имя конкретного столбца, и с ним будет связана фактическая ширина значения, а также максимальная ширина, разрешенная для столбца. Как уже упоминалось, значение может быть задано в виде символов. Если ширина указывается в символах, это будет означать, что для столбца работает семантика длины символов. В противном случае ширина будет указана в байтах. По сути, эта ошибка возникает из-за попытки передать значение или набор значений, которые превышают указанную максимальную ширину столбца. Итак, как пользователь исправляет этот тип ошибки?

РЕШЕНИЕ

Для начала откройте утилиту OERR. Пользователю потребуется полное сообщение ORA-12899, чтобы получить надлежащую обратную связь об ошибке. Это предоставит дополнительную информацию об ошибке и позволит провести дальнейшее расследование. Как правило, ошибка может исходить из одного из трех источников. Первый источник — это сгенерированные операторы SQL. Проверка типов данных исходного и целевого столбца, чтобы выяснить, совместимы ли они с текущими форматами, является вторым источником. Наконец, пользователь может посмотреть на ширину целевого столбца, где присваивается значение, чтобы убедиться, что она достаточно велика для размещения максимального значения, которое пользователь ожидает назначить. Теперь обратимся к примеру, исправляющему ORA-12899. Предположим, пользователь создал следующую таблицу:

CREATE TABLE Clients(
ClientID varchar2(9) PRIMARY KEY,
Client_Contact varchar2(40) NOT NULL,
Address varchar(20) NOT NULL,
Zip varchar2(5) NOT NULL,
Client_Number varchar2(11) NOT NULL)

Затем пользователь пытается выполнить оператор INSERT VALUES, который выглядит примерно так:

INSERT INTO Clients VALUES(
727546345,
‘Roger Holcomb’,
‘—Benjamin Road Syracuse’,
‘-----‘, 05307623754)

Пользователь может попытаться запустить инструкцию отсюда, но получит следующее сообщение об ошибке:

Ошибка, начинающаяся со строки 7 в команде: INSERT INTO Clients VALUES (727546345, «Рики Галори», «18 Benjamin Road Syracuse», «13208», 05307623754) Отчет об ошибке: Ошибка SQL: ORA-12899: значение слишком велико для столбца «ОРГАНИЗАЦИИ». ». "РЫНОК". «АДРЕС» (фактический: 25, максимальный: 20) 12899. 00000 — «значение слишком велико для столбца %s (фактический: %s, максимальный: %s)»

Это утверждение об ошибке указывает, что переменная «Адрес» не может содержать более двадцати символов, поскольку это превысит ширину параметра столбца. Когда мы смотрим на значение адреса («18 Benjamin Road Syracuse»), мы видим, что общее количество символов (25) превышает максимально допустимое количество для ширины столбца. Чтобы исправить это, пользователь может изменить VARCHAR2 для адреса на величину, которая может соответствовать типичной длине адреса, которую вводит его компания.

Исходный URL ответа выше

person Gehan Fernando    schedule 09.09.2016

Из-за различных настроек NLS в базе данных целевой таблицы может потребоваться больше байтов в целевой базе данных. Попробуйте изменить таблицу, как изменить таблицу1 изменить столбец1 varchar2 (30 символов)

person lakshmi tatavarty    schedule 09.09.2016