⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual_adding_functions.html

📁 详细介绍了MYSQL的主要功能几一些代码
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html>

<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
<style type="text/css">
<!--
.p14{font-size:14.8px;font-family:宋体;line-height:14pt;}
.p5{ border: 1px solid rgb(146,201,201) }
.a:hover{color:red;}
a.t1:visited{color:red;}
-->
</style>
<title>MySQL中文参考手册-14 向MySQL增加新函数</title>
</head>

<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#101090" VLINK="#7030B0" class="p4">

<h1><img src="Img/mysql-logo.gif" alt="mysql-logo.gif (3082 bytes)" WIDTH="127" HEIGHT="60"><font color="#FF0000">MySQL中文参考手册</font></h1>

<p>翻译:<a href="mailto:clyan@sohu.com">晏子</a>(yanzi) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主页:<a href="http://linuxdn.yeah.net">http://linuxdb.yeah.net</a></p>

<hr>

<p><a HREF="manual_Introduction.html">第一章</a>, <a HREF="manual_Maintenance.html">前一章</a>, 
<a HREF="manual_Adding_procedures.html">下一章</a>, <a HREF="manual_Concept_Index.html">最后一章</a>,<a HREF="manual_toc.html">目录</a>. </p>

<hr>

<h1><a NAME="Adding_functions" HREF="manual_toc.html#Adding_functions">14 为MySQL增加新函数</a></h1>

<p>有2种方法把新函数加到<strong>MySQL</strong>中: 

<ul>
  <li>你可以通过用户定义函数(UDF)接口加入函数。用户定义函数用<code>CREATE 
    FUNCTION</code>和<code>DROP FUNCTION</code>语句动态地增加和删除。见<a HREF="manual_Reference.html#CREATE_FUNCTION">7.30<code> CREATE FUNCTION/DROP FUNCTION</code>句法</a>。</li>
  <li>你可以加入函数作为一个原生的(内置的)<strong>MySQL</strong>函数。原生函数被编译进<code>mysqld</code>服务器并且在一个永久的基础上可得到。</li>
</ul>

<p>每种方法都有优点和缺点: 

<ul>
  <li>如果你编写一个用户定义函数,你必须安装服务器外还得自己安装对象文件。如果你编译函数进服务器中,你不需要那样做。</li>
  <li>你能把UDF加到<strong>MySQL</strong>二进制代码发行中。原生函数要求你修改源代码分发。</li>
  <li>如果你升级你的<strong>MySQL</strong>分发,你能继续使用你的以前安装的UDF。对于原生函数,你必须在每次升级时重复你的修改。 
  </li>
</ul>

<p>无论你使用哪种方法增加新函数,他们可以象原生函数例如<code>ABS()</code>或<code>SOUNDEX()</code>那样使用。</p>

<p><a NAME="IDX674"></a> <a NAME="IDX675"></a> <a NAME="IDX676"></a> </p>

<h2><a NAME="Adding_UDF" HREF="manual_toc.html#Adding_UDF">14.1 
增加一个新的用户定义函数</a></h2>

<p>对于UDF的工作机制,函数必须用C或C++编写并且你的操作系统必须支持动态装载。<strong>MySQL</strong>源代码分发包括一个文件<tt>“sql/udf_example.cc”</tt>,它定义了5个新函数。请教这个文件看UDF调用约定怎样工作。</p>

<p>对每一个你想在SQL语句中使用的函数,你应该定义对应的C(或 C++)函数。在下面的讨论中,“xxx”用于一个函数名的例子。为了区别SQL和C/C++用法,<code>XXX()</code>(大写)表明SQL函数调用,而<code>xxx()</code>((小写)表明C/C++函数调用。</p>

<p>你编写实现<code>XXX()</code>的接口的C/C++函数是: 

<dl COMPACT="Adding_UDF">
  <dt><code>xxx()</code>(必需的)</dt>
  <dd>主函数。这是计算函数结果的地方。SQL 类型于你的C/C++函数返回类型的对应关系如下:<table BORDER="1" WIDTH="100%" NOSAVE="#101090" class="p4">
      <tr>
        <td><strong>SQL 类型</strong> </td>
        <td><strong>C/C++ 类型</strong> </td>
      </tr>
      <tr>
        <td><code>STRING</code> </td>
        <td><code>char *</code> </td>
      </tr>
      <tr>
        <td><code>INTEGER</code> </td>
        <td><code>long long</code> </td>
      </tr>
      <tr>
        <td><code>REAL</code> </td>
        <td><code>double</code> </td>
      </tr>
    </table>
  </dd>
  <dt><code>xxx_init()</code>(可选)</dt>
  <dd>为<code>xxx()</code>的初始化函数,它可用于: <ul>
      <li>检查传到<code>XXX()</code>的参数数量。 </li>
      <li>检查参数是一种所需的类型,或,另外地,当主函数被调用时,告诉<strong>MySQL</strong>,为了强制参数到你想要的类型。</li>
      <li>分配任何由主函数所需的内存。</li>
      <li>指定结果的最大长度。</li>
      <li>指定(对<code>REAL</code>函数)小数位的最大数目。</li>
      <li>指定结果是否能是<code>NULL</code>。</li>
    </ul>
  </dd>
  <dt><code>xxx_deinit()</code>(可选)</dt>
  <dd>为<code>xxx()</code>的结束函数,它应该释放初始化函数分配了的任何内存。</dd>
</dl>

<p>当一条SQL语句调用<code>XXX()</code>时,<strong>MySQL</strong>调用初始化函数<code>xxx_init()</code>,让它执行任何所需的设置,例如参数检查或内存分配。如果<code>xxx_init()</code>返回一个错误,SQL语句用一条错误消息并被放弃而主函数和结束函数不被调用,否则,为每行调用主函数<code>xxx()</code>一次。在所有行被处理完后,结束函数<code>xxx_deinit()</code>被调用,因此它能执行任何必要的清除。</p>

<p>所有函必须是线程安全的(不只是主函数,还有初始化和结束函数)。这意味着,你不允许分配任何改变的全局或静态变量!如果你需要内存,你应该在<code>xxx_init()</code>种分配它并且在<code>xxx_deinit()</code>中释放它。</p>

<h3><a NAME="UDF_calling_sequences" HREF="manual_toc.html#UDF_calling_sequences">14.1.1 
UDF的调用顺序</a></h3>

<p>主函数应该如下定义。注意返回类型和参数不同,取决于你是否在<code>CREATE 
FUNCTION</code>语句中声明SQL函数<code>XXX()</code>返回<code>STRING</code>、<code>INTEGER</code>或<code>REAL</code>: 
</p>

<p>对<code>STRING</code>函数:</p>

<pre>char *xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *result, unsigned long *length,
              char *is_null, char *error);
