【问题标题】:ORA-12899: value too large for columnORA-12899: 值对于列来说太大
【发布时间】:2015-02-19 00:49:25
【问题描述】:

我以提要的形式从 erp 系统获取数据,特别是提要中的一列长度仅为 15。

在目标表中也对应列的长度也是varchar2(15),但是当我尝试将其加载到数据库中时,它显示如下错误:

ORA-12899: 列 emp_name 的值太大(实际值:16,最大值: 15)

我不能增加列长,因为它是生产中的基表。

【问题讨论】:

  • 你是说:有两个表,都有一个 varhcar2(15) 列,当你将 table1 中的值插入 table2 时,你会得到错误?
  • 如果它们真的是 varchar2(15) - 而不是 nvarchar2,那么您的代码会以某种方式添加字符。代码 sql 是什么样的(编辑您的帖子以添加它)。
  • 这是简单的插入语句,如下所示 insert into aaa (id, site_id) select id,site_id from bbb where id in (select id from cc)
  • 在 nls_database_parameters table parameter='NLS_LENGTH_SEMATICS' 的值为 'BYTE'。我需要将其更改为字符。
  • 对不起,如果我听起来脾气暴躁,但是您现在标记为接受的答案在哪些方面比我的(以前接受的)答案更好?它只是给出了相同的建议 (ALTER TABLE ... ),它不包含任何额外的有用信息,只包含一个外部链接(不鼓励在 SO 上使用)。

标签: oracle


【解决方案1】:

我发现 AL32UTF8 是唯一有效的设置。这与标准 UTF8 不同,其中一些字符具有补充字节,即字符大约 99% 相同。我猜你有字符转换问题。换句话说,table1 中的数据是使用一个字符集写入的,而新表的字符集略有不同。

如果这是真的,你必须找到古怪字符集的来源。因为这将继续发生。

【讨论】:

    【解决方案2】:

    此类问题的常见原因是非 ASCII 字符可以在原始数据库中用一个字节表示,但在目标数据库中需要两个(或更多)字节(由于不同的 NLS 设置)。

    为确保您的目标列足够容纳 15 个字符,您可以对其进行修改:

      ALTER TABLE table_name MODIFY column_name VARCHAR2(15 CHAR)
    

    (注意15 CHAR - 您也可以使用BYTE;如果两者都不存在,则数据库默认使用 NLS_LENGTH_SEMANTICS 设置。

    要检查哪些值大于 15 个字节,您可以

    • 在目标数据库中创建一个暂存表,列长度设置为15 CHAR
    • 将源表中的数据插入到暂存表中
    • 找到有问题的行

      SELECT * FROM staging WHERE lengthb(mycol) > 15

    (注意LENGTHBLENGTH 相对,前者返回字节长度,而后者返回字符长度)

    【讨论】:

      【解决方案3】:

      看看这个博客,我通过将列数据类型从 varchar(100) 更改为 varchar(100 char) 解决了这个问题。就我而言,数据包含一些变音符号。

      http://gerardnico.com/wiki/database/oracle/byte_or_character

      【讨论】:

        【解决方案4】:

        解决办法:

        ORA-12899:值对于列来说太大(实际,最大值)

        如果您在更新表的列大小时遇到​​问题,该表的数据已经超过了下面的新长度,那么这个简单的脚本肯定可以工作。

        ALTER TABLE TABLE_NAME ADD (NEW_COLUMN_NAME DATATYPE(DATASIZE));
        UPDATE TABLE_NAME SET NEW_COLUMN_NAME  = SUBSTR(OLD_COLUMN_NAME , 1, NEW_LENGTH);
        ALTER TABLE TABLE_NAME DROP COLUMN OLD_COLUMN_NAME ;
        ALTER TABLE TABLE_NAME RENAME COLUMN NEW_COLUMN_NAME  TO OLD_COLUMN_NAME;
        

        查询含义:

        ALTER TABLE TABLE_NAME ADD (NEW_COLUMN_NAME DATATYPE(DATASIZE));
        

        它只会在现有表中创建所需新长度的新列。

        UPDATE TABLE_NAME SET NEW_COLUMN_NAME  = SUBSTR(OLD_COLUMN_NAME , 1, NEW_LENGTH);
        

        它将丢弃旧列值中新长度值之后的所有值,并将修剪后的值设置为新列名。

        ALTER TABLE TABLE_NAME DROP COLUMN OLD_COLUMN_NAME ;
        

        它现在将删除旧的列名,因为它很荒谬,我们已将所有信息复制到新列中。

        ALTER TABLE TABLE_NAME RENAME COLUMN NEW_COLUMN_NAME  TO OLD_COLUMN_NAME;
        

        将新列名重命名为旧列名将帮助您恢复原始表结构,但新列大小除外。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-09
          • 2023-03-23
          • 1970-01-01
          • 1970-01-01
          • 2015-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多