修复 SQL 中的错误

Ris*_*mit 1 oracle backup restore

在对我公司的问题进行故障排除时,我更新了表中的所有文件,而不是需要使用测试的特定文件。

create table _file_*date*_BAK as select * from _file;
update _file set category = 'null'; 
commit;
Run Code Online (Sandbox Code Playgroud)

尝试修复它时,我尝试从备份文件中提取,但出现错误

update (select a.category as OLD, b.category as NEW

 from _file a inner join _file_*date*_BAK b on a.filecod = b.filecod) t

 set t.old = t.new;
Run Code Online (Sandbox Code Playgroud)

错误报告 -

SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 -  "cannot modify a column which maps to a non key-preserved table"
*Cause:    An attempt was made to insert or update columns of a join view which
           map to a non-key-preserved table.
*Action:   Modify the underlying base tables directly.
Run Code Online (Sandbox Code Playgroud)

不知道为什么那个脚本不起作用。

任何帮助,将不胜感激

And*_*yer 5

错误是说 Oracle 有可能最终将同一行更新两次,因为_file_*date*_BAK.filecod.

简单的解决方案是在您的逻辑备份表上创建唯一索引:

Create unique index _file_*date*_bak_uix on _file_*date*_BAK (filecod);
Run Code Online (Sandbox Code Playgroud)

然后完全按照您已经编写的方式运行更新语句。

尽管从 Oracle 19.10 开始,此答案现在取决于版本。如果您打了足够的补丁,Oracle 将允许您执行此更新语句,并且只有在您的数据会导致单行被多次更新时才会失败。此行为当前需要通过修复控制手动启用,无论是在您的会话级别还是系统(与您的 DBA 交谈):

Alter session set "_fix_control"='19138896:1';
Run Code Online (Sandbox Code Playgroud)

我希望这将成为未来主要版本中的默认行为。