Skip to content

Instantly share code, notes, and snippets.

@moomdate
Created August 2, 2026 08:31
Show Gist options
  • Select an option

  • Save moomdate/94d8364bf221fd8fdad4721d856ec33a to your computer and use it in GitHub Desktop.

Select an option

Save moomdate/94d8364bf221fd8fdad4721d856ec33a to your computer and use it in GitHub Desktop.
setup mac power query obdc mysql

คู่มือตั้งค่า ODBC สำหรับ Excel Power Query → MySQL บน macOS

บันทึกการแก้ปัญหาจริง — 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

สาเหตุ (มี 2 ชั้นซ้อนกัน)

ชั้นที่ 1 — Excel เป็นแอป Sandbox โหลด driver จาก /usr/local ไม่ได้

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 จะโหลดไม่ได้เสมอ

ชั้นที่ 2 — ชื่อ DSN บน Mac ไม่ตรงกับที่ไฟล์ 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 ชื่อเดียวกันรออยู่


ขั้นตอนการแก้ทั้งหมด

ขั้นที่ 1 — ย้าย driver ไปตำแหน่งที่ Sandbox อ่านได้

ตำแหน่งที่แอป 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

ขั้นที่ 2 — แก้ path ภายในไลบรารีให้ชี้หากันเองในตำแหน่งใหม่

ใช้ 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) เท่านั้น

ขั้นที่ 3 — ลงทะเบียน driver ใน odbcinst.ini

จดทะเบียนชื่อ ทั้งสองแบบตัวพิมพ์ (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

ขั้นที่ 4 — สร้าง DSN ใน odbc.ini (ชื่อต้องตรงกับที่ไฟล์ Excel เรียก!)

[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 = 1

ขั้นที่ 5 — วาง config ให้ครบ 3 จุด (จุดสำคัญที่คนมักพลาด!)

Excel บน 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 เสมอ

ขั้นที่ 6 — ทดสอบนอก 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


การเพิ่ม DSN ใหม่ในอนาคต

ถ้ามีไฟล์ Excel ตัวอื่นเรียก DSN ชื่ออื่น ให้เพิ่ม section ใหม่ใน odbc.ini ทั้ง 3 จุด ตามตารางขั้นที่ 5 โดยลอกรูปแบบ section [domain.co] แล้วเปลี่ยน ชื่อ section / SERVER / DATABASE / UID ตามจริง

ภาค 2 — ภาษาไทยเพี้ยนหลัง Refresh (แก้เมื่อ 2 สิงหาคม 2026)

อาการ

เชื่อมต่อและ 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 ล้วนๆ

ข้อสรุปสำคัญ — กลไกที่แท้จริง (พิสูจน์ด้วย iODBC trace + ทดสอบ byte จริง)

จาก trace เห็นพฤติกรรม Excel ชัดเจน:

  1. Excel ไม่ใช้ DSN — มันฝัง connection string เต็มในไฟล์: DRIVER={MySQL ODBC 8.0 Unicode Driver};UID=...;SERVER=... ดังนั้นตัวแปรที่ เราคุมได้มีแค่ ชื่อ driver ใน odbcinst.ini ชี้ไปไฟล์ไหน (option ใน DSN ทั้งหมดโดนข้าม และ section [Default] ก็ไม่ถูกอ่าน — ทดสอบแล้ว)
  2. Excel เชื่อมต่อแบบ Unicode (SQLDriverConnectW) แต่ bind ข้อมูลแบบ narrow (SQL_C_CHAR) เสมอ โดยไม่ถาม SQLGetInfo ใดๆ แล้วเอา bytes ที่ได้ไป decode ด้วย encoding ตามภาษาของแอป (อังกฤษ → Mac Roman)
  3. 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 ส.ค. 2026 — ใช้งานได้แล้ว ไม่ต้องแตะไฟล์ Excel เลย)

มี 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 + bind SQL_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) — ถ้าเปลี่ยนกลับเป็นอังกฤษ ภาษาไทยจะเพี้ยนทันที

Rollback (ถ้าต้องการกลับสภาพเดิม)

# 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/ เดิม ไม่ได้ใช้แล้ว ลบได้ถ้าต้องการ)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment