有2种方法把新函数加到MySQL中:
- 你可以通过用户定义函数(UDF)接口加入函数。用户定义函数用
CREATE FUNCTION和DROP FUNCTION语句动态地增加和删除。见7.30CREATE FUNCTION/DROP FUNCTION句法。 - 你可以加入函数作为一个原生的(内置的)MySQL函数。原生函数被编译进
mysqld服务器并且在一个永久的基础上可得到。
每种方法都有优点和缺点:
- 如果你编写一个用户定义函数,你必须安装服务器外还得自己安装对象文件。如果你编译函数进服务器中,你不需要那样做。
- 你能把UDF加到MySQL二进制代码发行中。原生函数要求你修改源代码分发。
- 如果你升级你的MySQL分发,你能继续使用你的以前安装的UDF。对于原生函数,你必须在每次升级时重复你的修改。
无论你使用哪种方法增加新函数,他们可以象原生函数例如ABS()或SOUNDEX()那样使用。
14.1 增加一个新的用户定义函数
对于UDF的工作机制,函数必须用C或C++编写并且你的操作系统必须支持动态装载。MySQL源代码分发包括一个文件“sql/udf_example.cc”,它定义了5个新函数。请教这个文件看UDF调用约定怎样工作。
对每一个你想在SQL语句中使用的函数,你应该定义对应的C(或 C++)函数。在下面的讨论中,“xxx”用于一个函数名的例子。为了区别SQL和C/C++用法,XXX()(大写)表明SQL函数调用,而xxx()((小写)表明C/C++函数调用。
你编写实现XXX()的接口的C/C++函数是:
xxx()(必需的)- 主函数。这是计算函数结果的地方。SQL 类型于你的C/C++函数返回类型的对应关系如下:
SQL 类型 C/C++ 类型 STRINGchar *INTEGERlong longREALdouble xxx_init()(可选)- 为
xxx()的初始化函数,它可用于:- 检查传到
XXX()的参数数量。 - 检查参数是一种所需的类型,或,另外地,当主函数被调用时,告诉MySQL,为了强制参数到你想要的类型。
- 分配任何由主函数所需的内存。
- 指定结果的最大长度。
- 指定(对
REAL函数)小数位的最大数目。 - 指定结果是否能是
NULL。
- 检查传到
xxx_deinit()(可选)- 为
xxx()的结束函数,它应该释放初始化函数分配了的任何内存。
当一条SQL语句调用XXX()时,MySQL调用初始化函数xxx_init(),让它执行任何所需的设置,例如参数检查或内存分配。如果xxx_init()返回一个错误,SQL语句用一条错误消息并被放弃而主函数和结束函数不被调用,否则,为每行调用主函数xxx()一次。在所有行被处理完后,结束函数xxx_deinit()被调用,因此它能执行任何必要的清除。
所有函必须是线程安全的(不只是主函数,还有初始化和结束函数)。这意味着,你不允许分配任何改变的全局或静态变量!如果你需要内存,你应该在xxx_init()种分配它并且在xxx_deinit()中释放它。
14.1.1 UDF的调用顺序
主函数应该如下定义。注意返回类型和参数不同,取决于你是否在CREATE FUNCTION语句中声明SQL函数XXX()返回STRING、INTEGER或REAL:
对STRING函数:
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error);
对INTEGER函数:
long long xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
对于REAL函数:
double xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
初始化和结束函数象这样被声明:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
initid参数被传给所有3个函数,它指向一个UDF_INIT结构,被用来在函数之间传递信息。UDF_INIT结构成员列在下面。初始化函数应该填写它想要改变的任何成员。(对一个成员使用缺省值,不改变它。)






