【ORACLE】記錄一些ORACLE的merge into語句的BUG

【ORACLE】記錄一些ORACLE的merge into語句的BUG

一、自相矛盾-DML重啟動行為差異,違反acid原則

發現版本:10g ~ 23ai
這個用例在我之前的文章里有提過,ORACLE和PG系關于并發事務行為有一個非常大的差異,就是ORACLE在某些并發沖突的場景下會進行DML重啟動,但是對比下面兩個例子,可以發現無論采取何種事務一致性實現邏輯,在read commit下,最終的結果無外乎得到(1,‘Alice’)、(10,‘Alice’)、(1,‘Tom’)三種其一,但ORACLE的merge into 卻得到了(10,‘Tom’)這一理論不應該存在的記錄。
用例一:

drop table test_dml_restart;create table test_dml_restart(id number ,name varchar2(10));
insert into test_dml_restart values (1,'Alice');
commit;--會話一,執行后不提交
update test_dml_restart set id=10 where name='Alice';--會話二執行,被鎖
update test_dml_restart set name='Tom' where id=1;--會話一提交,會話二自動解鎖,更新0行,會話2根據id=1進行了重啟動,找不到id=1的記錄
commit;--會話二查詢
select * from test_dml_restart;10,Alice

用例二:

drop table test_dml_restart;create table test_dml_restart(id number ,name varchar2(10));
insert into test_dml_restart values (1,'Alice');
commit;--會話一,執行后不提交
update test_dml_restart set id=10 where name='Alice';--會話二執行,被鎖
merge into test_dml_restart t1
using (select * from dual) t2
on (t1.id=1)
when matched then 
update set t1.name='Tom';--會話一提交,會話二自動解鎖,更新1行,會話2仍然按舊的id找到了數據進行更新
commit;--會話二查詢
select * from test_dml_restart;10,Tom

在asktom上也有人發現過,但從10g到目前最新的23ai,這個問題一直未修復
https://asktom.oracle.com/ords/f?p=100:11:::NO::P11_QUESTION_ID:61865893444475

merge and write consistency
Andrey N. Edemsky, May 04, 2006 - 3:51 pm UTC

其實這個問題在ORACLE里通過改寫SQL規避,就是把on里的條件,復制一份到update后面的where里

merge into test_dml_restart t1
using (select * from dual) t2
on (t1.id=1)
when matched then 
update set t1.name='Tom' where t1.id=1;

二、百密一疏-觸發ORA600的外關聯

發現版本:11g 12c 18c 19c

 create table test1 (col1 number,col2 number);create table test2 (col1 number,col2 number);insert into test1 values (1,1);merge into test2
using test1 on (test1.col1=test2.col1(+))
when matched thenupdate set test2.col2=test1.col2;ORA-00600: 內部錯誤代碼, 參數: [25027], [3], [3], [0], [0], [0], [1], [1], [], [], [], []

雖然這個sql本身的確不對,但是ORACLE報錯卻是ORA-600這個ORACLE自己沒有估計到的報錯。
19.20及最新的23ai版本已修復這個問題,在23ai中該SQL執行結果是merge 0行。

三、自欺欺人-不能更新on中引用的列

版本:9i ~ 23ai

詳見這篇 【ORACLE】你以為的真的是你以為的么?–ORA-38104: Columns referenced in the ON Clause cannot be updated

這個是個ORACLE故意做的限制,本身可以說不算BUG,但是通過特殊方式能繞過這個限制,就可以算個BUG了。所以ORACLE要么承認這個設計是BUG,要么承認開發遺漏了場景也還是BUG,總歸有一邊是BUG。

merge into test_merge_a a
using test_merge_b b
on (a.id=b.id)
when matched thenupdate set id=2;ORA-38104: 無法更新 ON 子句中引用的列: "A"."ID"--改寫
merge into test_merge_a a
using test_merge_b b
on ((a.id=b.id or 1=2) and (a.id=b.id or 1=2 ))
when matched thenupdate set a.id=2;Plan Hash Value  : 4101543598 --------------------------------------------------------------------------------
| Id  | Operation              | Name         | Rows | Bytes | Cost | Time     |
--------------------------------------------------------------------------------
|   0 | MERGE STATEMENT        |              |    1 |    13 |    4 | 00:00:01 |
|   1 |   MERGE                | TEST_MERGE_A |      |       |      |          |
|   2 |    VIEW                |              |      |       |      |          |
| * 3 |     HASH JOIN          |              |    1 |    76 |    4 | 00:00:01 |
|   4 |      TABLE ACCESS FULL | TEST_MERGE_B |    1 |    32 |    2 | 00:00:01 |
|   5 |      TABLE ACCESS FULL | TEST_MERGE_A |    1 |    44 |    2 | 00:00:01 |
--------------------------------------------------------------------------------Predicate Information (identified by operation id):
------------------------------------------
* 3 - access("A"."ID"="B"."ID")

