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 源码 在此,有兴趣的小伙伴尽管拿去测试!有什么问题可以及时反馈给我哟!

猜你喜欢

转载自blog.csdn.net/shihengzhen101/article/details/78567661