MySQL UDF (User Defined Function) 允許用 C/C++ 擴展 SQL 函數庫,實現高效能計算、外部庫調用、加密算法等。本文基於 Visual Studio (VC++) 環境,演示創建 DLL 項目、編寫 UDF 代碼、導出定義文件、編譯配置、部署註冊、測試驗證、刪除函數全流程。
include 目錄) 或安裝目錄下的 includemy_udf,位置任意。include 目錄 (如 D:\MySQL\include)。HAVE_DLOPEN (MySQL UDF 要求)。my_udf.dll。my_udf.def (下一步創建)。#include
#include
#include
// UDF 初始化函數 (可選)
my_bool my_name_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if (args->arg_count != 0) {
strcpy(message, "my_name() takes no arguments");
return 1;
}
initid->maybe_null = 0;
initid->max_length = 20;
return 0;
}
// UDF 反初始化 (可選)
void my_name_deinit(UDF_INIT *initid) {
// 釋放 initid->ptr 分配的內存
}
// UDF 主邏輯函數
char *my_name(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error) {
static const char *name = "MySQL UDF Demo";
*length = strlen(name);
memcpy(result, name, *length);
return result;
}
LIBRARY my_udf
EXPORTS
my_name
my_name_init
my_name_deinit
確保導出名與 C++ 函數名完全一致 (大小寫敏感)。
my_udf.dll (Debug/Release 目錄)。my_udf.dll 到系統 PATH 目錄:C:\Windows\System32 (全局)bin (如 D:\MySQL\bin)plugin_dir (查詢 SHOW VARIABLES LIKE 'plugin_dir';)-- 1. 登入 MySQL
mysql -u root -p
-- 2. 創建函數 (SONAME 指定 DLL 文件名)
CREATE FUNCTION my_name RETURNS STRING SONAME 'my_udf.dll';
-- 3. 測試調用
SELECT my_name();
-- 結果: MySQL UDF Demo
-- 4. 查看函數信息
SHOW FUNCTION STATUS WHERE Name = 'my_name';
-- 5. 刪除函數
DROP FUNCTION my_name;
char *sha256_udf(UDF_INIT *initid, UDF_ARGS *args, ...) {
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) { ... }
const char *input = args->args[0];
unsigned long len = args->lengths[0];
// 調用 OpenSSL EVP_sha256 計算...
// 結果寫入 result 緩衝區 (max_length 64)
}
// init: 分配上下文結構體 initid->ptr = malloc(sizeof(ctx));
// add: 每行調用,累積數據
// clear: 重置上下文 (用於 GROUP BY 切換組)
// deinit: 釋放上下文
| 問題 | 原因/解決 |
|---|---|
| Can't open shared library | DLL 不在 PATH/plugin_dir、依賴項缺失 (VC++ 運行時、OpenSSL)、位元數不匹配 (32/64 位) |
| Symbol not found | .def 導出名與函數名不一致、C++ 名稱修飾 (需 extern "C") |
| Server crashes on call | UDF 內部段錯誤、內存越界、未檢查 args->arg_count/arg_type、靜態緩衝區併發衝突 |
| 返回結果截斷 | initid->max_length 設置過小、result 緩衝區 255 字節限制 (需動態分配 initid->ptr) |
| 並發調用數據錯亂 | 使用靜態/全局變量存儲狀態 → 必須用 initid->ptr 分配線程私有上下文 |
Windows MySQL UDF 開發關鍵路徑:VS DLL 項目 → include 目錄 + HAVE_DLOPEN → extern "C" 導出三函數 (init/main/deinit) → .def 導出 → 複製到 plugin_dir → CREATE FUNCTION SONAME。掌握此技能後,可將高效能 C/C++ 算法 (加密、壓縮、科學計算、正則引擎) 無縫融入 SQL,實現「資料不動代碼動」的極致效能。