以上是較新版本中需要注意一些問題。

在早期版本中已經修復過的就不全部列舉了,MOS上搜merge into的BUG大把大把的,翻了N頁沒見底,什么更新視圖、分區表、并行、并發、行歸檔、dblink、壓縮表等等有一堆功能和merge into組合使用有問題的,這里只寫幾個簡單的merge into語句有問題的場景

四、無中生有-源數據為空的結果集也能匹配上

版本:11.2.0.2.0
https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:9537112000346374938
https://asktom.oracle.com/ords/f?p=100:11:::NO::P11_QUESTION_ID:61865893444475

Same guy - Correction
GPU, August 26, 2013 - 5:11 pm UTC

create table test_merge_null(col1 varchar2(20) not null);MERGE INTO test_merge_null
USING (SELECT dummy
FROM DUAL
WHERE 1 = 2) s
ON (1 = 2)
WHEN NOT MATCHED
THEN
INSERT (col1)
VALUES (s.dummy);

這是11.2.0.2.0 中的 bug,已在 11.2.0.3.0 中修復。還好,11.2.0.2.0這個版本用得少。

五、一山能容二虎-突破主鍵唯一限制

發現版本:10.2.0.1.0
通過direct path write,能突破主鍵限制進行插入,使表中數據違反有效的唯一約束,案例來自:
https://blog.csdn.net/jackpk/article/details/3788143

create table KL_TEST
(a           NUMBER(15) not null,b           NUMBER(15) not null,c           NUMBER(15) not null,d           NUMBER(15) not null,e           NUMBER(15) not null,f           NUMBER(15) not null
);10   ;Table created.alter table KL_TESTadd constraint KL_TEST_PK primary key (A, B, C, D)3      ;Table altered.CREATE TABLE KL_TEST_1 NOLOGGING PCTFREE 0 ASSELECT * FROM KL_TEST3   WHERE 1=2;Table created.SYS@ora10g> INSERT INTO KL_TEST_1 VALUES (1,1,1,1,1,1);1 row created.SYS@ora10g> INSERT INTO KL_TEST_1 VALUES (1,2,1,2,1,2);1 row created.SYS@ora10g> INSERT INTO KL_TEST_1 VALUES (1,1,1,1,1,1);1 row created.SYS@ora10g> commit;Commit complete.MERGE /*+ APPEND */ INTO KL_TEST trgt
USING
(select fct.a,fct.b,fct.c,fct.d,fct.e,fct.f from KL_TEST_1 fct) tmp
ON
(tmp.a = trgt.aand tmp.b = trgt.band tmp.c = trgt.cand tmp.d = trgt.dand tmp.e = trgt.eand tmp.f = trgt.f)WHEN NOT MATCHED THENINSERT (a,b,c,d,e,f)13   VALUES (tmp.a,tmp.b,tmp.c,tmp.d,tmp.e,tmp.f);3 rows merged.SYS@ora10g>  commit;Commit complete.SYS@ora10g> SELECT COUNT(*) FROM KL_TEST;COUNT(*)
----------0SYS@ora10g> SELECT /*+ FULL (KL_TEST)*/ COUNT(*) FROM KL_TEST;COUNT(*)
----------3SYS@ora10g> select * from kl_test;A          B          C          D          E          F
---------- ---------- ---------- ---------- ---------- ----------1          1          1          1          1          11          1          1          1          1          11          2          1          2          1          2SYS@ora10g> select CONSTRAINT_NAME,CONSTRAINT_TYPE, STATUS from dba_constraints where table_name ='KL_TEST';CONSTRAINT_NAME                C STATUS
------------------------------ - --------
SYS_C005398                    C ENABLED
SYS_C005397                    C ENABLED
SYS_C005396                    C ENABLED
SYS_C005395                    C ENABLED
SYS_C005394                    C ENABLED
SYS_C005393                    C ENABLED
KL_TEST_PK                     P ENABLED7 rows selected.SYS@ora10g> insert into kl_test values (1,1,1,1,1,1);1 row created.SYS@ora10g> select * from kl_test;A          B          C          D          E          F
---------- ---------- ---------- ---------- ---------- ----------1          1          1          1          1          11          1          1          1          1          11          2          1          2          1          21          1          1          1          1          1

在10.2.0.5.0和11.2.0.4版本中已經沒這個問題了

總結

