问题
I am running the following query. But getting ORA-12899. Altough the length of string am trying to insert is 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)
回答1:
You're seeing the difference between character and byte length semantics:
You must specify a maximum length for a VARCHAR2 column. This maximum must be at least 1 byte, although the actual string stored is permitted to be a zero-length string (''). You can use the CHAR qualifier, for example VARCHAR2(10 CHAR), to give the maximum length in characters instead of bytes. A character is technically a code point of the database character set. You can use the BYTE qualifier, for example VARCHAR2(10 BYTE), to explicitly give the maximum length in bytes. If no explicit qualifier is included in a column or attribute definition when a database object with this column or attribute is created, then the length semantics are determined by the value of the NLS_LENGTH_SEMANTICS parameter of the session creating the object.
If your session is using byte semantics then the column in your table will default to that:
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
That is the same as explicitly doing:
create table t42(text varchar2(5 byte));
If your source data is five characters but includes any multibyte characters then the number of bytes will exceed five:
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)
Which is what you're seeing. When you insert the values from your other table you are filter on the length of the values, but length()
counts characters rather than bytes. There is a lengthb()
function that does count bytes. If you check the byte length of the 30-character value you're selecting you'll see it is in fact 31 bytes, so one of those characters is multibyte.
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
From the dump()
values you can see that after Testing
(54,65,73,74,69,6e,67
) and before the space and dash (20,2d
) you have c2,a0
, which is the UTF-8 multibyte non-breaking space character. (You often see that, along with curly quotes and other non-ASCII-range characters, in text that has been copied from,. say, a Word document).
You can either change your insert to filter on LENGTHB(column1)=30
(which will exclude the row you currently find), or change your column definition to 30 characters instead of 30 bytes:
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.
Or replace any unexpected multibyte characters with single-byte equivalents, if that's possible and makes sense for your data; in this case a normal space might work, but with any substitution you are destroying information that might actually be important.
回答2:
Try to change your table like
ALTER TABLE1 MODIFY column1 VARCHAR2(30 CHAR)
The error states that your column1 can store maximum of 30 characters and you are passing more than 30 characters in it which results in the error.
You can also refer this article: Oracle Database - Bytes or Characters for VARCHAR2 and CHAR
回答3:
ORA-12899
Often times, as our companies grow and evolve in response to an expansion in the form of client-base, staff, profit or markets, the data associated with this growth will also change. Data systems like Oracle have the innate ability to remain fairly flexible in regards to working with this variance in information. Still, even the most versatile database systems require maintenance and refining in the face of increased data traffic. This work is essential to accommodating any constraints on memory or necessary redefinitions of parameters. The ORA-12899 error is representative of an instance in which either an uptick in data or a user error is forcing Oracle to stall during its requested action.
THE PROBLEM
The ORA-12899 is an Oracle error that occurs when the value entered into the column string is too large. What this means is that an attempt was made by the user to update or insert a column with a value that is too wide for the destination column. The name of a particular column will be given and the actual width of the value, as well as the maximum width permitted for the column, will be associated with that. As mentioned, the value can be given in the form of characters. In the event that the width is reported in characters, this will mean that character length semantics are operating for the column. Otherwise the width will be reported in bytes. Essentially, this error results from trying to push through a value, or set of values, that exceed the specified maximum width of the column. So, how does a user correct this type of error?
THE SOLUTION
To begin, open up the OERR utility. The user will require the full ORA-12899 message to receive the proper feedback on the error. This will provide more information on the error and allow further investigation. Typically, the error can come from one of three sources. The first source is the SQL statements that have been generated. Checking source and destination column data types to discover whether they are compatible with current formats is the second source. Lastly, the user can look at the destination column width – where the value is being assigned – to make sure it is large enough to accommodate the maximum value that the user anticipates assigning. Let us now turn to an example that corrects ORA-12899. Suppose the user has created the following table:
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)
The user then attempts to issue an INSERT VALUES statement that looks something like this:
INSERT INTO Clients VALUES( 727546345, ‘Roger Holcomb’, ‘—Benjamin Road Syracuse’, ‘-----‘, 05307623754)
The user might try to run the statement from here, but will receive the following error message:
Error starting at line 7 in command: INSERT INTO Clients VALUES(727546345, ‘Ricky Galorey’, ‘18 Benjamin Road Syracuse’, ‘13208’, 05307623754) Error report: SQL Error: ORA-12899: value too large for column “ORGANIZATIONS”. “MARKET”. “ADDRESS”(actual: 25, maximum: 20) 12899. 00000 – “value too large for column %s (actual: %s, maximum: %s)”
This error statement indicates that the variable ‘Address’ cannot hold more than twenty characters as that would exceed the width of the column parameter. When we look back at the address value (’18 Benjamin Road Syracuse’) we can see that the total number of characters (25) exceeds the maximum number allowed for the width of the column. To correct this, the user can change the VARCHAR2 for address to an amount that can accommodate the typical address length that their company would input.
The above answer original URL
回答4:
Due to different NLS settings in the target table database it might require more bytes in the target. Try altering the table as alter Table1 modify column1 varchar2(30 char)
来源:https://stackoverflow.com/questions/39405026/ora-12899-value-too-large-for-column-despite-of-same-length