跳至內容
Astera Technology

內部搬移欄為何出現在匯出內容?

目標結構改動前後,匯出欄清單都須明列。

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

先核來源與已訂規則

本例匯出只約定 a、b。視圖若用 SELECT *,底表加 internal 後形狀也改。更正明列 a、b,內部值不入此匯出;即使沒有紀錄,欄形狀也要一樣。

已填假設輸入
紀錄輸入 JSON
原例輸入{"records":[{"a":"A","b":2,"internal":"secret"}]}
下載可編輯 CSV ↓

比較兩條實際路徑

錯匯出多了第三欄 secret;更正仍兩個約定欄。行以外也核欄metadata,空結果才不會掩蓋結構變動。

錯誤與更正路徑的輸出
路徑輸出 JSON
錯誤路徑{"columns":["a","b","internal"],"records":[{"a":"A","b":2,"internal":"secret"}]}
更正路徑{"columns":["a","b"],"records":[{"a":"A","b":2}]}
下載可編輯 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 target(a TEXT,b INTEGER);CREATE VIEW export AS SELECT '+(corrected?'a,b':'*')+' FROM target;');
      db.exec('ALTER TABLE target ADD COLUMN internal TEXT;');
      for(const r of i.records)db.prepare('INSERT INTO target VALUES(?,?,?)').run(r.a,r.b,r.internal);
      const stmt=db.prepare('SELECT * FROM export');return {columns:stmt.columns().map(c=>c.name),records:stmt.all().map(r=>({...r}))};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"records":[{"a":"A","b":2,"internal":"secret"}]},"expected":{"columns":["a","b","internal"],"records":[{"a":"A","b":2,"internal":"secret"}]},"corrected":false},{"label":"corrected base","input":{"records":[{"a":"A","b":2,"internal":"secret"}]},"expected":{"columns":["a","b"],"records":[{"a":"A","b":2}]},"corrected":true},{"label":"null internal value remains excluded","input":{"records":[{"a":"A","b":0,"internal":null}]},"expected":{"columns":["a","b"],"records":[{"a":"A","b":0}]},"corrected":true},{"label":"empty dataset still has export shape","input":{"records":[]},"expected":{"columns":["a","b"],"records":[]},"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);
}
下載可執行例子 ↓

下次載入前核邊界

內部值 null 也不入匯出;資料空,匯出定義仍兩欄。

可編輯邊界紀錄及預期輸出
情況輸入 JSON預期輸出 JSON
內部空值也排除{"records":[{"a":"A","b":0,"internal":null}]}{"columns":["a","b"],"records":[{"a":"A","b":0}]}
資料空但欄形狀明確{"records":[]}{"columns":["a","b"],"records":[]}
下載可編輯 CSV ↓

匯出沒有行,是否已證明欄定義沒變?

查看參考答案

不是,也要查欄清單。更正空輸出仍明訂只有 a、b。

相關資源