บันทึกการแก้ปัญหาจริง — 1 สิงหาคม 2026 เครื่อง: Mac (Apple Silicon, macOS 26.5) · Excel for Mac (Microsoft 365) เซิร์ฟเวอร์:
domain.co:3306ฐานข้อมูลtable_name
ไฟล์ Excel ที่สร้างบน Windows มี Power Query เชื่อม MySQL ผ่าน ODBC ใช้งานบน Windows ได้ปกติ แต่บน Mac กด Refresh แล้วขึ้น error:
[iODBC][Driver Manager]Specified driver could not be loaded
และหลังแก้ชั้นแรกได้ ก็เจอ error ชั้นที่สอง:
[iODBC][Driver Manager]Data source name not found and no default driver specified
Driver (MariaDB Connector/ODBC 3.2.9 จดทะเบียนในชื่อ "MySQL ODBC 8.0 UNICODE Driver")
ติดตั้งไว้ที่ /usr/local/mariadb-odbc/ และไลบรารี OpenSSL ชี้ไป /opt/homebrew/
ซึ่ง App Sandbox ของ Excel ห้ามอ่านทั้งสองตำแหน่ง ทดสอบนอก Excel ผ่านตลอด
แต่ใน Excel จะโหลดไม่ได้เสมอ
ไฟล์ Excel ฝัง connection string ไว้ในคิวรีว่า DSN=domain.co
(ตอนสร้างบน Windows ตั้งชื่อ DSN เป็นชื่อเซิร์ฟเวอร์) แต่บน Mac สร้าง DSN ไว้ชื่อ TABLE_NAME
มันจึงหาไม่เจอ — เครื่อง Windows ใช้ได้เพราะมี DSN ชื่อ domain.co อยู่ใน
ODBC Data Sources ของ Windows อยู่แล้ว
บทเรียนสำคัญ: ไฟล์ Excel จำแค่ ชื่อ DSN ส่วน ความหมาย ของชื่อนั้น (เซิร์ฟเวอร์/driver) อยู่ที่เครื่องใครเครื่องมัน ย้ายไฟล์ไปเครื่องไหนต้องมี DSN ชื่อเดียวกันรออยู่
ตำแหน่งที่แอป sandbox (Excel, Power Query) อ่านได้แน่นอนคือ /Library/ODBC/
คัดลอกไลบรารีทั้งชุด 4 ไฟล์ไปที่ /Library/ODBC/mariadb-odbc/:
libmaodbc.dylib ← ตัว driver หลัก
libmariadb.3.dylib ← MariaDB client library
libssl.3.dylib ← OpenSSL
libcrypto.3.dylib ← OpenSSL
ใช้ install_name_tool เขียน install name ใหม่ทุกตัว ให้เลิกอ้าง /usr/local
และ /opt/homebrew ทั้งหมด แล้ว sign ใหม่ (การแก้ path ทำให้ signature เดิมพัง):
NEW=/Library/ODBC/mariadb-odbc
install_name_tool -id $NEW/libcrypto.3.dylib libcrypto.3.dylib
install_name_tool -id $NEW/libssl.3.dylib \
-change /opt/homebrew/Cellar/openssl@3/3.6.3/lib/libcrypto.3.dylib $NEW/libcrypto.3.dylib \
libssl.3.dylib
install_name_tool -id $NEW/libmariadb.3.dylib \
-change /usr/local/mariadb-odbc/lib/mariadb/libssl.3.dylib $NEW/libssl.3.dylib \
-change /usr/local/mariadb-odbc/lib/mariadb/libcrypto.3.dylib $NEW/libcrypto.3.dylib \
libmariadb.3.dylib
install_name_tool -id $NEW/libmaodbc.dylib \
-change /usr/local/mariadb-odbc/lib/mariadb/libmariadb.3.dylib $NEW/libmariadb.3.dylib \
-change /usr/local/mariadb-odbc/lib/mariadb/libssl.3.dylib $NEW/libssl.3.dylib \
-change /usr/local/mariadb-odbc/lib/mariadb/libcrypto.3.dylib $NEW/libcrypto.3.dylib \
libmaodbc.dylib
codesign -f -s - *.dylibตรวจผลด้วย otool -L libmaodbc.dylib — ทุก dependency ต้องชี้
/Library/ODBC/mariadb-odbc/ หรือ path ระบบ (/usr/lib, /Library/Frameworks) เท่านั้น
จดทะเบียนชื่อ ทั้งสองแบบตัวพิมพ์ (UNICODE / Unicode) กันเหนียว เพราะ Windows ใช้ "Unicode" แต่การตั้งค่าเดิมบน Mac ใช้ "UNICODE":
[ODBC Drivers]
MySQL ODBC 8.0 UNICODE Driver = Installed
MySQL ODBC 8.0 Unicode Driver = Installed
[MySQL ODBC 8.0 UNICODE Driver]
Driver = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
Setup = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
[MySQL ODBC 8.0 Unicode Driver]
Driver = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
Setup = /Library/ODBC/mariadb-odbc/libmaodbc.dylib[ODBC Data Sources]
TABLE_NAME = MySQL ODBC 8.0 UNICODE Driver
domain.co = MySQL ODBC 8.0 UNICODE Driver
[domain.co]
Driver = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
SERVER = domain.co
PORT = 3306
DATABASE = table_name
UID = user_name
NO_PROMPT = 1
[TABLE_NAME]
Driver = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
SERVER = domain.co
PORT = 3306
DATABASE = table_name
UID = user_name
NO_PROMPT = 1
[Default]
Driver = /Library/ODBC/mariadb-odbc/libmaodbc.dylib
SERVER = domain.co
PORT = 3306
DATABASE = table_name
NO_PROMPT = 1Excel บน Mac ประกอบด้วย 2 โปรเซส sandbox แยกกัน และแต่ละตัวอ่าน config
จาก container ของตัวเอง ต้องวางไฟล์ odbc.ini + odbcinst.ini ให้ครบทุกจุด:
| # | ตำแหน่ง | ใครอ่าน |
|---|---|---|
| 1 | /Library/ODBC/ |
ทุกโปรเซส (ระดับระบบ) |
| 2 | ~/Library/Containers/com.microsoft.Excel/Data/Library/ODBC/ |
ตัว Excel (dialog รหัสผ่าน) — เครื่องนี้ hardlink กับ ~/Library/ODBC/ |
| 3 | ~/Library/Containers/com.microsoft.Microsoft-Mashup-Container/Data/Library/ODBC/ |
Power Query ตอน Refresh จริง |
จุดที่ 3 คือตัวหลอก: ตอนกรอกรหัสผ่านทำงานใน Excel (จุด 2) แต่ตอนรันคิวรีจริง ทำงานในโปรเซส Mashup (จุด 3) ถ้าลืมจุดนี้จะเจออาการ "ใส่รหัสผ่านได้แต่ refresh พัง"
อัปเดต 2 ส.ค. 2026: Excel เวอร์ชันปัจจุบันเปลี่ยนสถาปัตยกรรมแล้ว — ตรวจด้วย
lsof -i TCP:3306พบว่าตอน Refresh ตัวโปรเซส Excel เองเป็นคนต่อ MySQL โดยตรง (ไม่ใช่โปรเซส Mashup แยกอีกต่อไป) ดังนั้น config ที่มีผลจริง คือจุดที่ 2 (~/Library/ODBC/ซึ่ง hardlink กับ Excel container) แต่ยังแนะนำ ให้วางครบ 3 จุดเหมือนเดิมกันเหนียว และ iODBC อ่าน config ตอนเริ่มโปรเซส เท่านั้น — แก้ config แล้วต้อง Cmd+Q Excel เสมอ
echo "quit" | "/Library/Application Support/iODBC/bin/iodbctestw" \
"DSN=domain.co;UID=user_name;PWD=รหัสผ่าน"- ได้
Access denied= driver + เครือข่ายทำงาน แค่รหัสผ่านผิด (ใกล้สำเร็จแล้ว) - ได้
Data source name not found= DSN ยังไม่ถูกลงทะเบียน - ได้
Specified driver could not be loaded= path ใน odbcinst.ini ผิด หรือ dependency หาย
จากนั้นปิด Excel ให้สนิท (Cmd+Q — ต้องปิดจริง เพราะโปรเซส Mashup ค้าง config เก่าได้) แล้วเปิดไฟล์ กด Refresh
เปิด trace ของ iODBC เพื่อดูว่า Excel ส่ง connection string อะไรมาจริง ๆ —
เพิ่มท้ายไฟล์ odbc.ini (ใน container ที่ Excel อ่าน):
[ODBC]
Trace = 1
TraceAutoStop = 0
TraceFile = /Users/<user>/Library/Containers/com.microsoft.Excel/Data/Library/Caches/iodbc.traceกด Refresh หนึ่งครั้ง แล้วค้นหาใน trace:
grep -n "SQLDriverConnect\|DSN=\|DRIVER=" iodbc.traceวิธีนี้ทำให้เห็นว่าคิวรีเรียก DSN=domain.co ไม่ใช่ TABLE_NAME — ตรงจุดที่เดาไม่มีทางเจอ
อย่าลืมปิด trace (Trace = 0) หลังแก้เสร็จ ไม่งั้นไฟล์ log โตหลาย MB ทุกครั้งที่ refresh
ถ้ามีไฟล์ Excel ตัวอื่นเรียก DSN ชื่ออื่น ให้เพิ่ม section ใหม่ใน odbc.ini
ทั้ง 3 จุด ตามตารางขั้นที่ 5 โดยลอกรูปแบบ section [domain.co] แล้วเปลี่ยน
ชื่อ section / SERVER / DATABASE / UID ตามจริง
เชื่อมต่อและ refresh ได้ปกติ แต่ข้อความภาษาไทยเพี้ยนเป็นสัญลักษณ์แบบนี้:
งวดที่ 9/26 ค่าบริการ → ‡∏á‡∏߇∏î‡∏ó‡∏µ‡πà 9/26 ‡∏чπà‡∏≤‡∏ö‡∏£‡∏¥‡∏Ň∏≤‡∏£
รูปแบบนี้คือ UTF-8 bytes ถูก decode เป็น Mac Roman (จุดสังเกต: มี ‡∏ นำหน้า
เกือบทุกตัวอักษรไทย เพราะไบต์แรกของอักษรไทยใน UTF-8 คือ 0xE0 = ‡ ใน Mac Roman)
การเพี้ยนแบบนี้ย้อนกลับได้ 100% ข้อมูลไม่หาย — แค่ decode ผิด charset
ข้อมูลฝั่ง server ปกติดี (character_set_server = utf8mb4 และทดสอบผ่าน
iodbctest/iodbctestw นอก Excel ภาษาไทยถูกต้อง) — ปัญหาอยู่ฝั่ง client ล้วนๆ
จาก trace เห็นพฤติกรรม Excel ชัดเจน:
- Excel ไม่ใช้ DSN — มันฝัง connection string เต็มในไฟล์:
DRIVER={MySQL ODBC 8.0 Unicode Driver};UID=...;SERVER=...ดังนั้นตัวแปรที่ เราคุมได้มีแค่ ชื่อ driver ใน odbcinst.ini ชี้ไปไฟล์ไหน (option ใน DSN ทั้งหมดโดนข้าม และ section[Default]ก็ไม่ถูกอ่าน — ทดสอบแล้ว) - Excel เชื่อมต่อแบบ Unicode (
SQLDriverConnectW) แต่ bind ข้อมูลแบบ narrow (SQL_C_CHAR) เสมอ โดยไม่ถามSQLGetInfoใดๆ แล้วเอา bytes ที่ได้ไป decode ด้วย encoding ตามภาษาของแอป (อังกฤษ → Mac Roman) - Driver (โหมด W-connect) ตั้ง charset การเชื่อมต่อเป็น utf8mb4 → ส่ง bytes
UTF-8 → Excel decode เป็น Mac Roman →
บ...
เหตุที่ template นี้ใช้ได้บนเครื่อง Windows: ฝั่งนั้น driver ส่ง bytes เป็น codepage 874 (TIS-620) และ Excel ภาษาไทย decode ด้วย codepage 874 — ตรงกันพอดี วิธีแก้บน Mac คือสร้างสภาพเดียวกัน: driver ส่ง TIS-620 + Excel decode แบบไทย (MacThai ซึ่งตำแหน่งอักษรไทยตรงกับ TIS-620)
มี 2 ส่วนประกอบกัน ขาดอย่างใดอย่างหนึ่งไม่ได้:
ส่วนที่ 1 — patch driver ให้ default charset เป็น tis620
MariaDB driver มี literal utf8mb4 อยู่จุดเดียวในไบนารี (ใช้ตั้ง charset
ตอน W-connect) แก้ไบนารีตรงๆ เป็น tis620 แล้ว sign ใหม่:
cp /Library/ODBC/mariadb-odbc/libmaodbc.dylib libmaodbc-tis620.dylib
# หา offset: strings - -t x libmaodbc-tis620.dylib | grep utf8mb4 (เจอที่ 0x75d9c)
printf 'tis620\x00\x00' | dd of=libmaodbc-tis620.dylib bs=1 seek=$((0x75d9c)) conv=notrunc
codesign -f -s - libmaodbc-tis620.dylib
sudo cp libmaodbc-tis620.dylib /Library/ODBC/mariadb-odbc/แล้วแก้ odbcinst.ini ทั้ง 3 จุด (~/Library/ODBC/ ซึ่ง hardlink กับ Excel
container, Mashup container, และ /Library/ODBC/) ให้ทั้งชื่อ
MySQL ODBC 8.0 UNICODE Driver และ ...Unicode Driver ชี้:
Driver = /Library/ODBC/mariadb-odbc/libmaodbc-tis620.dylib
Setup = /Library/ODBC/mariadb-odbc/libmaodbc-tis620.dylibส่วนที่ 2 — ตั้งภาษาของแอป Excel เป็นไทย (เพื่อให้ decode แบบ MacThai)
defaults write com.microsoft.Excel AppleLanguages -array "th-TH" "en-US"
defaults write ~/Library/Containers/com.microsoft.Excel/Data/Library/Preferences/com.microsoft.Excel AppleLanguages -array "th-TH" "en-US"เมนู Excel จะกลายเป็นภาษาไทย — ห้ามเปลี่ยนภาษา Excel กลับเป็นอังกฤษ ไม่งั้นการ decode กลับไปเป็น Mac Roman แล้วภาษาไทยเพี้ยนอีก (driver ยังส่ง TIS-620 อยู่ garble จะเป็นคนละแบบกับเดิม)
เสร็จแล้ว Cmd+Q Excel → เปิดใหม่ → Refresh
ข้อจำกัดที่ยอมรับ: ตัวอักษรนอก TIS-620 (emoji, จีน/ญี่ปุ่น, é ฯลฯ)
จะกลายเป็น ? หลัง refresh — ข้อมูลไทย+อังกฤษ+ตัวเลขปกติไม่กระทบ
- จำลอง Excel เป๊ะๆ นอก Excel: โปรแกรม C เล็กๆ ที่
SQLDriverConnectW+SQLExecDirectW+ bindSQL_C_CHARแล้ว hexdump bytes — บอกได้ทันทีว่า driver ส่ง charset อะไร (UTF-8 =E0 B8 .., TIS-620 =A1-FBทีละไบต์) - iODBC trace (ภาคแรก) ดู connection string + ชนิดการ bind ที่ Excel ใช้จริง — ต้อง Cmd+Q Excel ก่อน เพราะ iODBC อ่าน config ตอนเริ่มโปรเซสเท่านั้น
lsof -nP -i TCP:3306ระหว่าง refresh → โปรเซสไหนต่อ DB (คำตอบ: Excel เอง)
ทั้งหมดนี้ทดสอบแล้วว่า ไม่แก้ปัญหา เพราะ Excel ฝัง connection string เอง และ decode ตามภาษาแอป ไม่สนใจ config เหล่านี้:
| สิ่งที่ลอง | ผล |
|---|---|
CHARSET = utf8mb4 ในทุก DSN ทั้ง 3 จุด |
ไม่มีผล (Excel ไม่ได้ใช้ DSN) |
~/.CFUserTextEncoding → UTF-8 (0x8000100:0x0) |
ไม่มีผล |
LaunchAgent ตั้ง LANG + __CF_USER_TEXT_ENCODING ให้ GUI |
ไม่มีผล |
| เปลี่ยนไปใช้ MySQL Connector/ODBC 26.7 ตัวทางการ | ไม่มีผล (ส่ง UTF-8 เหมือนกัน) |
สองข้อกลางยังเก็บไว้บนเครื่องนี้เป็น hardening (ทำให้เครื่องมือ ODBC ตัวอื่นบน CLI ทำงานถูกต้อง) แต่ไม่เกี่ยวกับการแก้ Excel — ถ้าตั้งใหม่บน เครื่องอื่นข้ามได้เลย
รายละเอียดถ้าอยากทำ hardening:
chmod u+w ~/.CFUserTextEncoding
printf '0x8000100:0x0' > ~/.CFUserTextEncoding # 0x8000100 = kCFStringEncodingUTF8
# LaunchAgent ~/Library/LaunchAgents/local.lang-utf8.plist รันตอน login:
# launchctl setenv LANG en_US.UTF-8
# launchctl setenv __CF_USER_TEXT_ENCODING "0x1F5:0x8000100:0" (0x1F5 = uid 501)- Power Query transform: เพิ่ม step แปลง Mac Roman → UTF-8 ต่อคิวรี
(
Text.FromBinary(Text.ToBinary(_, 10000), TextEncoding.Utf8)) — ใช้ไม่ได้ กับเคสนี้เพราะไฟล์เป็น template กลางที่ห้ามแก้ - Actual Technologies driver (actualtech.com, ~$40) — driver การค้า ออกแบบเฉพาะ Office Mac มี trial จำกัดแถว ถ้าวันหน้า patch วิธีนี้ใช้ไม่ได้ ค่อยลอง
/Library/ODBC/mariadb-odbc/— driver ตัวจริงอยู่ที่นี่libmaodbc-tis620.dylib= ตัวที่ใช้งานจริง (patch แล้ว) ลบแล้วภาษาไทยพังlibmaodbc.dylib= ตัวต้นฉบับ เก็บไว้เผื่อ rollback
/Library/Frameworks/iODBCinst.framework— driver ต้องใช้- โฟลเดอร์ ODBC ใน container ทั้งสองของ Microsoft
- ค่าภาษาไทยของ Excel (
AppleLanguages= th-TH) — ถ้าเปลี่ยนกลับเป็นอังกฤษ ภาษาไทยจะเพี้ยนทันที
# 1. ชี้ odbcinst.ini ทั้ง 3 จุดกลับไป libmaodbc.dylib
sed -i '' 's|libmaodbc-tis620.dylib|libmaodbc.dylib|g' ~/Library/ODBC/odbcinst.ini \
~/Library/Containers/com.microsoft.Microsoft-Mashup-Container/Data/Library/ODBC/odbcinst.ini
sudo sed -i '' 's|libmaodbc-tis620.dylib|libmaodbc.dylib|g' /Library/ODBC/odbcinst.ini
# 2. คืนภาษา Excel เป็นอังกฤษ
defaults delete com.microsoft.Excel AppleLanguages
defaults delete ~/Library/Containers/com.microsoft.Excel/Data/Library/Preferences/com.microsoft.Excel AppleLanguages
# 3. Cmd+Q Excel แล้วเปิดใหม่(ส่วน /usr/local/mariadb-odbc/ เดิม ไม่ได้ใช้แล้ว ลบได้ถ้าต้องการ)