|
有2种方法把新函数加到MySql中: - 你可以通过用户定义函数(UDF)接口加入函数。用户定义函数用
CREATEFUNCTION和DROPFUNCTION语句动态地增加和删除。见7.30CREATEFUNCTION/DROPFUNCTION句法。 - 你可以加入函数作为一个原生的(内置的)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*INTEGERlonglongREALdoublexxx_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.1UDF的调用顺序主函数应该如下定义。注意返回类型和参数不同,取决于你是否在CREATEFUNCTION语句中声明SQL函数XXX()返回STRING、INTEGER或REAL: 对STRING函数: char*xxx(UDF_INIT*initid,UDF_ARGS*args,char*result,unsignedlong*length,char*is_null,char*error); 对INTEGER函数: longlongxxx(UDF_INIT*initid,UDF_ARGS*args,char*is_null,char*error); 对于REAL函数: doublexxx(UDF_INIT*initid,UDF_ARGS*args,char*is_null,char*error); 初始化和结束函数象这样被声明: my_boolxxx_init(UDF_INIT*initid,UDF_ARGS*args,char*message);voidxxx_deinit(UDF_INIT*initid); initid参数被传给所有3个函数,它指向一个UDF_INIT结构,被用来在函数之间传递信息。UDF_INIT结构成员列在下面。初始化函数应该填写它想要改变的任何成员。(对一个成员使用缺省值,不改变它。)my_boolmaybe_null如果xxx()能返回NULL,xxx_init()应该设置maybe_null为1。如果参数的任何一个被声明maybe_null,缺省值是1。unsignedintdecimals小数位数目。缺省值是在被传给主函数的参数中小数位的最大数目。(例如,如果函数传递1.34、1.345和1.3,缺省值将是3,因为1.345有3个小数位。unsignedintmax_length字符串结果的最大长度。缺省值不同,取决于函数的结果类型。对字符串函数,缺省是最长的参数的长度。对整数函数,缺省是21位。对实数函数,缺省是13加上由initid->decimals指出的小数位数。(对数字函数,长度包括任何符号位或小数点字符。)char*ptr函数可为它自己的目的使用的一个指针。例如,函数能使用initid->ptr在函数之间传递分配的内存。在xxx_init()中,分配内存并将它赋给这个指针:initid->ptr=allocated_memory; 在xxx()和xxx_deinit()中,参照initid->ptr来使用或释放内存。 14.1.2参数处理args参数指向一个UDF_ARGS成员,其结构列在下面:unsignedintarg_count参数个数。如果你想要函数用一个特定数量的参数被调用,在初始化函数中检查这个值。例如:if(args->arg_count!=2){strcpy(message,"XXX()requirestwoarguments");return1;}enumItem_result*arg_type为每个参数的类型。可能的类型值是STRING_RESULT、INT_RESULT和REAL_RESULT。为了确保参数是一种给定的类型,而如果他们不是,返回一个错误,在初始化函数中检查arg_type数组。例如:if(args->arg_type[0]!=STRING_RESULT&&args->arg_type[1]!=INT_RESULT){strcpy(message,"XXX()requiresastringandaninteger");return1;}作为另一种要求你的函数的参数类型是特定类型的选择,你可以使用初始化函数设置arg_type成员是你想要的类型。这导致MySQL为每个xxx()调用强制参数为那些类型,例如,为了指定头2个参数到字符串和整数的强制,在xxx_init()中做这些: args->arg_type[0]=STRING_RESULT;args->arg_type[1]=INT_RESULT; char**argsargs->args将关于你的函数用它调用的参数的一般特性的信息传递到初始化函数。对一个常数参数i,args->args[i]指向参数值。(见下面关于如何正确存取值的指令)对一个非常数的参数,args->args[i]是0。一个常数参数只是使用常数的一个表达式,例如3或4*7-2或SI(3.14)。一个非常数参数是引用可能每行不同的值的一个表达式,例如列名字或用非常数参数调用的函数。对主函数的每次调用,args->args包含对当前正在处理的行所传递的实际参数。函数可以如下地引用一个参数i:- 一个
STRING_RESULT类型的参数由一个字符串指针加一个长度给出,允许处理任意的长度的二进制的数据或数据。字符串内容可由args->args[i]得到并且字符串长度是args->lengths[i]。你不应该假设字符串是以空(null)结束的。 - 对于一个
INT_RESULT类型的参数,你必须强制转换args->args[i]为一个longlong值
[1] [2] [3] [4] 下一页
|