简体   繁体   中英

Why am I getting ORA-01401: inserted value too large for column - when I'm not inserting?

Here is some SQL to set up with a very simple table.

CREATE TABLE CC_TEST2 
  ("CURRENCYID" NUMBER NOT NULL ENABLE, 
"NAME" NVARCHAR2(255)) ;


insert into CC_TEST2 (select 1,'Testing issue'from dual);
commit;

Then this recreates the issue

    SELECT (step.Name ||
    'Commentary of 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890            1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
    1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 12')
 as thing  FROM CC_TEST2 step

Any ideas?

I think it's something odd about nVarchar2? If I change the column type to varChar2 then it's OK. Sadly I can't change the column type of the actual production database where I'm getting the issue

If "NAME" NVARCHAR2(255) is changed to "NAME" VARCHAR2(255) (ie by using varchar2) you won't get any issue. You can test the same at http://sqlfiddle.com/#!4/cefd8/2

There seems to be some strangeness with NVARCHAR2 and string concatenation.

See http://sqlfiddle.com/#!4/936c4/2

My understanding based on running the various statements in the SQL Fiddle is that the string constant on the right hand side of the concatenation operator || is also treated as an NVARCHAR2, and can be at most 1000 characters.

As per oracle documentation

NCHAR and NVARCHAR2 Datatypes

NCHAR and NVARCHAR2 are Unicode datatypes that store Unicode character data. They are also called as Native data types.

The NVARCHAR2 datatype stores variable length character strings.

When you create a table with an NVARCHAR2 column, the maximum size specified is always in character length semantics. Character length semantics is the default and only length semantics for NVARCHAR2 .

For example, if national character set is UTF8 , then the following statement defines the maximum byte length of 90 bytes:

CREATE TABLE tab1 (col1 NCHAR(30));

The maximum length of an NVARCHAR2 column is 4000 bytes. It can hold up to 4000 characters. The actual data is subject to the maximum byte limit of 4000. The two size constraints must be satisfied simultaneously at run time.

It all depends on your character set and length semantics.

Reason for your problem is

One other important thing to remember is that the upper bound of the number of bytes stored in a VARCHAR2 is 4,000. However, even if you specify VARCHAR2(4000 CHAR), you may not be able to fit 4,000 characters into that field. In fact, you may be able to fit as few as 1,000 characters in that field if all of the characters take 4 bytes to be represented in your chosen character set!

This holds good for Native datatype also.

Solution:

Use CHAR instead of BYTES as the length semantics for VARCHAR2 or CHAR.

The reason is that a 20-character string in a single-byte character set is 20 bytes long and will absolutely fit in a VARCHAR2(20). However a 20-character field could be as long as 80 bytes in a multibyte character set, and 20 Unicode characters may well not fit in 20 bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM