MySQL:如何编写UDF_MySQL
bitsCN.com
1.什么是UDF
UDF顾名思义,就是User defined Function,用户定义函数。我们知道,MySQL本身支持很多内建的函数,此外还可以通过创建存储方法来定义函数。UDF为用户提供了一种更高效的方式来创建函数。
UDF与普通函数类似,有参数,也有输出。分为两种类型:单次调用型和聚集函数。前者能够针对每一行数据进行处理,后者则用于处理Group By这样的情况。
2.为什么用UDF
既然MySQL本身提供了大量的函数,并且也支持定义函数,为什么我们还需要UDF呢?这主要基于以下几点:
1)UDF的兼容性很好,这得益于MySQL的UDF基本上没有变动
2)比存储方法具有更高的执行效率,并支持聚集函数
3)相比修改代码增加函数,更加方便简单
当然UDF也是有缺点的,这是因为UDF也处于mysqld的内存空间中,不谨慎的内存使用很容易导致mysqld crash掉。
3.如何编写UDF
UDF的API包括
name_init():
在执行SQL之前会被调用,主要做一些初始化的工作,比如分配后续用到的内存、初始化变量、检查参数是否合法等。
name_deinit()
在执行完SQL后调用,大多用于内存清理等工作。init和deinit这两个函数都是可选的
name()
UDF的主要处理函数,当为单次调用型时,可以处理每一行的数据;当为聚集函数时,则返回Group by后的聚集结果。
name_add()
在每个分组中每行调用
name_clear()
在每个分组之后调用
为了便于理解,这里给出两种UDF类型的API调用图:
下面将就上述几个API进行详细的讲解:
1). name_init
原型:
my_boolname_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
UDF_INIT结构体如下:
字段
类型
描述
maybe_null
my_bool
如果为1表示该UDF可以返回NULL
decimals
unsigned int
返回值为实数时,表示精度,范围0~30
max_length
unsigned long
对于返回值为INTEGER类型值为21,对于REAL类型值为17,对于字符串类型,存储函数最长参数的长度
ptr
char*
额外的指针,我们可以在这里分配内存。通过initd传递给其他API
const_item
my_bool
为1表示函数总是返回相同的值
extension
void*
用于扩展?
UDF_ARGS结构体如下:
字段
类型
描述
arg_count
unsigned int
参数个数
arg_type
enum Item_result*
参数类型数组,记录每一个参数的类型,可以是STRING_RESULT、REAL_RESULT、INT_RESULT以及DECIMAL_RESULT
args
char **
同样是一个数组,用于存储实际数据。
STRING_RESULT与DECIMAL_RESULT类型为char*,INT_RESULT类型为long long*,REAL_RESULT类型为double*,或者一个NULL指针
lengths
unsigned long*
数组,用于存储每一个参数的长度
maybe_null
char *
该数组用于表明每个参数是否可以为NULL,例如
attributes
char **
每个参数的名字
attribute_lengths
unsigned long*
每个参数名字的长度
extension
void*
用于扩展?
Message:用于打印错误信息,该指针本身提供长度为MYSQL_ERRMSG_SIZE,来存储信息;
2).name_deinit
原型:
void name_deinit(UDF_INIT*initid)
该函数会进行一些内存释放和清理的工作,在之前我们提到initid->ptr,我们可以在该区域·进行内存的动态分配,这里就可以直接进行内存释放。
3).name()
原型:针对不同的返回值类型,有不同的函数原型:
返回值类型
函数原型
STRING or DECIMAL
char *name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
INTEGER
long long name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
REAL
double name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
当返回值为STRING类型时,参数result开辟一个buffer来存储返回值,但不超过766字节,在length参数中存储了字符串的长度。
每个函数原型还包括了is_null和error参数,当*is_null被设置为1时,返回值为NULL,设置*error为1,表明发生了错误。
4).name_add()和name_clear()
原型:
void name_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error)
void name_clear(UDF_INIT *initid, char *is_null, char *error)
对于聚合类型的UDF,name_addd和name_clear会被反复调用。
4. 两个例子
下面将举两个简单的例子,一个单次调用型函数,一个聚集类型函数,来描述写一个UDF的过程。
1)接受一个参数,并返回该参数的值
//初始化
my_booludf_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1){ //检查参数个数
strcpy(message,
"udf_intexample() can onlyaccept one argument");
return 1;
}
if (args->arg_type[0] != INT_RESULT){ //检查参数类型
strcpy(message,
"udf_intexample() argumenthas to be an integer");
return 1;
}
return 0;
}
//清理操作
voidudf_int_deinit(UDF_INIT *initid)
{
}
//主函数
long long udf_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
long long num = (*(long long *)args->args[0]); //获取第一个参数值
return num;
}
2)接受一个浮点数类型的参数,并对每个分组进行求和
//初始化
my_booludf_floatsum_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
double *total = (double *) malloc (sizeof(double));
if (total == NULL){ //内存分配失败
strcpy(message,"udf_floatsum:alloc mem failed!");
return 1;
}
*total = 0;
initid->ptr = (char *)total;
if (args->arg_count != 1){ //检查参数个数
strcpy(message, "too moreargs,only one!");
return 1;
}
if (args->arg_type[0] != REAL_RESULT){ //检查参数类型
strcpy(message, "wrongtype");
return 1;
}
initid->decimals = 3; //设置返回值精度
return 0;
}
//清理、释放在init函数中分配的内存
voidudf_floatsum_deinit(UDF_INIT *initid)
{
free(initid->ptr);
}
//每一行都会调用到该函数
voidudf_floatsum_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double* float_total;
float_total = (double*)initid->ptr;
if (args->args[0])
*float_total += *(double*)args->args[0];
}
//每个分组完成后,返回结果
doubleudf_floatsum(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double* float_total;
float_total = (double *)initid->ptr;
return *float_total;
}
//在进行下一个分组前调用,设置initid->ptr指向的值为0,以便下一次分组统计
voidudf_floatsum_clear(UDF_INIT *initid, char *is_null, char *error)
{
double *float_total;
float_total = (double *)initid->ptr;
*float_total = 0;
}
3) Mysql-udf-http是一个开源的UDF,可以利用HTTP协议进行REST操作。什么是REST操作呢?REST是一种web service架构风格,其实现基于HTTP协议的四种方法:POST、GET、PUT以及DELETE操作,在mysql-udf-http里分别对应的函数是http_post、http_get()、http_put()、http_delete()。
源码下载:http://curl.haxx.se/download/curl-7.21.1.tar.gz
./configure–prefix={mysql安装目录} –with-mysql=/usr/local/webserver/mysql/bin/mysql_config
Make&& make install
该UDF的实现原理比较简单,主要使用libcurl库函数来实现http协议通信,总共三百多行代码。这里有使用和介绍http://blog.s135.com/mysql-udf-http/
有些比较有趣的功能:
例如,我们可以通过GET方法获取微博中的个人信息,其中1821798401为用户ID
selecthttp_get('http://api.t.sina.com.cn/statuses/user_timeline/1821798401.json?count=1&source=1561596835')
UDF具有非常高的自由度,你可以编写你任何想要实现的功能函数,甚至可以引用MySQL内核的代码和变量。
当然,UDF也有着局限性,如下:
a) 在mysql库下必须有func表,并且在‑‑skip‑grant‑tables开启的情况下,UDF会被禁止;
b) 当UDF挂掉时,有可能会导致mysqld crash掉;
c) 所有的UDF的函数必须是线程安全的,如果非要用全局变量,需要加互斥,尽量在name_init中分配资源,并在name_deinit中释放
d) 需要有insert权限
作者 zhaiwx1987
bitsCN.com
Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

