iT邦幫忙

2026 iThome 鐵人賽

DAY 20
0
AI 自動化

30 天一起培養一個習慣:把工作交給 AI 之前,先判斷,再搭建工作流系列 第 20 篇

Day 20 : 雲端連不到那個資料庫,那就讓地端的程式自己推進來

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260922/20141298vWrcubcOUd.png

檔案出來了,用 Excel 打開是一片亂碼

地端程式寫好,撈了 47 筆,POST 進昨天那個端點,回 202。信到了,卡片出來了,SharePoint 資料夾裡也多了一個 csv。

點兩下用 Excel 打開,作業名稱那一欄全部是問號和方塊。

檔案沒有壞,流程也沒有錯。那份 CSV 是 UTF-8,而 Excel 在沒有 BOM 的情況下用系統預設編碼去讀它。三個動作全部成功,資料一個字都沒掉,而收到這份檔案的人會告訴你檔案壞了。

目標第一次擴充

前三天的目標一直是同一句:值班的人早上知道昨天出了什麼事。今天第一次擴充,除了知道,還要能回頭查。

摘要看過就沒了。有人問上個月總共失敗幾次,現在沒有人答得出來。所以今天多一個出口,而它的形式是檔案,不是訊息。訊息是給當下的人看的,檔案是給以後的人查的。

同時資料來源也要換。前三天的內容都是我手動貼進去的,今天由一支地端的程式去撈。這是 Day 17 刻意留白的最後一格。

兩條路,差別不在技術

地端資料要上雲,標準答案是裝 on-premises data gateway,用 SQL Server 連接器拉。這條路是對的,官方支援,而且不用寫一行程式。

今天故意走另一條:在地端寫一支程式,自己撈、自己組、自己 POST 進昨天那個端點。理由不是 gateway 不好。

Gateway + SQL Server 連接器 地端程式推送到 HTTP 端點
查詢寫在哪 流程裡,改查詢要改流程 程式裡,改查詢不動流程
憑證在哪 存在 gateway,由 gateway 管理員管 在程式的執行環境裡
誰主動 雲端按排程去拉 地端決定什麼時候推
資料前處理 只能靠連接器與流程運算式 想做什麼都可以,推之前就做完
出事的時候 看 gateway 與流程兩邊 看程式的日誌與流程兩邊
誰維護得動 會用 Power Automate 的人 要會寫程式的人
適合 表結構穩定、查詢單純、要交給非工程人員維護 查詢複雜、需要先算過,或根本沒有 gateway

這張表的用處在最後兩列。選 gateway 是把維護權留在流程那一側,選程式是把它留在工程那一側。兩種都合理,不合理的是沒想過就選了自己比較熟的那一邊。

還有兩條硬邊界會先於你的偏好做決定:單次請求主體上限 100 MB,inbound 請求 120 秒逾時。一次推十萬筆不是設計問題,是它根本過不去。

CSV 是那種看起來最簡單的格式

Create CSV table 把一個 JSON 陣列變成 CSV 字串,SharePoint 的 Create file 把它寫成檔案。兩個動作,看起來沒有懸念。實際上有三格要自己決定。

**欄位順序。**Columns 設為 Automatic 的時候,欄位由陣列元素推得。要固定順序與表頭文字,就得改用 Custom 明列每一欄。下游如果有人拿這份 CSV 接 Power BI,順序變動那天他會比你先發現。

**編碼。**Create CSV table 的輸出是純字串,沒有 BOM,於是就有了開頭那一片亂碼。社群通行的作法是在寫檔前把 UTF-8 BOM 串到字串最前面,這一步不在官方文件裡,自己驗過一次再寫進流程。

**檔名。**不帶日期,每天覆蓋,昨天的就沒了;帶日期,資料夾會一直長。這一格沒有標準答案,但它必須是個決定,而不是第一次建的時候順手打的那幾個字。

今天介面與 plugin 的差異落在 SharePoint 的站台與資料夾。介面可以一層一層瀏覽選取,用 plugin 是把路徑貼進去,而貼錯的那個路徑不會當場報錯,它會等到建立檔案那一步才失敗。等一下的指令書把站台與資料夾寫成「我會在對話中回答」,理由就在這裡。

今天可以做的一件事

最省事的一句是這個:

幫我寫一支程式把資料庫的資料抓出來丟給 Power Automate 存成 CSV。

它會給你一支能跑的程式。連線字串寫在檔案裡,沒有分批,沒有逾時設定,重試會產生第二份檔案,而這些你要到某一天資料變多才會知道。

第一段:產生地端的取數與推送程式

我要在地端寫一支程式,每天早上把昨天未完成的批次作業清單
推送到一個 Power Automate 的 HTTP 端點。

請先問我下列事項再開始寫:資料庫類型與版本、連線方式、
要查的資料表與欄位、執行這支程式的環境。

程式要滿足下列條件,每一條都要在程式碼中看得出來:

【取數】
- 連線字串與任何密鑰不寫在程式碼裡,從環境變數或憑證存放區取得
- 查詢語句獨立成一個常數或設定,不要內嵌在流程控制裡
- 查詢逾時要明確設定,不要用預設值

【組裝】
- 輸出的 JSON 主體格式如下,欄位名稱不得更動:
  {
    "reportDate": "yyyy-MM-dd",
    "failedJobCount": <整數>,
    "summary": "<多行文字>",
    "runKey": "<這一次執行的唯一識別碼>",
    "jobs": [
      { "jobName": "", "owner": "", "lastStatus": "", "failedAt": "" }
    ]
  }
- runKey 由執行日期與批次序號組成,同一天重試要沿用同一個 runKey

