1.问题背景

尽管在数据库操作中我们并不提倡改动主键,可是确实在实际生活中有这种业务需求:

表A有主键KA,表B中声明了一个references A(KA)的外键约束。我们须要改动A中某条目KA的值而且更新B中外键约束。

可是DBMS在运行了第一条update后检查完整性会发现冲突:B中条目的外键不存在

注:我在Oracle database环境下遇到这个问题的。Oracle非常蛋疼的不能设置外键为update级连。所以仅仅有人工处理。

2.举例说明

用一个简单的样例说明。数据库中有下面三个表:

(1)学生表。属性有学号(主键)、姓名和年龄:

create table Student(S# integer primary key, sname varchar2(20), age integer);

(2)课程表,属性有课程号(主键)、课程名和学分:

create table Course(C# integer primary key, cname varchar2(20), credit integer);

(3)成绩表,属性有学号、课程号和分数,学号是学生表中学号外键、课程号是课程表中课程号外键:

create table SC (
S# integer foreign key (S#) references Student(S#) on delete cascade
C# integer foreign key (C#) references Course(C#) on delete cascade
score integer
);

我们须要改动一个学生的学号,假设成绩表中存在改学生的成绩条目,那么就会引发上述完整性冲突。

3.解决方式

我想到的思路有两个:

  • 屏蔽(或删除)SC表外键约束,改动Student表学号,而且在保证一致性(我们DBA来保证)的情况下更新全部SC中该学生的学号,最后恢复(或加入)SC表外键约束。

  • 取出SC中全部该学生的成绩条目放在零时表/外部变量中然后删除SC中的这些记录,改动Student表学号,而且在保证一致性(相同我们DBA保证)的情况下改动零时表/外部变量中数据后再全部插入SC表。

前一个方法(屏蔽改动再恢复)比較简单。下面进一步解说步骤:

  1. 我们须要改动下面SC表中外键声明,加入外键约束的名字,以方便我们兴许屏蔽和恢复外键约束:
create table SC (
S# integer,
C# integer,
score integer,
constraint sidfk foreign key (S#) references Student(S#) on delete cascade,
constraint cidfk foreign key (C#) references Course(C#) on delete cascade
);

这里两个外键分别命名为sidfk和cidfk。

2. 屏蔽和开启外键约束:

用SQL alter table语句实现屏蔽和开启。设S#_new是新学号,S#_old是老学号:

alter table SC disable constraint sidfk;
update Student set S# = S#_new where S# = S#_old;
update SC set S# = S#_new where S# = S#_old;
alter table SC enable constraint sidfk;

3.在Oracle上用存储过程实现

因为Oracle存储过程中不能直接使用create table或者alter table一类改动表结构的语句。需用execute immediate + SQL Command动态调用。

完整的存储步骤例如以下:

create or replace procedure ChangeStuId(S#_old in integer, S#_new in integer)
as
begin
execute immediate 'alter table SC disable constraint sidfk';
update Student set S# = S#_new where S# = S#_old;
update SC set S# = S#_new where S# = S#_old;
execute immediate 'alter table SC enable constraint sidfk';
end;

Oracle存储过程update受外键约束的主键值时完整性冲突解决方式的更多相关文章

  1. Oracle数据库,非空约束、主键约束、外键约束、唯一约束

    非空约束:设置列时,可为空默认可为空,去掉对号之后设置数据不可为空: 唯一约束:在键中设置,唯一约束名称.类型Unique.列名:设置应用完成之后,此列数据具有唯一性:即数据不可重复(类型:Uniqu ...

  2. 获取oracle 表字段,表名,以及主键之类等等的信息

    数据库版本号:select * from v$version 数据库名:select * from v$instance 注意: 我在C#项目中查询语句的时候报“ORA-00911: 无效字符” 的错 ...

  3. 获取oracle 表字段,表名,以及主键之类等等的信息。

    获取表名:  Oracle的user_talbes用于记录了用户表信息. select * from user_tables  获取某个表的字段: USER_TAB_COLS中记录了用户表的列信息.下 ...

  4. (2.10)Mysql之SQL基础——约束及主键重复处理

    (2.10)Mysql之SQL基础——约束及主键重复处理 关键词:mysql约束,批量插入数据主键冲突 [1]查看索引: show index from table_name; [2]查看有约束的列: ...

  5. sql insert、update、delete完以后返回主键ID

    以前只用过在insert完以后利用select @@IDENTITY返回主键ID,最近在做微信公众平台,遇到一个需求是在帮绑定万微信openid后自动完成登陆,这就需要update以后返回主键ID,查 ...

  6. Oracle使用游标为所有用户表添加主键语句

    应用场合:数据表新增自增一主键能加快数据表的访问速度,而且是整形的索引速度最快.本程序适合在导入Oracle数据库时删除不存在主键的情况下运行. 代码说明:所有的表主键字段名都设置为ID,如果已存在I ...

  7. oracle中查看一张表是否有主键,主键在哪个字段上

    利用Oracle中系统自带的两个视图可以实现查看表中主键信息,语句如下:select a.constraint_name, a.column_name from user_cons_columns a ...

  8. sqlite里执行查询提示未启用约束、主键冲突之——数据竟能超字段长度存储

    数据表设计如图:szflbm为主键 数据表主键数据: 以上数据在查询时,执行到该语句adapter.Fill(table); 提示主键冲突. 解决: 1.尝试修改数据,把ZC1改成ZZ,正常.说明原因 ...

  9. Oracle 主键、联合主键的查询与创建

    --查询某个表是否有唯一主键 select cu.* from user_cons_columns cu, user_constraints au where cu.constraint_name = ...

随机推荐

  1. NSPredicate用法总结(Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取)

    简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...

  2. linux 101 hacks 3null 改文件大小写 xargs

    禁止标准输出和错误信息的输出 当我们调试 shell 脚本的时候,我们往往不希望看到标准输出和标准错误的信息.我们可以使用/dev/nulll 来禁止标准错误的信息. 将标准输出重定向到/dev/nu ...

  3. CentOS 升级Python3.X和pip3

    目的:实现python3 and python2 共存,pip2 and pip3共存 一.安装依赖 yum install openssl-devel -y yum install zlib-dev ...

  4. 新一代数据库TiDB在美团的实践

    1. 背景和现状 近几年,基于MySQL构建的传统关系型数据库服务,已经很难支撑美团业务的爆发式增长,这就促使我们去探索更合理的数据存储方案和实践新的运维方式.而随着分布式数据库大放异彩,美团DBA团 ...

  5. OpenGL 笔记<3> 数据传递 一

    Sending data to a shader using vertex attributes and vertex buffer object 上次我们说到着色器的编译和连接,后面的事情没有做过多 ...

  6. python opencv3 cornerHarris 角点检测

    git:https://github.com/linyi0604/Computer-Vision 角点也是处在一个无论框框往哪边移动 框框内像素值都会变化很大的情况而定下来的点 如果框框水平方向上移动 ...

  7. django中日志配置

    # ======日志配置====== # 错误优先级:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL # Djang ...

  8. 下载 ....aar jitpack.io 打不开。

    下载 ....aar aar 是 安卓的 打包. 相对与jar 就是可以打包android的资源 比如res下的 . ------ jitpack.io  打不开. ====== 这个是jcenter ...

  9. 洛谷.4238.[模板]多项式求逆(NTT)

    题目链接 设多项式\(f(x)\)在模\(x^n\)下的逆元为\(g(x)\) \[f(x)g(x)\equiv 1\ (mod\ x^n)\] \[f(x)g(x)-1\equiv 0\ (mod\ ...

  10. VC 操作 EXCEL---插入工作表(Insert.Sheet)方法

    看到的资料 http://bbs.csdn.net/topics/198565 自己总结一下 //插入到nIndex工作表之前 void InsertSheet(int nIndex) { sheet ...