`
starbhhc
  • 浏览: 649795 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
社区版块
存档分类
最新评论

如何解决DB2数据迁移中的外键约束问题

 
阅读更多

测试表

-- 创建测试主表. ID 是主键.
CREATE TABLE test_main (
  id      INT   NOT NULL,
  value   VARCHAR(10),
  PRIMARY KEY(id)  
);


-- 创建测试子表. 
CREATE TABLE test_sub (
  id      INT  NOT NULL,
  main_id INT ,
  value   VARCHAR(10),
  PRIMARY KEY(id)  
);


-- 插入测试主表数据.
INSERT INTO test_main(id, value) VALUES (1, 'ONE');
INSERT INTO test_main(id, value) VALUES (2, 'TWO');

-- 插入测试子表数据.
INSERT INTO test_sub(id, main_id, value) VALUES (1, 1, 'ONEONE');
INSERT INTO test_sub(id, main_id, value) VALUES (2, 2, 'TWOTWO');

 

 

 

默认外键约束方式

db2 => ALTER TABLE test_sub ADD CONSTRAINT main_id_cons  FOREIGN KEY (main_id)  REFERENCES  test_main;
DB20000I  SQL 命令成功完成。

db2 => DELETE
db2 (cont.) =>   test_main
db2 (cont.) => WHERE
db2 (cont.) =>   ID = 1;
DB21034E  该命令被当作 SQL 语句来处理,因为它是无效的"命令行处理器"命令。在
SQL 处理期间,它返回:
SQL0532N  因为关系 "WZQ.TEST_SUB.MAIN_ID_CONS" 限制删除,所以不能删除父行。
SQLSTATE=23504

 

测试完毕后,删除 外键约束 
ALTER TABLE test_sub DROP CONSTRAINT main_id_cons;

 

 

 

DELETE CASCADE 方式

 

db2 => ALTER TABLE test_sub
db2 (cont.) =>   ADD CONSTRAINT main_id_cons
db2 (cont.) =>     FOREIGN KEY (main_id)
db2 (cont.) =>       REFERENCES  test_main   ON DELETE CASCADE;
DB20000I  SQL 命令成功完成。

db2 => -- 测试删除主表数据. 将成功地执行.
db2 => DELETE
db2 (cont.) =>   TEST_MAIN
db2 (cont.) => WHERE
db2 (cont.) =>   ID = 1;
DB20000I  SQL 命令成功完成。

-- 测试检索子表,应该只有一条 main_id = 2 的数据.
db2 =>  SELECT * FROM test_sub;

ID          MAIN_ID     VALUE
----------- ----------- ----------
          2           2 TWOTWO

  1 条记录已选择。

 

测试完毕后,删除 外键约束 
ALTER TABLE test_sub DROP CONSTRAINT main_id_cons;

 

 

 

UPDATE CASCADE方式

DB2 不支持

db2 => ALTER TABLE test_sub
db2 (cont.) =>   ADD CONSTRAINT main_id_cons
db2 (cont.) =>     FOREIGN KEY (main_id)
db2 (cont.) =>       REFERENCES test_main
db2 (cont.) =>         ON UPDATE CASCADE;
DB21034E  该命令被当作 SQL 语句来处理,因为它是无效的"命令行处理器"命令。在
SQL 处理期间,它返回:
SQL0104N  在 "ON UPDATE" 后面找到异常标记
"CASCADE"。预期标记可能包括:"RESTRICT, NO ACTION"。  SQLSTATE=42601

 

 

 

SET NULL方式

 

db2 => ALTER TABLE test_sub
db2 (cont.) =>   ADD CONSTRAINT main_id_cons
db2 (cont.) =>     FOREIGN KEY (main_id)
db2 (cont.) =>       REFERENCES  test_main
db2 (cont.) =>         ON DELETE SET NULL;
DB20000I  SQL 命令成功完成。

db2 => -- 测试删除主表数据. 将成功地执行.
db2 => DELETE TEST_MAIN WHERE ID = 2;
DB20000I  SQL 命令成功完成。

db2 =>  -- 测试检索子表,应该有一条的 main_id = null
db2 => SELECT * FROM test_sub;

ID          MAIN_ID     VALUE
----------- ----------- ----------
          2           - TWOTWO

  1 条记录已选择。

 

 


 

关于非主键的外键设置
-- 创建测试主表.  无主键.
CREATE TABLE test_main2 (
  id      INT   NOT  NULL,
  value   VARCHAR(10)
);


-- 创建测试子表. 
CREATE TABLE test_sub2 (
  id      INT   NOT  NULL,
  main_id INT,
  value   VARCHAR(10),
  PRIMARY KEY(id)  
);


-- 插入测试主表数据.
INSERT INTO test_main2(id, value) VALUES (1, 'ONE');
INSERT INTO test_main2(id, value) VALUES (2, 'TWO');

-- 插入测试子表数据.
INSERT INTO test_sub2(id, main_id, value) VALUES (1, 1, 'ONEONE');
INSERT INTO test_sub2(id, main_id, value) VALUES (2, 2, 'TWOTWO');

 

 

db2 => ALTER TABLE test_sub2
db2 (cont.) =>   ADD CONSTRAINT main_id_cons2
db2 (cont.) =>     FOREIGN KEY (main_id)
db2 (cont.) =>       REFERENCES  test_main2(id);
DB21034E  该命令被当作 SQL 语句来处理,因为它是无效的"命令行处理器"命令。在
SQL 处理期间,它返回:
SQL0573N  在约束 "MAIN_ID_CONS2" 的引用子句中指定的列列表不标识父表或昵称
"WZQ.TEST_MAIN2" 的唯一约束。  SQLSTATE=42890

 

db2 => ALTER TABLE test_main2
db2 (cont.) =>   ADD UNIQUE (id);
DB20000I  SQL 命令成功完成。

 

db2 => ALTER TABLE test_sub2
db2 (cont.) =>   ADD CONSTRAINT main_id_cons2
db2 (cont.) =>     FOREIGN KEY (main_id)
db2 (cont.) =>       REFERENCES  test_main2(id);
DB20000I  SQL 命令成功完成。

 

 

 


启用/禁用 

当遇到批量数据导入的时候,如果外键处于有效的状态。
那么要求 数据导入的程序, 必须先导入主表的数据,然后再导入子表的数据。
如果表多,且关系复杂的话,会增加很大的工作量。

可以在数据导入以前, 先暂时禁用外键约束。
子表、主表数据都导入完毕后, 再启用外键约束。



以下测试环境为 初始的创建表、初始数据的情况。

 


db2 => ALTER TABLE test_sub ADD CONSTRAINT main_id_cons  FOREIGN KEY (main_id)
REFERENCES  test_main;
DB20000I  SQL 命令成功完成。


db2 => INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (3, 3, 'THREETHREE');
DB21034E  该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0530N  FOREIGN KEY "TEST.TEST_SUB.MAIN_ID_CONS"
的插入或更新值不等于父表的任何父键值。  SQLSTATE=23503


db2 =>ALTER TABLE test_sub ALTER FOREIGN KEY main_id_cons NOT ENFORCED;
DB20000I  SQL 命令成功完成。


db2 => INSERT INTO test_sub (ID, MAIN_ID, VALUE) VALUES (3, 3, 'THREETHREE');
DB20000I  SQL 命令成功完成。
db2 => INSERT INTO test_main(id, value) VALUES (3, 'THREE');
DB20000I  SQL 命令成功完成。


db2 => ALTER TABLE test_sub ALTER FOREIGN KEY main_id_cons ENFORCED;
DB20000I  SQL 命令成功完成。
db2 =>

 

db2 => DELETE test_main  WHERE ID = 1;
DB21034E  该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0532N  因为关系 "TEST.TEST_SUB.MAIN_ID_CONS" 限制删除,所以不能删除父行。
SQLSTATE=23504

 

 

 

最后提示三种情况:

第一:
整性的英语单词是integrity,所以这个临时关闭外键约束让你畅快导入的命令是:

set integrity for table_name off 
set integrity for table_name foreign key immediate unchecked 

 

第二:

除了这种方式,你还可以使用alter语句修改constraint,使它不执行,这样也能达到这个目的:
ALTER TABLE <table-name> ALTER FOREIGN KEY <constraint-name> NOT ENFORCED  
数据导入完成后你需要它正常工作,保证数据的完整性:
ALTER TABLE <table-name> ALTER FOREIGN KEY <constraint-name> ENFORCED 

 

 第三:

操作DML之前
ALTER TABLE TABLENAME DISABLE CONSTRAINT CONSTRAINTNAME;

操作完DML以后
ALTER TABLE TABLENAME ENABLE CONSTRAINT CONSTRAINTNAME;

 

 

分享到:
评论

相关推荐

    DB2到GreenPlum/PostgreSQL的转换指南

    - **外键**:DB2支持外键约束,但在GreenPlum/PostgreSQL中,外键约束可能会受到分区等因素的影响。 - **唯一约束**:DB2支持在表级或列级定义唯一约束,而在GreenPlum/PostgreSQL中也可以这样做,但实现方式可能略...

    SQL Server到DB2迁移中级联更新问题解决的探讨.pdf

    这种机制极大地简化了数据库维护工作,尤其是在数据库设计中广泛使用了外键约束的情况下。然而,DB2并不支持这种级联更新操作,这就为数据库迁移工作带来了挑战。 在介绍数据库迁移策略时,作者首先强调了在迁移...

    利用数据转换器移植数据,提供从db2导入到oracle

    数据移植是IT行业中常见的任务,尤其在数据库管理系统之间,如从DB2到Oracle的迁移。这个过程涉及到数据的完整性和一致性,确保业务连续性不受影响。以下是对标题和描述中所述知识点的详细说明: 1. **数据转换器**...

    db2数据库从AIX操作系统移植到windows XP

    在IT行业中,数据迁移是一项常见的任务,特别是在不同的操作系统之间进行时。本文将深入探讨如何将DB2数据库从AIX操作系统移植到Windows XP环境,这是一个跨越不同硬件架构和操作系统的复杂过程。下面我们将分步骤...

    IBM DB2 视频教程

    - **db2move**:实现数据迁移任务,如将数据从一个数据库移动到另一个数据库中。 - **db2stop/db2start**:分别用于停止和启动数据库实例服务。 #### 七、DB2 性能监控与调优实践 - **使用db2top工具**:实时监控...

    DB2日常处理语句db2命令

    - `db2move` 是一个数据迁移工具,可以在不同DB2数据库之间移动数据,即使它们位于不同的服务器上。这对于大规模数据迁移非常有用。 5. **catalog** 和 **uncatalog** - `catalog` 用于将数据库或节点添加到DB2的...

    Server 2000 移植到 DB2

    在移植过程中需要确保所有必需的约束(如主键、外键等)都被正确地迁移到新数据库中。 ##### 计算列 (Computed Columns) 计算列是基于其他列的值通过表达式计算得到的。移植时需要注意 DB2 是否支持相同类型的计算...

    db2mysql access to mysql 数据库转换

    - 最后,将这些数据文件导入到MySQL中,完成数据迁移。 5. **db2mysql工具**: - 这个工具可能提供图形用户界面(GUI)或命令行接口,简化了转换过程。用户无需手动编写大量SQL语句,只需按照指导进行操作。 - ...

    IBM DB2 数据库使用小技巧

    通过`SYSCAT.REFERENCES`视图,可以查询表中的所有外键约束,包括父表和子表之间的关系、更新和删除规则。 #### 23. 了解BUFFER POOLS状态? BUFFER POOLS是DB2内存管理的一部分,用于缓存经常访问的数据页,以...

    DB2错误代码

    如果外键约束在数据库中存在重复引用,DB2将无法正确维护参照完整性,从而引发错误。 ### 权限问题 (+551, 01548; +552, 01542) 在尝试执行受权限控制的操作时,如果当前用户缺乏必要的权限,DB2将拒绝操作并返回...

    DB2错误代码对照表

    为了能够快速定位并解决问题,理解错误代码的含义至关重要。本文将对DB2错误代码对照表进行详细解析,帮助读者深入理解每个错误代码背后的原因及可能的解决方案。 #### 错误代码解析 ##### SQL执行错误 - **SQL ...

    学习笔记:DB2+9+基础.pdf

    #### 四、访问DB2数据 了解如何有效地与DB2数据库交互至关重要。 ##### 1. DB2数据库组成 - **表空间**:物理存储区域,用于存储数据文件。 - **表**:数据的基本存储单位。 - **索引**:加快查询速度的数据结构。 ...

    数据库移库神器,支持10多种常见数据库

    数据库移库工具是一种高效、便捷的数据迁移解决方案,尤其在企业级环境中,经常需要在不同的数据库系统间进行数据和结构的迁移。本工具以其强大的兼容性和灵活性,被誉为“数据库移库神器”,支持包括MySQL、SQL ...

    mysql数据库转换成SQLserver工具包

    1. 数据库结构转换:工具首先分析MySQL的表结构,包括字段名、字段类型、键约束(主键、外键等)、索引等,然后在SQL Server中创建相应的表结构。 2. 数据迁移:将MySQL中的记录逐条读取并写入到SQL Server中,确保...

    SQLtoDB2.rar

    标题“SQLtoDB2.rar”表明这是一个关于将SQL Server数据迁移或转换到IBM DB2数据库的资源包。这个过程通常涉及到数据库结构的映射、数据类型转换、SQL语法的调整等多个方面。描述中的“sql sever转化DB2的东西”...

    mysql数据库转换成SQLserver数据库

    此外,还要考虑主键、外键和约束的转换。 3. **工具使用**:"DB2DB"可能是一个用于数据库转换的工具,它可以帮助简化迁移过程。这类工具通常提供图形用户界面,用户可以配置源数据库和目标数据库的连接,选择要迁移...

    EA帮助文档翻译(数据建模)1.0.doc

    - **检查约束**用于验证插入或更新到表中的数据是否满足特定条件。 ##### 9. 生成DDL - DDL是用于创建数据库对象(如表、索引、视图等)的语言。 - EA支持自动生成DDL脚本,这对于数据库的快速部署非常有用。 - ...

Global site tag (gtag.js) - Google Analytics