`

ORA-1779错误

阅读更多

在对子查询执行UPDATE时,可能会遇到ORA-1779错误,这里简单讨论一下。

 

 

首先构造两个表:

SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30), DOC VARCHAR2(30));

表已创建。

SQL> CREATE TABLE T2 (ID NUMBER PRIMARY KEY, FID NUMBER, NAME VARCHAR2(30), DOC VARCHAR2(30));

表已创建。

SQL> INSERT INTO T1 VALUES (1, 'A', 'TEST1');

已创建 1 行。

SQL> INSERT INTO T1 VALUES (2, 'B', 'TEST2');

已创建 1 行。

SQL> INSERT INTO T1 VALUES (3, 'C', 'TEST3');

已创建 1 行。

SQL> INSERT INTO T2 VALUES (1, 1, 'A', 'TESTA');

已创建 1 行。

SQL> INSERT INTO T2 VALUES (2, 2, 'B', 'TESTB');

已创建 1 行。

SQL> INSERT INTO T2 VALUES (3, 3, 'C', 'TESTC');

已创建 1 行。

SQL> INSERT INTO T2 VALUES (4, NULL, 'A', 'TESTD');

已创建 1 行。

SQL> COMMIT;

提交完成。

经常有需求会根据一张表的记录更新另一张表上对于记录的字段,一般这个SQL如下所示:

SQL> UPDATE T2 SET DOC = (SELECT DOC FROM T1 WHERE ID = T2.FID)
2 WHERE EXISTS (SELECT 1 FROM T1 WHERE ID = T2.FID);

已更新3行。

SQL> SELECT * FROM T2;

ID FID NAME DOC
---------- ---------- ------------------------------ ---------------------
1 1 A TEST1
2 2 B TEST2
3 3 C TEST3
4 A TESTD

SQL> ROLLBACK;

回退已完成。

其中WHERE条件是为了避免将连接中匹配不到的记录更新为NULL。

与此等价的有另外一种写法,直接对子查询进行更新:

SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.ID = T2.FID)
2 SET DOC_2 = DOC_1;

已更新3行。

SQL> SELECT * FROM T2;

ID FID NAME DOC
---------- ---------- ------------------------------ ---------------------------
1 1 A TEST1
2 2 B TEST2
3 3 C TEST3
4 A TESTD

SQL> ROLLBACK;

回退已完成。

采用这种方式,SQL显得更加简洁。

不过这种方式使用不当就会造成ORA-1779错误:

SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.ID = T2.FID)
2 SET DOC_1 = DOC_2;
SET DOC_1 = DOC_2
*第 2 行出现错误:
ORA-01779: 无法修改与非键值保存表对应的列

造成这个错误的原因是更新的列不是事实表的列,而是维度表的列。换句话说,如果两张表关联,其中一张表的关联列是主键,那么另一张表就是事实表,也就是说另一张表中的列就是可更新的;除非另一张表的关联列也是主键,否则这张表就是不可更新的,如果更新语句涉及到了这张表,就会出现ORA-1799错误。

如果是两张表主键关联,那么无论更新那个表的字段都可以:

SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.ID = T2.ID)
2 SET DOC_1 = DOC_2;

已更新3行。

SQL> ROLLBACK;

回退已完成。

SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.ID = T2.ID)
2 SET DOC_2 = DOC_1;

已更新3行。

SQL> ROLLBACK;

回退已完成。

如果两张表都不包含主键,那么无论更新那张表的字段都会报错:

SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.NAME = T2.NAME)
2 SET DOC_1 = DOC_2;
SET DOC_1 = DOC_2
*第 2 行出现错误:
ORA-01779: 无法修改与非键值保存表对应的列


SQL> UPDATE (SELECT T1.DOC DOC_1, T2.DOC DOC_2 FROM T1, T2 WHERE T1.NAME = T2.NAME)
2 SET DOC_2 = DOC_1;
SET DOC_2 = DOC_1
*第 2 行出现错误:
ORA-01779: 无法修改与非键值保存表对应的列

其实这个限制的真正原因是Oracle要确保连接后更新的内容可以写到一张表中,而这就要求连接方式必须是1对N或者1对1的连接。这样才能确保连接后的结果集数量和事实表一致。从而使得Oracle对连接后子查询的更新可以顺利的更新到事实表中。

分享到:
评论

相关推荐

    ora-00604错误解决方法

    ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法ora-00604 错误 解决 方法

    Oracle数据库发生ORA-04031错误原因浅析及处理.pdf

    Oracle数据库发生ORA-04031错误原因浅析及处理 Oracle数据库是甲骨文公司提供的一种分布式数据库管理系统,以分布式数据库为核心的软件产品。它具有完整的数据管理功能,作为一个关系数据库,它是一个非常实用的...

    使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查

    在使用Oracle Data Pump工具IMPDP(Import Data Pump)进行数据导入的过程中,可能会遇到ORA-39002和ORA-39070等错误。本文将针对这些错误的排查方法进行详细介绍,帮助用户理解问题的原因及解决策略。 ### 错误...

    Oracle 10g启动后报ORA-16038错误的解决方法

    ### Oracle 10g启动后报ORA-16038错误的解决方法 #### 错误概述 在启动Oracle 10g数据库时遇到ORA-16038错误,该错误通常与归档日志操作有关。具体错误信息为: ``` ORA-16038: log 1 sequence #230 cannot be ...

    ora-01460 错误原因分析

    ### ORA-01460 错误原因分析 #### 概述 在Oracle数据库操作过程中,可能会遇到ORA-01460错误,该错误全称为“ORA-01460: 转换请求无法实现或不合理”。这一错误通常发生在数据类型转换或者与操作系统之间的数据...

    创建物化视图ORA-12014错误解决方法

    ### 创建物化视图ORA-12014错误解决方法 #### 背景介绍 在Oracle数据库中,物化视图(Materialized View)是一种用于优化查询性能的重要工具。它预先计算并存储了复杂的查询结果,从而在实际查询时能够快速地返回...

    ORACLE ORA-00132 ORA-00214

    ### Oracle 错误 ORA-00132 和 ORA-00214 解析及处理 #### 一、错误概述 在Oracle数据库管理过程中,遇到ORA-00132和ORA-00214这类错误时,往往意味着数据库配置或启动过程中出现了问题。下面将对这两个错误进行...

    如何处理错误ORA-29275:部分多字节字符

    ### 如何处理错误ORA-29275:部分多字节字符 #### 问题背景与描述 在Oracle数据库操作过程中,用户可能会遇到一个特定的错误提示——ORA-29275:部分多字节字符。这一错误通常出现在执行查询`SELECT * FROM V$...

    Oracle 11gr2连Oracle 19c 报ORA-28040 ORA-01017解决方法.pdf

    Oracle数据库不同版本间的客户端与服务端的连接问题通常涉及到安全和兼容性配置,这篇文章主要讲述了在Oracle 11g R2客户端尝试连接Oracle 19c服务端时,遇到了两个特定的错误:ORA-28040和ORA-01017,以及如何解决...

    oracle ora-03113错误

    ### Oracle ORA-03113 错误解析及解决方法 #### 一、ORA-03113 错误概述 ORA-03113 是一个较为常见的Oracle错误,通常出现在网络通信出现问题时,具体表现为“end-of-file on communication channel”(通信通道上...

    数据库ORA-01460错误的解决方法

    在IT领域,尤其是在数据库管理与维护中,遇到ORA-01460错误是常见的问题之一,这通常意味着系统在尝试执行数据转换时遇到了未实现或不合理的请求。本文将深入探讨ORA-01460错误的成因、影响以及提供一系列有效的解决...

    关于WIN10系统配置了环境变量后oracle instant client后依然提示ORA-01019错误的解决方案

    关于WIN10系统使用oracle instant client 时候提示ORA-01019错误的解决方案,本方案是配置好环境变量后依然提示ORA-01019错误的解决方案,内附本人制作测试的全过程说明

    离线误删空间文件导致的ORA-01033及ORA-01145问题的解决办法

    这些问题可能会导致数据库启动时出现ORA-01033错误(数据库无法完成启动过程),以及在尝试修复过程中可能遇到的ORA-01145错误(除非启用了介质恢复,否则不允许立即脱机)。本文将详细介绍这两种错误的原因、可能的...

    Drop goldengate用户时报ORA-00604 ORA-20782 ORA-06512问题解决

    `命令时,可能会遭遇ORA-00604、ORA-20782以及ORA-06512等错误。这些错误通常是因为Goldengate用户在安装Oracle GoldenGate (OGG) 时配置了DDL捕获功能。 #### 二、错误分析及处理步骤 **1. 错误现象** 执行`drop ...

    ORA-04052p5731178_92080_WINNT.zip

    ORA-00604: 递归SQL层1出现错误 ORA-03106: 致命的双工通信协议错误 ORA-02063: 紧接着line(源于dblink) 以及 ORA-04052: 在查找远程对象时出错 ORA-00604: 递归SQL层1出现错误 ORA-03120: 双工转换例行程序:整数...

    关于创建oracle 连接时报以下错误,ORA-01017 ORA-02063

    在创建Oracle数据库连接时遇到的错误ORA-01017和ORA-02063涉及到用户认证问题以及Oracle数据库版本之间的差异处理。ORA-01017错误表示用户名或密码无效,登录被拒绝,而ORA-02063则通常表示在Oracle数据库之间进行...

    ora-227101错误解决办法

    在Oracle数据库管理与维护的过程中,遇到各种错误代码是家常便饭,其中“ORA-227101”错误虽然在题目中被误标,实际案例中展示的是“ORA-27101”错误,这是一个较为常见的问题,通常发生在数据库服务未能正确启动或...

    ora-12514的错误的原因

    ORA-12514 错误的原因和解决方法 ORA-12514 错误是 Oracle 数据库中常见的一种错误,它的出现可能是由于多种原因引起的。下面我们将从根本上探究 ORA-12514 错误的原因,并提供相应的解决方法。 原因 1:监听器没有...

    ERwin连接oracle报ORA-01041内部错误,hostdef扩展名不存在.docx

    ### ERwin连接Oracle报ORA-01041内部错误,hostdef扩展名不存在的知识点解析 #### 一、问题背景及概述 在使用ERwin数据建模工具连接Oracle数据库时,可能会遇到ORA-01041内部错误提示:“hostdef扩展名不存在”。...

Global site tag (gtag.js) - Google Analytics