MySQL-UDF说明
在MySQL中,用户定义函数(User-Defined Functions,UDF)是用户编写的、能够扩展MySQL功能的自定义函数。这些函数可以用于SQL语句,就像MySQL内置的函数一样。UDFs可以用于执行各种任务,从简单的计算到复杂的数据处理,甚至可以与外部库进行交互。
UDF这个术语有歧义,不仅仅可以指使用DLL加载的自定义函数,也可以指使用SQL编写的自定义函数。因此,MySQL官方将UDF修改成了Loadable functions
。本教程为了讨论方便,继续沿用UDF术语,本教程的UDF等同于Loadable functions
。
教程说明
本教程提供了一个UDF(User-Defined Function)示例,旨在引导用户在Windows环境下创建和使用MySQL-UDF。该示例演示了如何以UDF的形式获取字符的Unicode码点。
该示例将创建一个MySQL函数,函数名为udf_example
。该函数的传入参数只有1个,参数的数据类型是String,返回该参数的第一个字符的unicode码点。比如,使用SQL语句SELECT udf_example("中国");
调用该函数时,会返回字符"中"的Unicode码点20013。
本教程的MySQL版本信息为:mysql Ver 8.0.31 for Win64 on x86_64 (MySQL Community Server - GPL)
。本教程将使用Visual Studio 2019生成用于UDF的DLL。
具体步骤
本教程大体分为3步
- 生成用于UDF的DLL
- 加载UDF到MySQL
- 使用UDF
生成用于UDF的DLL
新建MySQL_UDF工程
在Visual Studio 2019中创建动态链接库(DLL)
工程,工程名为MySQL_UDF
。创建完成之后工程目录如下所示:
| 头文件
|-- framework.h
|-- pch.h
| 源文件
|-- dllmain.cpp
|-- pch.cpp
配置MySQL_UDF工程
将本地Windows调试器
左边的解决方案配置/解决方案平台
改为Debug/x64
;
右键MySQL_UDF工程
,点击属性,在属性页进行如下配置:
配置
改为Debug
,平台
改为x64
- 添加MySQL相关的包含目录。
- 进入:
配置属性 => C/C++ => 常规 => 附加包含目录
- 添加目录:
C:\Program Files\MySQL\MySQL Server 8.0\include
- 进入:
添加源代码
在头文件下新建mysql_udf.h
文件,并添加如下代码:
#pragma once
#pragma warning(disable: 4996)
#define UDF_DLL __declspec(dllexport)
#include "mysql.h"
#include "mysql/udf_registration_types.h"
#include <codecvt>
#include <wchar.h>
extern "C" {
UDF_DLL bool udf_example_init(UDF_INIT* initid, UDF_ARGS* args, char* message);
UDF_DLL long long udf_example(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error);
UDF_DLL void udf_example_deinit(UDF_INIT*);
}
在源文件的dllmain.cpp
文件中添加如下代码
#include "mysql_udf.h"
bool udf_example_init(UDF_INIT * initid, UDF_ARGS * args, char* message) {
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
//strcpy(message, "this function only takes 1 parameter, its type is STRING");
strcpy(message, u8"这个函数只支持一个参数,参数类型是STRING!");
return true;
}
return false;
}
long long udf_example(UDF_INIT* initid, UDF_ARGS* args,
char* is_null, char* error) {
// 解析参数
char* utf8_str = args->args[0];
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::wstring wide_str = converter.from_bytes(utf8_str);
return (long long)wide_str[0];
}
void udf_example_deinit(UDF_INIT*) {}
关于xxx()
,xxx_init()
,xxx_deinit()
的作用与相互关系,详见https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html#loadable-function-interface-functions
生成MySQL_UDF.dll文件
右键MySQL_UDF工程
,点击生成
。
DLL生成完成,即可在$(SolutionDir)\x64\Debug\
路径下找到MySQL_UDF.dll
。
加载 UDF 到 MySQL
- 将
MySQL_UDF.dll
复制到C:\Program Files\MySQL\MySQL Server 8.0\lib\plugin
- 执行SQL语句
CREATE FUNCTION udf_example RETURNS INTEGER SONAME 'MySQL_UDF.dll';
- 不需要使用
udf_example
函数后,可以用SQL语句DROP FUNCTION udf_example;
删除udf_example
函数
使用UDF
执行SQL语句SELECT udf_example("中国");
参考文档
MySQL-UDF官方文档 https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html
MySQL-UDF官方示例 https://github.com/mysql/mysql-server/blob/trunk/sql/udf_example.cc