当前位置: 首页 > news >正文

mysql函数扩展之UDF开发

前言

一开始接触到UDF是在目前开发的项目中,在项目的存储过程中接触到了这样一条sql语句:

CREATE FUNCTION XXXXX RETURNS INTEGER SONAME "YYYYY.so";

存储过程的名字叫做CreateUDF,当时看到这条语句很迷惑,根本不知道是做什么用的,只能在项目资源中查找YYYYY.so这个库文件,结果却什么也没有找到,一番努力之后我断定,项目中调用CreateUDF之后并没有产生任何效果。

可是什么是UDF呢?既然存储过程的名字是CreateUDF,那么这条sql语句肯定和UDF有关,于是我开始广泛搜索UDF相关的条目,一开始看得我一头雾水,因为这三个字母组合在一起的意思太多了,根本找不到我想要的解释,最后在角落里发现了一条mysql与UDF相关的条目,这才弄懂什么是UDF。

关于UDF详细的解释和使用方法请参照MYSQL官方文档:Adding a New User-Defined Function

这里只做一个简单的解释:UDF全称是User defined function, 属于mysql的一个拓展接口,一般翻译为用户自定义函数,这个是用来拓展mysql的技术手段。

我们知道mysql本身提供了大量的函数,并且也支持定义函数,为什么我们还需要UDF呢?这主要看到了他的优点:UDF本身的兼容性很好,并且比存储方法具有更高的执行效率,同时支持聚集函数,相比修改原代码增加函数,更加方便简单,但是UDF也处于mysqld的内存空间中,不谨慎的内存使用很容易导致mysql的服务挂掉。

既然明白了什么是UDF,并且知道了它的作用,那么接下来我们写一个小例子测试一下,看看mysql是怎样调用外部函数的。

测试环境

操作系统:Microsoft Windows 7 旗舰版 (64位/Service Pack 1)
开发环境:Microsoft Visual Studio 2008
mysql版本: 5.1.53-community MySQL Community Server (GPL)

一开始本来想在linux测试一下使用.so文件中的函数,但是无奈linux服务器上没有mysql的开发环境,换句话说就是我没有找到mysql/include这个文件夹,只能在windows上测试一下,原理都一样,只不过在windows上就需要把.so文件换成.dll文件罢了。

具体方法

  1. 新建项目:打开VS2008新建项目,选择“Win32控制台用用程序”,输入项目名称mysql_udf_c++,点击确定进入下一步。


    新建项目

  2. 继续操作:直接选择下一步。


    下一步

  3. 选择程序类型:选择DLL按钮,勾选控项目复选框,点击完成。


    DLL

  4. 右键单击项目添加文件:选择C++文件,输入文件名udf_demo,点击添加按钮。


    udf_demo.cpp

  5. 右键单击项目选择属性:在常规选项卡中的“附加包含目录”中选择mysql开发目录,也就是包含mysql.h的那个目录,安装mysql的时候会让你选择。


    include目录

  6. 设置完成后开始写代码,在文件udf_demo.cpp中输入以下代码:

    
    #include <winsock.h>
    
    
    #include <mysql.h>  
    
    
    extern "C" {
        __declspec(dllexport) long long udf_add(UDF_INIT *initid, UDF_ARGS *args, 
        char *is_null, char *error)  
        {  
            long long a = *((long long *)args->args[0]);  
            long long b = *((long long *)args->args[1]);  
            return a + b;  
        }  
    
        __declspec(dllexport) my_bool udf_add_init(UDF_INIT *initid, UDF_ARGS *args, 
        char *message)  
        {  
            return 0;  
        }  
    
    }
  7. 编译代码生成dll,将mysql_udf_c++.dll放到mysql的扩展目录”bin\plugin”或者系统目录“System32”,只要让mysql.exe能够找到它就可以。


    放置dll

  8. 使用udf,打开mysql客户端,输入CREATE FUNCTION udf_add RETURNS INTEGER SONAME "mysql_udf_c++.dll,创建一个自定义函数,然后输入select udf_add(520, 1314),就会得到如图所示的结果。


    使用udf

总结

按照上面的步骤来做,一个简单的udf小例子就实现了,不过我在实现的过程中也遇到了一些问题。

  1. 想要给mysql使用的函数必须要添加__declspec(dllexport)来导出,否则mysql客户端无法找到函数,网上有一些例子是不加这个参数的,但是去掉这个参数无法实现。

  2. 使用C的方式编译extern "C" { ... }也是必须加上的,否则编译出的函数符号前面有其他的标识,导致创建函数的时候找不到,无法创建成功。

  3. functionname_initfunctionname_deinit网上的教程一般说是可选的,但是在我的例子中,如果两个都不写,会编译报错,所以我写了udf_add_init函数。

  4. 返回值问题需要注意,这个做加法的函数,在一开始创建的时候我写成了CREATE FUNCTION udf_add RETURNS STRING SONAME "mysql_udf_c++.dll,返回值写成了字符串,结果一运行就崩溃,mysqld直接挂掉了,后来修改后才正常。

附注

mysql udf demo 源码 在此,有兴趣的小伙伴尽管拿去测试!有什么问题可以及时反馈给我哟!

相关文章:

  • Python实现一个简单的图片爬虫
  • 验证mysql联合索引最左原则
  • Mysql查询时case when语句的使用
  • Vim中简单格式化代码
  • Vim、Xshell、远程终端莫名卡死的原因
  • 关于游戏中仓库类的设计
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • 神秘莫测的时间复杂度
  • 排序算法系列之(三)——略显神秘的快速排序
  • .bat批处理(六):替换字符串中匹配的子串
  • 操作指向类成员的指针需要了解的两个操作符-*和.*
  • VS2015调试dump文件时提示未找到xxx.exe或xxx.dll
  • 结构体sockaddr、sockaddr_in、sockaddr_in6之间的区别和联系
  • 简述TCP三次握手和四次挥手流程
  • 智能指针(零):分类及简单特性
  • Angular 4.x 动态创建组件
  • C# 免费离线人脸识别 2.0 Demo
  • EOS是什么
  • Go 语言编译器的 //go: 详解
  • jquery ajax学习笔记
  • laravel with 查询列表限制条数
  • Map集合、散列表、红黑树介绍
  • MySQL QA
  • Object.assign方法不能实现深复制
  • 看域名解析域名安全对SEO的影响
  • 码农张的Bug人生 - 初来乍到
  • 树莓派 - 使用须知
  • 推荐一个React的管理后台框架
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 我有几个粽子,和一个故事
  • 小程序开发中的那些坑
  • 函数计算新功能-----支持C#函数
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • $.ajax()
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (4)(4.6) Triducer
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (二)WCF的Binding模型
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (一)SpringBoot3---尚硅谷总结
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转载)深入super,看Python如何解决钻石继承难题
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • ***通过什么方式***网吧
  • .“空心村”成因分析及解决对策122344
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • ?php echo ?,?php echo Hello world!;?
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [ABC294Ex] K-Coloring