With the rapid development of social media, Xiaohongshu has become one of the most popular social platforms. Users can create a Xiaohongshu account to show their personal identity and communicate and interact with other users. If you need to find a user’s Xiaohongshu number, you can follow these simple steps. 1. How to use Xiaohongshu account to find users? 1. Open the Xiaohongshu APP, click the "Discover" button in the lower right corner, and then select the "Notes" option. 2. In the note list, find the note posted by the user you want to find. Click to enter the note details page. 3. On the note details page, click the "Follow" button below the user's avatar to enter the user's personal homepage. 4. In the upper right corner of the user's personal homepage, click the three-dot button and select "Personal Information"

The Local Users and Groups utility is built into Computer Management and can be accessed from the console or independently. However, some users find that local users and groups are missing in Windows 11. For some people who have access to it, the message suggests that this snap-in may not work with this version of Windows 10. To manage user accounts for this computer, use the User Accounts tool in Control Panel. The issue has been reported in previous iterations of Windows 10 and is usually caused by issues or oversights on the user's side. Why are local users and groups missing in Windows 11? You are running Windows Home edition, local users and groups are available on Professional edition and above. Activity

In Ubuntu systems, the root user is usually disabled. To activate the root user, you can use the passwd command to set a password and then use the su- command to log in as root. The root user is a user with unrestricted system administrative rights. He has permissions to access and modify files, user management, software installation and removal, and system configuration changes. There are obvious differences between the root user and ordinary users. The root user has the highest authority and broader control rights in the system. The root user can execute important system commands and edit system files, which ordinary users cannot do. In this guide, I'll explore the Ubuntu root user, how to log in as root, and how it differs from a normal user. Notice

