【问题标题】:Exporting/Importing data across environments in Oracle with an IDENTITY column在 Oracle 中使用 IDENTITY 列跨环境导出/导入数据
【发布时间】:2018-07-31 23:14:02
【问题描述】:

我在列上使用 IDENTITY 子句创建了一个表,如下所示:

CREATE TABLE tablename
(
    id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    c1 VARCHAR2 (100),
    c2 VARCHAR2 (100),
    c3 VARCHAR2 (100)
);

然后我在这个表中插入了一些行:

INSERT INTO tablename(c1,c2,c3)
VALUES('a','b','c')
INSERT INTO tablename(c1,c2,c3)
VALUES('d','e','f')
...

每行自动生成 id 列,分别为 1、2 等。

然后我需要导出表和数据并导入到新环境。我将数据导出为 xls 文件,在新环境中创建表,并从 xls 文件中导入数据。

数据已成功导入,但当我尝试插入新行时遇到错误

ORA-00001:违反了唯一约束 (APPS.SYS_C00453325)

我认为这是因为 id 列试图再次从 1 开始,其中导入的数据中已经存在 id 为 1 的行。

有没有办法让 IDENTITY 列从导入的最高 id 值继续?

我意识到使用 INSERT 脚本导入我的数据可以解决这个问题。使用任何其他方法导出/导入数据是否被视为不好的做法?

非常感谢任何建议。

编辑:

我还发现即使使用 INSERT 脚本也会出现同样的错误。由于在 INSERT 期间提供了 id 值,因此 IDENTITY 序列永远不会被访问,因此永远不会增加。是否可以使用 IDENTITY 从我手动插入的 ID 继续序列?

【问题讨论】:

  • 使用数据泵导出和导入是否可以避免这个问题? (我想是这样,但我还没有尝试过)。否则,在目标中创建表之前,您是否知道源中的最高 ID - 如果知道,您可以为标识列指定 start with? (如果您要重复此操作将不起作用;但在目标中插入新行表明这是一次性的,我认为。)
  • 而识别列实际上只是下面的一个序列;您还可以识别它并在“导入”之后使用通常的技术将其重置为更高的值。你失败的插入也会增加它,所以如果你重复第一个新的插入,它最终会起作用……虽然不理想!
  • 谢谢亚历克斯。我不熟悉数据泵,但我一定会研究它。

标签: sql oracle insert export identity


【解决方案1】:

您可以使用start with limit value 修改列的生成属性。

create table demo1
( id integer generated by default as identity primary key
, dummy varchar2(1) );

insert into demo1 (dummy) select dummy from dual connect by rownum <= 10;

-- 10 rows created.

create table demo2
( id integer generated by default as identity primary key
, dummy varchar2(1) );

insert into demo2 select * from demo1;

-- 10 rows created.

insert into demo2 (dummy) select 'Y' from dual;

-- Fails with ORA-00001: unique constraint (xxx.SYS_C001886275) violated
-- because the identity generator tries to set id = 1, but 1 already exists in the table.

alter table demo2 modify id generated by default as identity start with limit value;

-- Table altered.

insert into demo2 (dummy) select 'Y' from dual;

-- 1 row created.

select * from demo2;

       ID DUMMY
--------- -----
        1 X
        2 X
        3 X
        4 X
        5 X
        6 X
        7 X
        8 X
        9 X
       10 X
       11 Y

此时最好避免手动输入 ID 值:

alter table demo2 modify id generated always as identity;

-- Table altered.

insert into demo2 (id, dummy) values (99, 'Z')
--                 *
-- ERROR at line 1:
-- with ORA-32795: cannot insert into a generated always identity column

【讨论】:

  • 感谢您的回复。为了进一步防止手动输入 ID 值,我是否应该确保我的 INSERT 脚本仅排除 ID 列,让 IDENTITY 序列处理所有内容?
  • 是的,您可以省略 ID 列并让身份机制处理它。如果您将其定义为generated always 而不是generated by default,那么它将不允许您为ID 指定值。
猜你喜欢
  • 2019-12-06
  • 2021-08-25
  • 2017-08-24
  • 2012-12-12
  • 2013-06-21
  • 2023-03-30
  • 2010-10-15
  • 1970-01-01
  • 2022-12-06
相关资源
最近更新 更多