跳至內容
Astera Technology

父行在後,為何有效參考也令單次載入失敗?

先分配所有所附紀錄,再在同一交易連回參考。

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

先核來源與已訂規則

本例節點先 A→B,再根 B,目標是即時自外鍵。B 雖在完整輸入,寫 A 時尚未在目標。已准兩步路徑先建可空連結行,再改參考;完整交易才提交。

已填假設輸入
紀錄輸入 JSON
原例輸入{"nodes":[{"id":"A","parent":"B"},{"id":"B","parent":null}]}
下載可編輯 CSV ↓

比較兩條實際路徑

更正目標有 A→B 及根 B。若批次根本缺 B,後段 UPDATE 真會錯 787,回復也移除暫建行。

錯誤與更正路徑的輸出
路徑輸出 JSON
錯誤路徑{"error":{"code":787},"nodes":[]}
更正路徑{"error":null,"nodes":[{"id":"A","parent_id":"B"},{"id":"B","parent_id":null}]}
下載可編輯 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('PRAGMA foreign_keys=ON;CREATE TABLE node(id TEXT PRIMARY KEY,parent_id TEXT REFERENCES node(id));BEGIN;');
      const error=failed(()=>{for(const n of i.nodes)db.prepare('INSERT INTO node VALUES(?,?)').run(n.id,corrected?null:n.parent);
        if(corrected)for(const n of i.nodes)db.prepare('UPDATE node SET parent_id=? WHERE id=?').run(n.parent,n.id);
        db.exec('COMMIT;');});
      if(error)db.exec('ROLLBACK;');return {error,nodes:rows(db,'SELECT * FROM node ORDER BY id')};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"nodes":[{"id":"A","parent":"B"},{"id":"B","parent":null}]},"expected":{"error":{"code":787},"nodes":[]},"corrected":false},{"label":"corrected base","input":{"nodes":[{"id":"A","parent":"B"},{"id":"B","parent":null}]},"expected":{"error":null,"nodes":[{"id":"A","parent_id":"B"},{"id":"B","parent_id":null}]},"corrected":true},{"label":"missing later reference rolls back allocations","input":{"nodes":[{"id":"A","parent":"B"}]},"expected":{"error":{"code":787},"nodes":[]},"corrected":true},{"label":"independent root","input":{"nodes":[{"id":"A","parent":null}]},"expected":{"error":null,"nodes":[{"id":"A","parent_id":null}]},"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 可連 null 父提交。

可編輯邊界紀錄及預期輸出
情況輸入 JSON預期輸出 JSON
後列父紀錄實際欠缺{"nodes":[{"id":"A","parent":"B"}]}{"error":{"code":787},"nodes":[]}
獨立根紀錄{"nodes":[{"id":"A","parent":null}]}{"error":null,"nodes":[{"id":"A","parent_id":null}]}
下載可編輯 CSV ↓

暫時分配好行,參考未核過,可算載入完成嗎?

查看參考答案

不可,欠 B 會令參考更新失敗,全部暫建行都回復。參考齊才提交。

相關資源