跳至內容
Astera Technology

資料表拷貝後為何開始收重複代碼?

先重建目標所需限制,才載入原有行。

下載完整個案資料及參考答案 ↓

先核來源與已訂規則

本例來源 code 定 NOT NULL、UNIQUE。CREATE TABLE target AS SELECT 會拷值,卻不帶這些限制。須先明建受限制目標,載行後再試真正重複寫入。

已填假設輸入
紀錄輸入 JSON
原例輸入{"source":["A"],"incoming":"A"}
下載可編輯 CSV ↓

比較兩條實際路徑

錯目標存兩行 A;更正第二 A 違 UNIQUE2067,首 A 仍留。試寫前行數相同,並查不出已丟保護。

錯誤與更正路徑的輸出
路徑輸出 JSON
錯誤路徑{"error":null,"records":[{"code":"A"},{"code":"A"}]}
更正路徑{"error":{"code":2067},"records":[{"code":"A"}]}
下載可編輯 CSV ↓
本地 Node.js 程序:22.23.3 或 24.14.1
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};

import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
    const db=new DatabaseSync(':memory:');try{db.exec('CREATE TABLE source(code TEXT NOT NULL UNIQUE);');
      for(const code of i.source)db.prepare('INSERT INTO source VALUES(?)').run(code);
      if(corrected)db.exec('CREATE TABLE target(code TEXT NOT NULL UNIQUE); INSERT INTO target SELECT code FROM source;');
      else db.exec('CREATE TABLE target AS SELECT * FROM source;');
      const error=failed(()=>db.prepare('INSERT INTO target VALUES(?)').run(i.incoming));
      return {error,records:rows(db,'SELECT code FROM target ORDER BY code')};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"source":["A"],"incoming":"A"},"expected":{"error":null,"records":[{"code":"A"},{"code":"A"}]},"corrected":false},{"label":"corrected base","input":{"source":["A"],"incoming":"A"},"expected":{"error":{"code":2067},"records":[{"code":"A"}]},"corrected":true},{"label":"new unique source value","input":{"source":["A"],"incoming":"B"},"expected":{"error":null,"records":[{"code":"A"},{"code":"B"}]},"corrected":true},{"label":"empty source table","input":{"source":[],"incoming":"A"},"expected":{"error":null,"records":[{"code":"A"}]},"corrected":true}];
for(const test of cases){
  const actual=run(test.input,test.corrected);
  assert.deepEqual(actual,test.expected,test.label);
  console.log(test.label,actual);
}
下載可執行例子 ↓

下次載入前核邊界

新 B 可與 A 並存;來源起初空,目標仍須有唯一限制。

可編輯邊界紀錄及預期輸出
情況輸入 JSON預期輸出 JSON
另一個新代碼{"source":["A"],"incoming":"B"}{"error":null,"records":[{"code":"A"},{"code":"B"}]}
空來源仍保目標限制{"source":[],"incoming":"A"}{"error":null,"records":[{"code":"A"}]}
下載可編輯 CSV ↓

已有行都拷齊,是否自動保住 UNIQUE?

查看參考答案

不會,CTAS 沒有帶上限制。須重建並驗第二 A 真正被拒。

相關資源