</pre>

<p>对<code>INTEGER</code>函数: </p>

<pre>long long xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
</pre>

<p>对于<code>REAL</code>函数: </p>

<pre>double xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
</pre>

<p>初始化和结束函数象这样被声明:</p>

<pre>my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

void xxx_deinit(UDF_INIT *initid);
</pre>

<p><code>initid</code>参数被传给所有3个函数,它指向一个<code>UDF_INIT</code>结构,被用来在函数之间传递信息。<code>UDF_INIT</code>结构成员列在下面。初始化函数应该填写它想要改变的任何成员。(对一个成员使用缺省值,不改变它。) 

<dl COMPACT="UDF_calling_sequences">
  <dt><code>my_bool maybe_null</code> </dt>
  <dd>如果<code>xxx()</code>能返回<code>NULL</code>,<code>xxx_init()</code>应该设置<code>maybe_null</code>为<code>1</code>。如果参数的任何一个被声明<code>maybe_null</code>,缺省值是<code>1。</code></dd>
  <dt><code>unsigned int decimals</code> </dt>
  <dd>小数位数目。缺省值是在被传给主函数的参数中小数位的最大数目。(例如,如果函数传递<code>1.34</code>、<code>1.345</code>和<code>1.3</code>,缺省值将是3,因为<code>1.345</code>有3个小数位。</dd>
  <dt><code>unsigned int max_length</code> </dt>
  <dd>字符串结果的最大长度。缺省值不同,取决于函数的结果类型。对字符串函数,缺省是最长的参数的长度。对整数函数,缺省是21位。对实数函数,缺省是13加上由<code>initid-&gt;decimals</code>指出的小数位数。(对数字函数,长度包括任何符号位或小数点字符。)</dd>
  <dt><code>char *ptr</code> </dt>
  <dd>函数可为它自己的目的使用的一个指针。例如,函数能使用<code>initid-&gt;ptr</code>在函数之间传递分配的内存。在<code>xxx_init()</code>中,分配内存并将它赋给这个指针:<pre>initid-&gt;ptr = allocated_memory;
</pre>
    <p>在<code>xxx()</code>和<code>xxx_deinit()</code>中,参照<code>initid-&gt;ptr</code>来使用或释放内存。</p>
  </dd>
</dl>

<h3><a NAME="UDF_arguments" HREF="manual_toc.html#UDF_arguments">14.1.2 参数处理</a></h3>

<p><code>args</code>参数指向一个<code>UDF_ARGS</code>成员,其结构列在下面: 

<dl COMPACT="UDF_arguments">
  <dt><code>unsigned int arg_count</code> </dt>
  <dd>参数个数。如果你想要函数用一个特定数量的参数被调用,在初始化函数中检查这个值。例如:<pre>if (args-&gt;arg_count != 2)
{
    strcpy(message,&quot;XXX() requires two arguments&quot;);
    return 1;
}
</pre>
  </dd>
  <dt><code>enum Item_result *arg_type</code> </dt>
  <dd>为每个参数的类型。可能的类型值是<code>STRING_RESULT</code>、<code>INT_RESULT</code>和<code>REAL_RESULT</code>。为了确保参数是一种给定的类型,而如果他们不是,返回一个错误,在初始化函数中检查<code>arg_type</code>数组。例如:<pre>if (args-&gt;arg_type[0] != STRING_RESULT
      &amp;&amp; args-&gt;arg_type[1] != INT_RESULT)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -