From db67c19e859c2b8b425ee64400f2f7b6bbf76a1a Mon Sep 17 00:00:00 2001 From: JianMiau Date: Mon, 10 Aug 2026 15:22:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8B=95=E6=94=BE=E5=AF=AC=E8=88=8A?= =?UTF-8?q?=E8=B3=87=E6=96=99=E8=A1=A8=E9=81=8E=E5=B0=8F=E7=9A=84=E6=AC=84?= =?UTF-8?q?=E4=BD=8D=EF=BC=8C=E4=BF=AE=E6=AD=A3=E4=B8=8A=E5=82=B3=E5=A4=B1?= =?UTF-8?q?=E6=95=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根本原因: badminton 資料表是舊系統先建立的,battlecombination 欄位型別比 TEXT 小;ensureTable 的 CREATE TABLE IF NOT EXISTS 對已存在的資料表不會生效,跨區平衡後 6 隊 × 3 輪的 JSON 超過欄位長度,寫入時噴出「Data too long for column 'battlecombination'」。 影響: - server 啟動後第一次資料庫操作會自動把 personnel 與 battlecombination 放寬成 TEXT,不需手動下 SQL - ensureTable 加上 tableReady 旗標,每個 process 只檢查一次,不再每個 request 都跑 CREATE TABLE 修法: 新增 widenLegacyColumns 查詢 information_schema,欄位型別不是 TEXT 系列時執行 ALTER TABLE MODIFY 放寬,並以模組層旗標記憶檢查結果。 Co-Authored-By: Claude Fable 5 --- server/server.mjs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/server/server.mjs b/server/server.mjs index 6d1646a..2ee7c30 100644 --- a/server/server.mjs +++ b/server/server.mjs @@ -240,7 +240,13 @@ app.listen(port, () => { } }) +let tableReady = false + async function ensureTable(poolInstance, currentTableName) { + if (tableReady) { + return + } + await poolInstance.execute(` CREATE TABLE IF NOT EXISTS \`${currentTableName}\` ( time INT(11) NOT NULL, @@ -249,6 +255,34 @@ async function ensureTable(poolInstance, currentTableName) { PRIMARY KEY (time) ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci `) + + await widenLegacyColumns(poolInstance, currentTableName) + tableReady = true +} + +async function widenLegacyColumns(poolInstance, currentTableName) { + const [columns] = await poolInstance.execute( + ` + SELECT COLUMN_NAME AS name, DATA_TYPE AS type + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = ? + AND COLUMN_NAME IN ('personnel', 'battlecombination') + `, + [currentTableName], + ) + + for (const column of columns) { + if (['text', 'mediumtext', 'longtext'].includes(String(column.type).toLowerCase())) { + continue + } + + const nullability = column.name === 'personnel' ? 'NOT NULL' : 'DEFAULT NULL' + await poolInstance.execute( + `ALTER TABLE \`${currentTableName}\` MODIFY \`${column.name}\` TEXT ${nullability}`, + ) + console.log(`widened column ${column.name} to TEXT on \`${currentTableName}\``) + } } function buildLineFlexMessage(time, rounds) {