Value.NativeQuery ใช้รันคำสั่ง SQL โดยตรงกับฐานข้อมูล เช่น SQL Server, PostgreSQL, BigQuery โดยสามารถส่ง parameters และเปิด Query Folding ได้
| อาร์กิวเมนต์ | ชนิด | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| target | any | Data source connection ที่ต้องการรัน query (เช่น ผลลัพธ์จาก Sql.Database หรือ Sql.Databases) | |
| query | text | คำสั่ง SQL หรือ native query ของ data source นั้นๆ เช่น T-SQL สำหรับ SQL Server | |
| [parameters]ไม่บังคับ | any | null | Record หรือ List ของ parameter values สำหรับ parameterized query (ใช้ @ สำหรับ SQL Server หรือ ? สำหรับบาง database) |
| [options]ไม่บังคับ | nullable record | null | Record ของ options เช่น [EnableFolding = true] เพื่อเปิด Query Folding หรือ [PreserveTypes = true] เพื่อรักษา data type จาก database |
[ ] = อาร์กิวเมนต์ที่ไม่บังคับ
Value.NativeQuery ใช้รันคำสั่ง Native Query (เช่น T-SQL) โดยตรงกับ Data Source จาก Power Query
ทำไมต้องใช้ Value.NativeQuery? เพราะบางครั้ง Power Query UI ไม่รองรับ feature ของ database โดยตรง เช่น Window Functions, CTE, หรือ stored procedures – ฟังก์ชันนี้ช่วยให้เราเขียน SQL เองได้เต็มที่ และที่สำคัญคือสามารถเปิด Query Folding ได้ด้วย!
ที่เจ๋งคือเราสามารถเปิด EnableFolding = true ได้ ทำให้ step ที่ตามมา (เช่น filter, sort) จะถูกแปลงเป็น SQL และส่งไปรันที่ Server แทนที่จะโหลดข้อมูลทั้งหมดมาก่อน ช่วยเรื่อง performance ได้มากครับ
ส่วนตัวผมใช้ฟังก์ชันนี้ตอนที่ต้องการควบคุม SQL Query เองแบบเต็มที่ หรือต้องใช้ feature ของ database ที่ Power Query ไม่รองรับ เช่น ROW_NUMBER, CTE หรือ complex JOIN patterns 😎
รัน SELECT query ตรงๆ กับ SQL Server โดยไม่ต้องผ่าน Table.SelectRows เลย เขียน SQL ได้เต็มรูปแบบตามที่ต้องการ Power Query ส่ง query นี้ไปรันที่ server โดยตรง ประมวลผลได้เร็วกว่าการโหลดข้อมูลทั้งหมดมาก่อน
ส่ง parameter @minprice และ @maxprice ผ่าน record แทนการต่อ string ปลอดภัยจาก SQL Injection เพราะ parameter จะถูก escape อัตโนมัติ โค้ดอ่านง่ายและสามารถใช้ซ้ำได้โดยเปลี่ยนค่าตัวแปร
EnableFolding = true ทำให้ step ถัดไป (SelectRows, Sort) ถูกแปลงเป็น SQL subquery และส่งไปรันที่ Server ด้วย แทนโหลดข้อมูลทั้งหมดมากลับเครื่องก่อน ลดการถ่ายโอนข้อมูลอย่างมาก ประสิทธิภาพดีขึ้นเห็นชัด
CTE (WITH clause) และ ROW_NUMBER() เป็น feature ที่ Power Query UI ไม่รองรับโดยตรง Value.NativeQuery ช่วยให้เขียน advanced SQL ได้เต็มที่ เหมาะสำหรับการดึงข้อมูลที่มีเงื่อนไขซับซ้อน ใช้ PARTITION BY เพื่อจัดลำดับภายในกลุ่ม
ทำให้ step ที่ตามมา เช่น Table.SelectRows หรือ Table.Sort สามารถถูกแปลงเป็น SQL และส่งไปรันที่ Server ได้ แทนที่จะต้องโหลดข้อมูลทั้งหมดมาก่อนแล้วค่อยประมวลผลในเครื่อง ช่วยเรื่องความเร็วได้มากโดยเฉพาะถ้าข้อมูลมีหลายล้านแถว ถ้าไม่เปิด option นี้ native query จะ fold แค่ตัวมันเอง ส่วน step ถัดไปจะถูกประมวลผลใน Power Query ซึ่งช้ากว่ามากครับ
Power Query จะแจ้งเตือนเรื่องความปลอดภัยทุกครั้งที่ใช้ native query เพราะคำสั่งที่เขียนเองอาจมีคำสั่งอันตรายที่สร้างความเสียหายต่อข้อมูลได้ เราต้องกด Edit Permission แล้วเลือก Run เพื่ออนุญาตให้รันได้ นี่เป็นเรื่องปกติและจำเป็นเพื่อความปลอดภัยของข้อมูลและระบบครับ
รองรับหลาย database ได้แก่ SQL Server, PostgreSQL, Oracle, MySQL, Snowflake, Google BigQuery, Amazon Redshift, SAP HANA และ Dataverse (ที่เปิด Enhanced Compute) แต่ละ database อาจมีรูปแบบการเขียน SQL และ parameter placeholder ที่แตกต่างกัน เช่น SQL Server ใช้ @param แต่บางตัวอาจใช้ ? แทน ต้องศึกษาเพิ่มเติมตาม database ที่ใช้งานครับ
ไม่ได้ครับ Value.NativeQuery ใช้ได้เฉพาะ Import mode เท่านั้น ถ้าพยายามใช้กับ DirectQuery จะได้ข้อความแสดงข้อผิดพลาด ถ้าต้องการใช้ native query ใน DirectQuery ให้ตั้งค่าตอนเชื่อมต่อ database แทน โดยเลือกใส่ native query ใน connector settings ตั้งแต่ต้นครับ
ไม่ได้โดยตรงครับ เพราะ parameters ต้องกำหนดค่าตอนที่ query ถูกประมวลผล ซึ่งเกิดขึ้นก่อนที่รายงานจะโหลด ถ้าต้องการให้ผู้ใช้สามารถเลือกกรองข้อมูลจาก slicer ได้ แนะนำให้ใช้ DAX filter แทน หรือถ้าข้อมูลไม่ใหญ่มากก็โหลดข้อมูลทั้งหมดมาแล้วใช้ slicer filter ใน report แทนครับ
ยังไม่มีบทความที่เกี่ยวข้องกับฟังก์ชันนี้
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่