Certain folders are not always accessible due to permissions, and in today’s guide we will show you how to access user folders on your old hard drive on Windows 11. The process is simple but can take a while, sometimes even hours, depending on the size of the drive, so be extra patient and follow the instructions in this guide closely. Why can't I access my user folders on my old hard drive? User folders are owned by another computer, so you cannot modify them. You don't have any permissions on the folder other than ownership. How to open user files on old hard drive? 1. Take ownership of the folder and change permissions Find the old user directory, right-click on it and select Properties. Navigate to "An

sudo (superuser execution) is a key command in Linux and Unix systems that allows ordinary users to run specific commands with root privileges. The function of sudo is mainly reflected in the following aspects: Providing permission control: sudo achieves strict control over system resources and sensitive operations by authorizing users to temporarily obtain superuser permissions. Ordinary users can only obtain temporary privileges through sudo when needed, and do not need to log in as superuser all the time. Improved security: By using sudo, you can avoid using the root account during routine operations. Using the root account for all operations may lead to unexpected system damage, as any mistaken or careless operation will have full permissions. and

Many users have been added to the Ubuntu system. I want to delete the users that are no longer in use. How to delete them? Let’s take a look at the detailed tutorial below. 1. Open the terminal command line and use the userdel command to delete the specified user. Be sure to add the sudo permission command, as shown in the figure below. 2. When deleting, be sure to be in the administrator directory. Ordinary users do not have this permission. , as shown in the figure below 3. After the delete command is executed, how to judge whether it has been truly deleted? Next we use the cat command to open the passwd file, as shown in the figure below 4. We see that the deleted user information is no longer in the passwd file, which proves that the user has been deleted, as shown in the figure below 5. Then we enter the home file

Microsoft began rolling out KB2 to the public as an optional update for Windows 503145511H22 or later. This is the first update to enable Windows 11 Moment 4 features by default, including Windows Copilot in supported areas, preview support for items in the Start menu, ungrouping of the taskbar, and more. Additionally, it fixes several Windows 11 bugs, including potential performance issues that caused memory leaks. But ironically, the optional update for September 2023 will be a disaster for users trying to install the update, or even for those who have already installed it. Many users will not install this Wi

This website reported on March 7 that Dr. Zhou Yuefeng, President of Huawei's Data Storage Product Line, recently attended the MWC2024 conference and specifically demonstrated the new generation OceanStorArctic magnetoelectric storage solution designed for warm data (WarmData) and cold data (ColdData). Zhou Yuefeng, President of Huawei's data storage product line, released a series of innovative solutions. Image source: Huawei's official press release attached to this site is as follows: The cost of this solution is 20% lower than that of magnetic tape, and its power consumption is 90% lower than that of hard disks. According to foreign technology media blocksandfiles, a Huawei spokesperson also revealed information about the magnetoelectric storage solution: Huawei's magnetoelectronic disk (MED) is a major innovation in magnetic storage media. First generation ME