【推送】
- 以 POST 送出,Content-Type 為 application/json
- 取得 Microsoft Entra ID 的 bearer token 帶在 Authorization 標頭,
  audience 為 https://service.flow.microsoft.com/(結尾斜線不可省略)
- 明確檢查回應狀態碼,非 2xx 要寫進日誌並以非零狀態結束
- 主體大小超過 20 MB 或筆數超過 5000 時分批送出,
  每一批帶相同的 runKey 與不同的批次序號

【日誌】
- 每次執行至少記錄:runKey、查詢筆數、分批數、每一批的回應狀態碼

寫完之後,另外用條列說明:
這支程式在哪幾種情況下會送出重複的資料,
以及接收端需要做什麼才能辨識出重複。

最後那一段說明才是重點。重試這件事在地端程式裡是一行 retry,在接收端是「同一天出現兩份 CSV」。runKey 存在的理由,就是讓第二側看得出來這兩份是同一次。

Day 14 講過那些確定性需求,唯一識別碼、重試前先確認上一次有沒有成功、部分成功怎麼算,今天它們第一次真的被寫進程式碼裡,而不是留在規格上。

第二段:擴充流程的契約與出口

請使用 Power Automate plugin 修改 Day19-HTTP觸發-值班摘要雙出口。
在你動手之前,先把【修改前的回報】做完。

【schema 變更】
在現有的 Request Body JSON Schema 中新增兩個屬性,
現有的三個屬性與 required 清單完全不動:
- runKey,型別 string
- jobs,型別 array,元素為 object,
  屬性為 jobName、owner、lastStatus、failedAt,皆為 string
新增的兩個屬性不要加入 required。

【新增動作】
在現有的兩個出口之外,再加一條並行分支,依序執行:
1. Data Operation 的 Create CSV table
   - From:jobs 陣列
   - Columns:使用 Custom,依序為
     作業名稱(jobName)、負責人(owner)、
     狀態(lastStatus)、失敗時間(failedAt)
2. SharePoint 的 Create file
   - Site Address:我會在對話中回答,先問我
   - Folder Path:我會在對話中回答,先問我
   - File Name:以 reportDate 與 runKey 組成,副檔名 .csv,
     組法先提案給我確認
   - File Content:Create CSV table 的輸出

【不要做的事】
- 不要修改現有的寄信與發卡片兩個分支
- 不要把 required 清單改掉
- 不要自行選擇站台或資料夾

【修改前的回報】
1. 把 schema 從三個必填欄位擴充成五個屬性之後,
   昨天那個只送三個欄位的呼叫端還能不能成功?依據是什麼?
2. jobs 是空陣列時,Create CSV table 會輸出什麼,
   SharePoint 那一步會發生什麼?
3. 這份 CSV 用 Excel 開啟時中文會不會正常顯示?
   如果不會,原因是什麼?先講原因,不要直接給我修法。
4. 我沒有明講、但你必須自己決定才能改起來的每一項,逐項列出

第 1 題是這一天真正的架構課。加上非必填的欄位,舊的呼叫端不受影響;把欄位改成必填,它下一次就會拿到 400,而且是昨天那種連執行紀錄都沒有的 400。

契約的演進規則只有這麼一條,而它決定了以後這條流程能不能在不通知任何人的情況下修改。今天這條流程只有一個呼叫者,就是我自己寫的那支程式,所以改壞了馬上知道。等到有三個呼叫者的時候,這一條就不再是知識,是紀律。

第三段:驗收這份檔案

流程已經改好,我要驗收產出的 CSV。請針對下面四項各給一個
可以實際檢查的方法,並告訴我在目前設定下的實際結果:

1. 欄位順序是否固定?如果上游的 jobs 陣列某一筆缺少 owner,
   那一列會變成什麼樣子?
2. 某個 jobName 的值裡含有半形逗號或換行時,CSV 會怎麼處理?
   下游用 Excel 或 Power BI 讀進去會是幾欄?
3. 中文是否正常顯示?如果需要處理編碼,請給出實際的運算式,
   並說明它是官方文件的作法還是通行的社群作法
4. 同一天用相同的 runKey 重送一次,SharePoint 上會變成一個檔案
   還是兩個?目前的檔名規則導致的是哪一種?

第 4 題回答之後,告訴我這兩種結果各自在什麼情況下是對的,
不要幫我選。

第 2 題跟昨天那張壞掉的卡片是同一個病。值裡有一個分隔符號,結構就會被切錯,而上游完全不知道。差別在於卡片壞掉你看得出來,CSV 多一欄還是能開,錯的是資料,不是檔案。

第 3 題要求它自己標明來源,這一格值得養成習慣。加 BOM 這種作法在社群裡流通很久,它有效,但它不是官方文件裡的步驟,而這兩種東西的可靠程度不一樣。

留到明天的問題

這條流程現在有三個出口、一個對外入口、一支地端程式,還有一份每天落在 SharePoint 上的檔案。四天前它只有兩格。

它們各自都很小,而且都是我建的。哪一格為什麼長這樣、哪一格是刻意留白、哪一格是它替我決定而我事後才發現,這些全都在我腦子裡,沒有一個字寫在流程上。

明天如果換一個人來接手,他要先知道哪些事,才有辦法動其中任何一格?

https://ithelp.ithome.com.tw/upload/images/20260922/20141298WPs2jnZBQR.png


上一篇
Day 19 : 把手動觸發拿掉,這條流程就變成別人會依賴的東西
系列文
30 天一起培養一個習慣:把工作交給 AI 之前,先判斷,再搭建工作流 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言