在 Oracle 12c 的 IDENTITY 列中通过 SQL * Loader 加载数据

Posted

技术标签:

【中文标题】在 Oracle 12c 的 IDENTITY 列中通过 SQL * Loader 加载数据【英文标题】:Load data via SQL * Loader in IDENTITY column in Oracle 12c 【发布时间】:2017-03-31 14:34:05 【问题描述】:

我需要使用 SQL* Loader 将数据加载到带有 GENERATE ALWAYS AS IDENTITY 的 Oracle 表中

CREATE TABLE tbl_identity
(
  col1 NUMBER(10,0) GENERATED ALWAYS AS IDENTITY(START WITH 7 INCREMENT BY 1)    NOT NULL,
  col2 VARCHAR2(20)
);

但是当我尝试在这个表中加载数据时,我得到一个错误

ORA-32795: cannot insert into a generated always identity column

也许 SQLLDR 中有任何选项可以跳过 IDENTITY 一段时间?

或者有什么想法可以使用 SQLLDR 将数据加载到 GENERATED ALWAYS IDENTITY 列中?

SQLLDR 命令

sqlldr userid=user/passw@TNS control=tbl_identity.ctl log=tbl_identity.log rows=1000 readsize=65535 bindsize=65535

CTL 文件

OPTIONS(direct=false)
LOAD DATA
INFILE 'tbl_identity.txt'
INTO TABLE tbl_identity
INSERT
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
(col1,
 col2)

【问题讨论】:

忽略该列并加载其他列。你能显示 sql 加载器脚本吗? 但是如果我有这样的东西1 'one'2 'two'4 'four'如果我忽略第一列,它会加载我不正确的数据这是SQLLDR命令sqlldr userid=user/passw@TNS control=tbl_identity.ctl log=tbl_identity.log rows=1000 readsize=65535 bindsize=65535 我觉得你应该把tbl_identity.ctl的内容贴出来 OPTIONS(direct=false) LOAD DATA INFILE 'tbl_identity.txt' INTO TABLE tbl_identity INSERT FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (col1, col2) 【参考方案1】:

将您的 DDL 从 GENERATED ALWAYS 更改为 GENERATED BY DEFAULT

【讨论】:

好的,我已经考虑过这个解决方案,但我想防止在将数据加载到表后将任何 INSERT 插入 IDENTITY 列。我试图制作ALTER TABLE MODIFY col1 NUMBER(10,0) GENERATED ALWAYS AS IDENTITY,但在这种情况下,我需要为身份指定开始位置 - MAX (col1) +1。如果我有很多桌子,我想知道如何快速完成 这不是一个真正可行的解决方案。在 DDL 中使用这两个参数时,意图存在明显差异。我有点惊讶 GENERATED ALWAYS 的行为方式。有没有办法和SQL*Loader结合起来?【参考方案2】:

我在加载数据之前使用以下脚本:

begin
  for rec in (
    select owner, table_name, column_name, generation_type
    from all_tab_identity_cols
    where owner = 'owner '
      and generation_type in ('ALWAYS')
      and table_name in ('','',......)
  )loop
     -- before load data
     if rec.generation_type = 'ALWAYS' then
       execute immediate 'alter table '||rec.owner||'.'||rec.table_name||' modify '||rec.column_name||' generated by default as identity';
     end if;
     if rec.generation_type = 'BY DEFAULT' then
     -- return (after data load)
       execute immediate 'alter table '||rec.owner||'.'||rec.table_name||' modify '||rec.column_name||' generated always as identity';
     end if;
  end loop;
end;            
/

然后将一切恢复原状。

小心,在查询中列出正确的表!

【讨论】:

以上是关于在 Oracle 12c 的 IDENTITY 列中通过 SQL * Loader 加载数据的主要内容,如果未能解决你的问题,请参考以下文章

Oracle12c:支持通过创建identity columen来实现创建自增列

如何在 oracle 12c 中使用多个数据更新单个列

Oracle 12c - 插入到选择查询中的不明确列,ORA-00918

12c带你了解Oracle 12c数据库扩展的统计信息(Extended Statistics)的搜集

12c带你了解Oracle 12c数据库扩展的统计信息(Extended Statistics)的搜集

12c 新特性-隐藏列