← 所有文章

工業 CSV 欄位規格與匯入驗收

· 站長

訂定CSV欄位、單位、空值與版本,透過合法與拒收案例驗證跨工具交換結果。

先寫 CSV 合約 再談匯出工具

CSV 是交換格式,不是資料庫 schema,也不是 Excel 的型別宣告。工程團隊應先寫欄位規格:欄名、順序、是否必填、單位、編碼、空值表示、引號和換行,再選匯出工具。RFC 4180 描述每筆記錄一行、欄位以逗號分隔、含逗號或換行的欄位用雙引號,並提醒實作之間仍有差異。

本例的泵浦批次檔固定 UTF-8、CRLF、第一行欄名、五欄順序:record_id,device_id,flow_l_min,quality,recorded_at。flow_l_min 是十進位數字字串,quality為本案例自訂交換品質,允許Good、Stale、Bad;與來源品質碼的映射另列,不能宣稱這是通用OPC列舉;空值不寫成 0。這些是本案契約,不能因某個試算表自動轉型就省略。

欄位規格要寫成可審核的契約文件。除了欄名與順序,還應列出編碼、換行、分隔字元、引用字元、空值、數字小數點、時間精度、列舉與唯一性。若資料來自不同國家,不能讓小數逗號與欄位逗號同時出現而未定義;本案例固定小數點為句點、欄位分隔為逗號。

欄位 型別/單位 必填 例值與限制
record_id 字串 B20260917-0001,不可重複
device_id 字串 P-101,保留連字號
flow_l_min 十進位 L/min 120.5;空值代表未量測
quality 列舉 Good/Stale/Bad
recorded_at ISO 8601 offset 2026-09-17T10:00:00+08:00

引號 逗號與換行的實例

若 device_note 另放入欄位,內容為「濾網,待清潔」時,整個欄位必須被雙引號包住;內容含雙引號時,以兩個雙引號表示一個字元。換行也屬欄位內容,不應簡單以每一行 split 逗號。匯入程式要使用 CSV parser,並測試欄位內逗號、引號、CRLF 和最後一行沒有換行。

例如一筆合法記錄可寫成 B1,P-101,120.5,Good,2026-09-17T10:00:00+08:00。若備註欄為 濾網,待清潔,應寫成 B1,P-101,120.5,Good,"濾網,待清潔",2026-09-17T10:00:00+08:00,同時更新欄位規格為六欄。不可讓文章中的例值與欄位數互相矛盾。

匯出程式應先產生暫存檔,再以 parser 讀回檢查欄數和內容,最後在同一檔案系統且支援原子更名的環境發布;跨磁碟搬移需另定完成標記。這能避免操作員讀到只寫了一半的檔案。每個檔案另產 manifest,記錄 schema_version、row_count、created_at、sha256 和來源批次。manifest 不是 CSV 欄位,但能讓匯入端知道檔案是否完整。

欄位名稱含非 ASCII 字元時,本案例仍建議用穩定的 ASCII machine name,另以資料字典提供中文顯示名。這不是 CSV grammar 的要求,而是便於 SQL、腳本和跨平台系統維護的工程決策,應寫入 schema_version。

版本升級時不要默默改欄位順序。先發布新 schema_version,再讓匯入端接受新舊版本各自的欄位清單;未知版本應拒收並保留檔案。這能把格式變更從一次性的人工提醒變成可重現的流程。

若要支援 tab 分隔或分號分隔,必須另建版本或明確參數,不能讓 parser 自動猜分隔符;猜錯時欄數可能仍然看似合法而造成資料錯欄。

輸入片段 parser 結果 是否通過 排查
P-101,"濾網,待清潔" 一個含逗號欄位 確認欄位數
P-101,"泵""A" 第二欄內容為泵"A 檢查雙引號成對
P-101,120.5 欄位不足 補必填欄位或拒收
P-101。 空字串 依欄位規格 不可自動改成 0

CSV grammar 不等於 schema

RFC 4180 的 grammar 只說明如何分隔與引用文字,沒有定義 flow 的單位、時間時區、品質列舉或 record_id 唯一性。因此「能被 parser 讀入」不代表資料符合工業交換規格。匯入端要先驗欄位數與欄名,再驗列舉、數字範圍、時間 offset 和跨列唯一鍵。

Excel 或其他試算表可能把 0012 顯示成 12、把長 ID 當數字、把日期依本機 locale 改寫,也可能把空欄當成零。驗收不能只開檔看畫面;應以原始 bytes、parser 結果和匯入後資料庫查詢三者比對。若一定要給人工開啟,另提供 schema 說明與不可變更的原始檔。

資料型別驗證必須保留錯誤的原文。flow_l_min=1O2.3 中的 O 不是零時,錯誤報告要指出列號、欄名、原始字串和期望格式;不能把它轉成 102.3。對空值也要區分「欄位缺少」、「欄位為空字串」和「明確的 NULL 標記」,否則統計程式會把三者混為一談。

檔案大小與列數也要驗收。manifest 宣告 3 筆但 parser 讀到 2 筆時,檔案應拒收;最後一行被截斷或 CRLF 被轉換時,先比較 hash 與 row_count,再查傳輸模式,不要直接修補來源檔後匯入。

數字欄的量程也要有規格,例如 flow_l_min 允許 0 到 500、最多 3 位小數。超過量程、負值或 NaN 字串要回報原始列,不可在匯入時裁切到上下限,因為裁切會掩蓋設備或轉換錯誤。

檢查層 輸入 判定 失敗例
語法 CRLF、引號、欄數 parser 可讀 未閉合引號
schema 欄名/順序/列舉 符合契約 quality=OK
語意 單位/範圍/時間 可供控制報表使用 flow=-4
保存 raw bytes/hash 可追溯 Excel 另存覆寫

匯出 匯入與錯誤回報流程

以 3 筆資料做驗收:第一筆 Good=120.5,第二筆 Stale 且 flow 空值,第三筆 Bad 且仍保留原始數值 118.0。匯出後計算檔案 hash;匯入端先解析到暫存表,逐列回報 record_id、欄位、錯誤原因,全部通過才提交正式表。第二筆空值在此契約合法,不應跳過;另加入第四筆負值作錯誤測試,亦不能把 Bad 改為 Good。

排錯順序是先看編碼與原始 bytes,再看 parser 欄位數,接著看 schema 驗證,最後才檢查 Excel 顯示。若匯入後時間少了 offset,應回到 raw CSV 確認;若只有 Excel 顯示不同而 parser 正確,問題是工具格式化,不是來源資料。版本欄可放在檔名或伴隨 manifest,但不能用檔名取代欄位契約。

如果交付對象使用 Excel,應把它當檢視工具而非權威 parser。驗收先以固定語言的 CSV parser 讀原檔,確認 bytes 與 hash;再開啟副本觀察是否顯示科學記號、日期轉換或前導零消失。若使用者需要可編輯表格,另交付 XLSX 並保留原始 CSV,不能以另存 CSV 取代來源。

RFC 4180 是 Informational 文件,記錄常見 CSV 格式並非所有產品的完整標準。本文因此把分隔、引號和換行當 grammar,把單位、品質和版本當自訂 schema,兩層在表格與測試中分開。

筆次 原始值 預期匯入 驗收結果
1 120.5,Good 120.5 / Good 接受
2 空值,Stale NULL / Stale 接受並保留品質
3 118.0,Bad 118.0 / Bad 接受但不可供控制
4 -4,Good 範圍錯誤 拒收並回報列號

FAQ 限制與官方來源

匯入提交要有批次狀態:Parsed、Validated、Committed、Rejected。任何一列驗證失敗就進 Rejected,並保存錯誤清單;若資料庫提交失敗,整批回滾但不得刪除原始檔與 manifest。相同來源與schema版本下,重跑已成功提交的同一hash應回報已處理;上次失敗則允許按修正後規則重新驗證,避免把重複匯入誤當新批次。

跨平台測試至少包括 Linux parser、Windows 匯入工具和資料庫 COPY 或等價 API。三者讀同一份原始檔後,欄位數、Unicode、空值與時間offset解讀必須相同,輸入原檔hash也須一致;若工具差異無法消除,就要在交付文件中明示限制。

對含逗號的備註做 round trip:原始字串送入 exporter、parser、資料庫再輸出,應得到同樣字元與欄位位置。對含雙引號和換行的備註各做一次,並比較解析後的欄位內容;重新匯出的引號與換行可能合法改變,只有要求位元組完全不變的原檔傳輸才比較相同hash;若只在 Excel 畫面看起來相同,仍不足以通過。

資料字典要把每欄的 nullability、unit、scale 和 enum 寫清楚,並附一個合法檔與四個非法檔供工具測試。任何工具更新都重新跑同一組 fixture,避免匯入行為隨版本改變卻無人發現。

FAQ1:CSV 能否直接當 schema?不能,CSV grammar 不含單位、列舉、唯一鍵或時間語意。

FAQ2:把數字欄全部加雙引號就能避免 Excel 轉型嗎?不能,引用只處理分隔語意;開啟工具仍可能依 locale 轉型。

FAQ3:空值可否寫成 0?只有欄位規格明確定義才可以;量測未知時 0 會製造錯誤資料。

FAQ4:最後一筆一定要 CRLF 嗎?RFC 4180 描述最後記錄可有或沒有換行,但本案例為可重現驗收,明確要求 CRLF。

限制:本文使用 RFC 4180 的常見規則與自訂工業 schema,未指定某一 PLC、資料庫或試算表產品的自動型別行為。正式交付前要以目標 parser、編碼和匯入設定測試。

參考:IETF RFC 4180, Common Format and MIME Type for CSV Files(定義 record、CRLF、逗號與雙引號規則)

延伸閱讀


使用 PLC 工具箱 →