首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 同表跨列更新進階技巧:以 ME_TITLE 模式匹配同步資料

     編輯:DB2 教學

實務上常需在同一張表內,依據某欄位模式匹配,將符合條件的記錄以另一筆記錄的資料覆蓋更新。本文實例展示如何處理 metadata_xt 表中 me_title 為 '第__講 精簡版' 的記錄,找出同組(other_courseware_name 相同)且標題前綴相符的「源記錄」,同步更新欄位並重組標題。

資料結構與需求

metadata_xt(id, subject_id, other_courseware_name, me_author, me_title, me_key, me_abstract)
-- id 唯一,me_title 應唯一但無約束(可能重複,重複時其他欄位必定相同視為冗餘)

匹配模式:

  • 目標記錄:me_title LIKE '第__講 精簡版'(雙位數講次)
  • 源記錄:me_title LIKE '第%' 且 不含 '精簡版'
  • 匹配規則:前 6 字元相同(如 '第01講'、'第55講'),或源記錄為單位數格式 '第_講%' 時,比對第 3 字元為 '0' 且第 4-6 字元相符

兩階段更新策略

先更新非關鍵欄位,再更新關鍵欄位 me_title,避免匹配條件失效。

階段 1:更新非關鍵欄位

UPDATE DB2ADMIN.metadata_xt AS a
   SET (me_key, me_abstract, subject_id, me_author) =
       (SELECT DISTINCT me_key, me_abstract, subject_id, me_author
          FROM DB2ADMIN.metadata_xt AS b
         WHERE other_courseware_name = '房屋建築學'
           AND b.me_title LIKE '第%'
           AND ( LEFT(b.me_title, 6) = LEFT(a.me_title, 6)
              OR ( SUBSTR(a.me_title, 3, 1) = '0' 
                   AND SUBSTR(a.me_title, 4, 3) = SUBSTR(b.me_title, 3, 3) )
           )
           AND b.me_title <> a.me_title)
 WHERE other_courseware_name = '房屋建築學'
   AND me_title LIKE '第__講 精簡版'
   AND EXISTS (
       SELECT 1 FROM DB2ADMIN.metadata_xt AS c
        WHERE c.other_courseware_name = '房屋建築學'
          AND c.me_title LIKE '第%'
          AND ( LEFT(c.me_title, 6) = LEFT(a.me_title, 6)
             OR ( SUBSTR(a.me_title, 3, 1) = '0' 
                  AND SUBSTR(a.me_title, 4, 3) = SUBSTR(c.me_title, 3, 3) )
          )
          AND c.me_title <> a.me_title
   );

關鍵技巧:

  • SET (col1, col2, ...) = (SELECT ...):DB2 支援單一子查詢同時賦值多欄位
  • DISTINCT 確保子查詢只回傳單列,避免「單列子查詢回傳多列」錯誤
  • EXISTS 子句:防止無匹配源記錄時將目標欄位設為 NULL
  • LEFT()、SUBSTR() 組合實現彈性前綴匹配

階段 2:更新關鍵欄位 ME_TITLE

UPDATE DB2ADMIN.metadata_xt AS a
   SET me_title =
       (SELECT DISTINCT me_title
          FROM DB2ADMIN.metadata_xt AS b
         WHERE other_courseware_name = '房屋建築學'
           AND b.me_title LIKE '第%'
           AND ( LEFT(b.me_title, 6) = LEFT(a.me_title, 6)
              OR ( SUBSTR(a.me_title, 3, 1) = '0' 
                   AND SUBSTR(a.me_title, 4, 3) = SUBSTR(b.me_title, 3, 3) )
           )
           AND b.me_title <> a.me_title) || ' (精簡版)'
 WHERE other_courseware_name = '房屋建築學'
   AND me_title LIKE '第__講 精簡版'
   AND EXISTS (
       SELECT 1 FROM DB2ADMIN.metadata_xt AS c
        WHERE c.other_courseware_name = '房屋建築學'
          AND c.me_title LIKE '第%'
          AND ( LEFT(c.me_title, 6) = LEFT(a.me_title, 6)
             OR ( SUBSTR(a.me_title, 3, 1) = '0' 
                  AND SUBSTR(a.me_title, 4, 3) = SUBSTR(c.me_title, 3, 3) )
          )
          AND c.me_title <> a.me_title
   );

更新後 me_title = 源記錄標題 + ' (精簡版)',其他欄位同步為源記錄值。

避坑指南

  • 分兩階段更新,避免第一階段修改 me_title 導致第二階段匹配失敗
  • 必須加 EXISTS 保護,否則無匹配源記錄時會寫入 NULL
  • DISTINCT 配合 b.me_title <> a.me_title 確保不自我匹配且唯一
  • 大量資料建議分批處理(加 FETCH FIRST N ROWS ONLY)避免長鎖定
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved