教你写MySQL UDF
浏览:2058次 出处信息
第一次听说UDF是,一片懵懂。还被一个半桶水的培训师忽悠说是存储函数即是UDF。现在想来真是匪夷所思,害人不浅。
从名字上可以得知UDF(user define function)为用户自定义函数。UDF在一定程度上可以使得普通用户定制自己的MySQL函数库,减少对内建函数的依赖。UDF 的功能还是非常强大的。
各类技术人员都可以开发相应的UDF。
管理员可以开发一些与系统交互的UDF。而开发人员可将常用功能用UDF替代存储函数,这样可以大幅提高执行速度和效率。
这篇BLOG的目的想给希望编写UDF的读者提供一些帮助,但读者应该根据自己的需要添加某些具体函数。
现在直入话题,MySQL手册上确实提供了有关MySQL UDF的一些规则。读者可以参考链接。
咱们分4步骤创建一个UDF:
- 编写代码
- 编译
- 安装
- 使用
下面给出一个简单的UDF。其作用就是往error日志里面写入语句。为了做这个实验,我们将使用如下平台:
- OS:OpenSolaris,
- DB:MySQL 5.1.39
- C compiler: Sun C
实例代码如下:
以下是代码片段: /* You owed me when you copy this code without informing dingze.zhu@gmail.com * It’s owned by mysqlsystems.com */ #if defined(_WIN32) #define DLLEXP __declspec(dllexport) #else #define DLLEXP #endif #include <stdlib.h> #include <string.h> #include <stdio.h> #include <mysql.h> #define LIBVERSION “mysqlsystems_udf_log version 0.1 beta” #define ERR_ARG “Hiro tells you: Exactly one argument expected!” #define ERR_MEM “Out of memory!” #ifdef __cplusplus extern “C” { #endif /** * mysqlsystems_udf_log */ DLLEXP my_bool mysqlsystems_udf_log_init( UDF_INIT *initid , UDF_ARGS *args , char *message ){ return 0; } DLLEXP void mysqlsystems_udf_log_deinit( UDF_INIT *initid ){} DLLEXP char* mysqlsystems_udf_log( UDF_INIT *initid , UDF_ARGS *args , char* result , unsigned long* length , char *is_null , char *error ){ *length = strlen(LIBVERSION); return LIBVERSION; } /** * another one : log2error */ DLLEXP my_bool log2error_init( UDF_INIT *initid , UDF_ARGS *args , char *message ){ if(args->arg_count==1){ //alloc mem for format pattern: // “%s0.xxxx\n” // where xxxx is the max // 7 = length of %s0.\n + trailing \0 if(!(initid->ptr = (char *)malloc(7 + 4))){ strcpy(message, ERR_MEM); return 1; } args->arg_type[0] = STRING_RESULT; initid->maybe_null = 0; } else { strcpy(message, ERR_ARG); return 1; } return 0; } DLLEXP void log2error_deinit( UDF_INIT *initid ){ if(initid->ptr) { fflush(stderr); free(initid->ptr); } } DLLEXP my_ulonglong log2error( UDF_INIT *initid , UDF_ARGS *args , char *is_null , char *error ){ int numDigits; char *fmt; *is_null = 0; if(args->args[0]==NULL){ fprintf(stderr, “NULL\n”); } else { fmt = (char *)initid->ptr; memcpy(fmt, “%0.”, 3); sprintf(fmt+3, “%d”, args->lengths[0]<=9998? args->lengths[0]: 9998); numDigits = strlen(fmt + 4); memcpy(fmt + 4 + numDigits, “s\n\0″, 3); fprintf(stderr, fmt, args->args[0]); } return 0; } #ifdef __cplusplus } #endif |
编写完毕代码后,需要将源代码编译成动态库.so文件。随后将动态库拷贝到MySQL安装目录的lib/plugin下。(在那里我们还可以找到Innodb的动态库文件)
根据你使用的OS、MySQL等环境。可能有所出入。在本实验中,使用如下
cc -I/user/local/mysql/include -shared -o mysqlsystems_udf_log.so mysqlsystems_udf_log.c
下图是安装和使用的过程:
查看MySQL的error日志:
网友可以看到,在error log第22号,出现了我们输入的 hello world字样。
建议继续学习:
- 不定参数的应用 function(fmt, …) (阅读:4017)
- 函数式编程 (阅读:3691)
- JavaScript的5种调用函数的方法 (阅读:3650)
- 为 MySQL 增加 HTTP/REST 客户端:MySQL UDF 函数 mysql-udf-http 1.0 发布 (阅读:3134)
- C 语言中统一的函数指针 (阅读:3048)
- C语言函数实现的另类方法 (阅读:2924)
- 关于在函数调用时传递string引用的必要性 (阅读:2857)
- 深入理解PHP之匿名函数 (阅读:2614)
- MySQL 内部函数简介 (阅读:2459)
- PHP中htmlentities()和htmlspecialchars()这两个函数的区别 (阅读:2456)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:slow-log中出现极大的执行时间的问题解决
后一篇:CMDBA战报之Part1 >>
文章信息
- 作者:hironics 来源: SQL部落
- 标签: UDF 函数
- 发布时间:2009-11-29 22:03:15
建议继续学习
近3天十大热文
- [69] Twitter/微博客的学习摘要
- [67] IOS安全–浅谈关于IOS加固的几种方法
- [65] 如何拿下简短的域名
- [65] android 开发入门
- [63] find命令的一点注意事项
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则