ORACLE從很早的版本就增加了merge into這一語法,雖然給開發人員帶來了很大的便利性,但是其BUG數之多非常恐怖,很多BUG從發現到修復跨越了數十年的好幾個大版本,甚至還有些BUG一直延續到了最新的23ai版本。國產數據庫的開發人員遠沒有ORACLE那么多,ORACLE都做成這樣了,國產數據庫要是說merge into里沒有BUG我是不相信的。

  • 本文作者: DarkAthena
  • 本文鏈接: https://www.darkathena.top/archives/oracle-merge-into-some-bug
  • 版權聲明: 本博客所有文章除特別聲明外,均采用CC BY-NC-SA 3.0 許可協議。轉載請注明出處

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902772.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902772.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902772.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025上海車展:光峰科技全球首發“靈境”智能車載光學系統

當AI為光賦予思想,汽車將會變成什么樣?深圳光峰科技為您揭曉答案。 2025年4月23日,在剛剛開幕的“2025上海車展”上,全球領先的激光核心器件公司光峰科技舉辦了主題為“AI光影盛宴,智享未來出行”的媒體發布會&#x…

密碼學的hash函數,哈希碰撞, collision resistance, BTC用到的SHA-256簡介

密碼學中的哈希函數、哈希碰撞、抗碰撞性(collision resistance)以及比特幣中使用的 SHA-256 的簡明介紹: 🧩 一、哈希函數(Hash Function) 定義: 哈希函數是一種將任意長度的輸入(…

unity TEngine學習4

上一篇我們學習了UI部分,這一篇我們學習其他部分,按照老規矩還是先打開官方文檔 ResourceModule 在官方文檔里介紹了當前加載的設置,但是我們是小白看不懂,那就不管他內部怎么實現的,我們主要看下面的代碼給的方法&am…

【AI訓練環境搭建】在IDE(Pycharm或VSCode)上使用WSL2+Ubuntu22.04+Conda+Tensorflow+GPU進行機器學習訓練

本次實踐將在IDE(Pycharm或VSCode)上使用WSL2Ubuntu22.04TensorflowGPU進行機器學習訓練。基本原理是在IDE中拉起WSL2中的Python解釋器,并運行Python程序。要運行CondaTensorflowGPU你可能需要進行以下準備工作。 1. 此示例中將使用一個mnis…

【華為OD機試真題E卷】521、 機器人可活動的最大網格點數目 | 機試真題+思路參考+代碼解析(E卷復用)(C++)

文章目錄 一、題目題目描述輸入輸出樣例1 一、代碼與思路🧠C語言思路?C代碼 一、題目 參考鏈接:https://sars2025.blog.csdn.net/article/details/141748083 題目描述 現有一個機器人口,可放置于MxN的網格中任意位置,每個網格包…

windows端遠程控制ubuntu運行腳本程序并轉發ubuntu端腳本輸出的網頁

背景 對于一些只能在ubuntu上運行的腳本,并且這個腳本會在ubuntu上通過網頁展示運行結果。我們希望可以使用windows遠程操控ubuntu,在windows上查看網頁內容。 方法 start cmd.exe /k "sshpass -p passwd ssh namexxx.xxx.xxx.xxx "cd /hom…

Vue3集成瀏覽器API實時語音識別

效果示例 用法 <!-- 瀏覽器語音識別 --> <BrowserSpeechRecognitionModal v-if"showModal" :isOpen"showModal" close"showModal false" confirm"handleRecognitionResult" />const showModal ref(false); const input…

k8s 手動續訂證書

注意:如果是高可用環境,本文的操作需要在所有控制節點都執行。 查看證書是否過期 kubeadm certs check-expirationkubeadm certs renew可以續訂任何特定證書,或者使用子命令all可以續訂所有證書: kubeadm certs renew all使用 kubeadm 構建的集群通常會將admin.conf證書復…

每日一道leetcode(補充版)

1679. K 和數對的最大數目 - 力扣&#xff08;LeetCode&#xff09; 題目 給你一個整數數組 nums 和一個整數 k 。 每一步操作中&#xff0c;你需要從數組中選出和為 k 的兩個整數&#xff0c;并將它們移出數組。 返回你可以對數組執行的最大操作數。 示例 1&#xff1a; …

基于Keras3.x使用CNN實現簡單的貓狗分類

使用CNN實現簡單的貓狗分類 完整代碼見&#xff1a;基于Keras3.x使用CNN實現簡單的貓狗分類&#xff0c;置信度約為&#xff1a;85% 文章目錄 概述項目整體目錄環境版本注意 環境準備下載miniconda新建虛擬環境基于conda虛擬環境新建Pycharm項目下載分類需要用到的依賴 數據準備…

中介者模式:解耦對象間復雜交互的設計模式

中介者模式&#xff1a;解耦對象間復雜交互的設計模式 一、模式核心&#xff1a;用中介者統一管理對象交互&#xff0c;避免兩兩直接依賴 當系統中多個對象之間存在復雜的網狀交互時&#xff08;如 GUI 界面中按鈕、文本框、下拉框的聯動&#xff09;&#xff0c;對象間直接調…

豆包桌面版 1.47.4 可做瀏覽器,免安裝綠色版

自己動手升級更新辦法&#xff1a; 下載新版本后安裝&#xff0c;把 C:\Users\用戶名\AppData\Local\Doubao\Application 文件夾的文件&#xff0c;拷貝替換 DoubaoPortable\App\Doubao 文件夾的文件&#xff0c;就升級成功了。 再把安裝的豆包徹底卸載就可以。 桌面版比網頁版…

Android PackageManagerService(PMS)框架深度解析

目錄 一、概念與核心作用 二、技術架構與模塊組成 1. 分層架構 1.1 應用層架構細節 1.2 Binder接口層實現 1.3 PMS核心服務層 1.4 底層支持層實現 2. 核心模塊技術要點與工作流程 2.1 PackageParser 2.2 Settings 2.3 PermissionManager 2.4 Installer 2.5 ComponentM…

TensorFlow深度學習實戰(14)——循環神經網絡詳解

TensorFlow深度學習實戰(14)——循環神經網絡詳解 0. 前言1. 基本循環神經網絡單元1.1 循環神經網絡工作原理1.2 時間反向傳播1.3 梯度消失和梯度爆炸問題2. RNN 單元變體2.1 長短期記憶2.2 門控循環單元2.3 Peephole LSTM3. RNN 變體3.1 雙向 RNN3.2 狀態 RNN4. RNN 拓撲結構…

PySide6 GUI 學習筆記——常用類及控件使用方法(常用類矩陣QRectF)

文章目錄 類描述構造方法主要方法1. 基礎屬性2. 邊界操作3. 幾何運算4. 坐標調整5. 轉換方法6. 狀態判斷 類特點總結1. 浮點精度&#xff1a;2. 坐標系統&#xff1a;3. 有效性判斷&#xff1a;4. 幾何運算&#xff1a;5. 類型轉換&#xff1a;6. 特殊處理&#xff1a; 典型應用…

Electron主進程渲染進程間通信的方式

在 Electron 中&#xff0c;主進程和渲染進程之間的通信主要通過 IPC&#xff08;進程間通信&#xff09;機制實現。以下是幾種常見的通信方式&#xff1a; 1. 渲染進程向主進程發送消息&#xff08;單向&#xff09; 渲染進程可以通過 ipcRenderer.send 向主進程發送消息&am…

【C++基礎知識】C++類型特征組合:`disjunction_v` 和 `conjunction_v` 深度解析

這兩個模板是C17引入的類型特征組合工具&#xff0c;用于構建更復雜的類型判斷邏輯。下面我將從技術實現到實際應用進行全面剖析&#xff1a; 一、基本概念與C引入版本 1. std::disjunction_v (邏輯OR) 引入版本&#xff1a;C17功能&#xff1a;對多個類型特征進行邏輯或運算…

私有知識庫 Coco AI 實戰(二):攝入 MongoDB 數據

在之前的文章中&#xff0c;我們介紹過如何使用《 Logstash 遷移 MongoDB 數據到 Easyseach》&#xff0c;既然 Coco AI 后臺數據存儲也使用 Easysearch&#xff0c;我們能否直接把 MongoDB 的數據遷移到 Coco AI 的 Easysearch&#xff0c;使用 Coco AI 對數據進行檢索呢&…

sql server 與navicat測試后,連接qt

先用Navicat測試和sql的連通性&#xff0c;Navicat和sql連通之后&#xff0c;qt也能和sql連通了。 Navicat和Sqlserver Management 能連上&#xff0c;項目無法連接本地 Navicat 連接SQLServer 數據庫 QT國內鏡像網站 Navicat連接SqlServer的問題點 Sql Server的基本配置以及使…

2025年3月電子學會青少年機器人技術(六級)等級考試試卷-理論綜合

青少年機器人技術等級考試理論綜合試卷&#xff08;六級&#xff09; 分數&#xff1a;100 題數&#xff1a;30 一、單選題(共20題&#xff0c;共80分) 1. 2025年初&#xff0c;中國科技初創公司深度求索在大模型領域迅速崛起&#xff0c;其開源的大模型成為全球AI領域的焦…