?? manual_adding_functions.html
字號:
<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增加新函數(shù)</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)
主頁:<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增加新函數(shù)</a></h1>
<p>有2種方法把新函數(shù)加到<strong>MySQL</strong>中:
<ul>
<li>你可以通過用戶定義函數(shù)(UDF)接口加入函數(shù)。用戶定義函數(shù)用<code>CREATE
FUNCTION</code>和<code>DROP FUNCTION</code>語句動態(tài)地增加和刪除。見<a HREF="manual_Reference.html#CREATE_FUNCTION">7.30<code> CREATE FUNCTION/DROP FUNCTION</code>句法</a>。</li>
<li>你可以加入函數(shù)作為一個原生的(內(nèi)置的)<strong>MySQL</strong>函數(shù)。原生函數(shù)被編譯進<code>mysqld</code>服務(wù)器并且在一個永久的基礎(chǔ)上可得到。</li>
</ul>
<p>每種方法都有優(yōu)點和缺點:
<ul>
<li>如果你編寫一個用戶定義函數(shù),你必須安裝服務(wù)器外還得自己安裝對象文件。如果你編譯函數(shù)進服務(wù)器中,你不需要那樣做。</li>
<li>你能把UDF加到<strong>MySQL</strong>二進制代碼發(fā)行中。原生函數(shù)要求你修改源代碼分發(fā)。</li>
<li>如果你升級你的<strong>MySQL</strong>分發(fā),你能繼續(xù)使用你的以前安裝的UDF。對于原生函數(shù),你必須在每次升級時重復(fù)你的修改。
</li>
</ul>
<p>無論你使用哪種方法增加新函數(shù),他們可以象原生函數(shù)例如<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
增加一個新的用戶定義函數(shù)</a></h2>
<p>對于UDF的工作機制,函數(shù)必須用C或C++編寫并且你的操作系統(tǒng)必須支持動態(tài)裝載。<strong>MySQL</strong>源代碼分發(fā)包括一個文件<tt>“sql/udf_example.cc”</tt>,它定義了5個新函數(shù)。請教這個文件看UDF調(diào)用約定怎樣工作。</p>
<p>對每一個你想在SQL語句中使用的函數(shù),你應(yīng)該定義對應(yīng)的C(或 C++)函數(shù)。在下面的討論中,“xxx”用于一個函數(shù)名的例子。為了區(qū)別SQL和C/C++用法,<code>XXX()</code>(大寫)表明SQL函數(shù)調(diào)用,而<code>xxx()</code>((小寫)表明C/C++函數(shù)調(diào)用。</p>
<p>你編寫實現(xiàn)<code>XXX()</code>的接口的C/C++函數(shù)是:
<dl COMPACT="Adding_UDF">
<dt><code>xxx()</code>(必需的)</dt>
<dd>主函數(shù)。這是計算函數(shù)結(jié)果的地方。SQL 類型于你的C/C++函數(shù)返回類型的對應(yīng)關(guān)系如下:<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>的初始化函數(shù),它可用于: <ul>
<li>檢查傳到<code>XXX()</code>的參數(shù)數(shù)量。 </li>
<li>檢查參數(shù)是一種所需的類型,或,另外地,當(dāng)主函數(shù)被調(diào)用時,告訴<strong>MySQL</strong>,為了強制參數(shù)到你想要的類型。</li>
<li>分配任何由主函數(shù)所需的內(nèi)存。</li>
<li>指定結(jié)果的最大長度。</li>
<li>指定(對<code>REAL</code>函數(shù))小數(shù)位的最大數(shù)目。</li>
<li>指定結(jié)果是否能是<code>NULL</code>。</li>
</ul>
</dd>
<dt><code>xxx_deinit()</code>(可選)</dt>
<dd>為<code>xxx()</code>的結(jié)束函數(shù),它應(yīng)該釋放初始化函數(shù)分配了的任何內(nèi)存。</dd>
</dl>
<p>當(dāng)一條SQL語句調(diào)用<code>XXX()</code>時,<strong>MySQL</strong>調(diào)用初始化函數(shù)<code>xxx_init()</code>,讓它執(zhí)行任何所需的設(shè)置,例如參數(shù)檢查或內(nèi)存分配。如果<code>xxx_init()</code>返回一個錯誤,SQL語句用一條錯誤消息并被放棄而主函數(shù)和結(jié)束函數(shù)不被調(diào)用,否則,為每行調(diào)用主函數(shù)<code>xxx()</code>一次。在所有行被處理完后,結(jié)束函數(shù)<code>xxx_deinit()</code>被調(diào)用,因此它能執(zhí)行任何必要的清除。</p>
<p>所有函必須是線程安全的(不只是主函數(shù),還有初始化和結(jié)束函數(shù))。這意味著,你不允許分配任何改變的全局或靜態(tài)變量!如果你需要內(nèi)存,你應(yīng)該在<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的調(diào)用順序</a></h3>
<p>主函數(shù)應(yīng)該如下定義。注意返回類型和參數(shù)不同,取決于你是否在<code>CREATE
FUNCTION</code>語句中聲明SQL函數(shù)<code>XXX()</code>返回<code>STRING</code>、<code>INTEGER</code>或<code>REAL</code>:
</p>
<p>對<code>STRING</code>函數(shù):</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>函數(shù): </p>
<pre>long long xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
</pre>
<p>對于<code>REAL</code>函數(shù): </p>
<pre>double xxx(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
</pre>
<p>初始化和結(jié)束函數(shù)象這樣被聲明:</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>參數(shù)被傳給所有3個函數(shù),它指向一個<code>UDF_INIT</code>結(jié)構(gòu),被用來在函數(shù)之間傳遞信息。<code>UDF_INIT</code>結(jié)構(gòu)成員列在下面。初始化函數(shù)應(yīng)該填寫它想要改變的任何成員。(對一個成員使用缺省值,不改變它。)
<dl COMPACT="UDF_calling_sequences">
<dt><code>my_bool maybe_null</code> </dt>
<dd>如果<code>xxx()</code>能返回<code>NULL</code>,<code>xxx_init()</code>應(yīng)該設(shè)置<code>maybe_null</code>為<code>1</code>。如果參數(shù)的任何一個被聲明<code>maybe_null</code>,缺省值是<code>1。</code></dd>
<dt><code>unsigned int decimals</code> </dt>
<dd>小數(shù)位數(shù)目。缺省值是在被傳給主函數(shù)的參數(shù)中小數(shù)位的最大數(shù)目。(例如,如果函數(shù)傳遞<code>1.34</code>、<code>1.345</code>和<code>1.3</code>,缺省值將是3,因為<code>1.345</code>有3個小數(shù)位。</dd>
<dt><code>unsigned int max_length</code> </dt>
<dd>字符串結(jié)果的最大長度。缺省值不同,取決于函數(shù)的結(jié)果類型。對字符串函數(shù),缺省是最長的參數(shù)的長度。對整數(shù)函數(shù),缺省是21位。對實數(shù)函數(shù),缺省是13加上由<code>initid->decimals</code>指出的小數(shù)位數(shù)。(對數(shù)字函數(shù),長度包括任何符號位或小數(shù)點字符。)</dd>
<dt><code>char *ptr</code> </dt>
<dd>函數(shù)可為它自己的目的使用的一個指針。例如,函數(shù)能使用<code>initid->ptr</code>在函數(shù)之間傳遞分配的內(nèi)存。在<code>xxx_init()</code>中,分配內(nèi)存并將它賦給這個指針:<pre>initid->ptr = allocated_memory;
</pre>
<p>在<code>xxx()</code>和<code>xxx_deinit()</code>中,參照<code>initid->ptr</code>來使用或釋放內(nèi)存。</p>
</dd>
</dl>
<h3><a NAME="UDF_arguments" HREF="manual_toc.html#UDF_arguments">14.1.2 參數(shù)處理</a></h3>
<p><code>args</code>參數(shù)指向一個<code>UDF_ARGS</code>成員,其結(jié)構(gòu)列在下面:
<dl COMPACT="UDF_arguments">
<dt><code>unsigned int arg_count</code> </dt>
<dd>參數(shù)個數(shù)。如果你想要函數(shù)用一個特定數(shù)量的參數(shù)被調(diào)用,在初始化函數(shù)中檢查這個值。例如:<pre>if (args->arg_count != 2)
{
strcpy(message,"XXX() requires two arguments");
return 1;
}
</pre>
</dd>
<dt><code>enum Item_result *arg_type</code> </dt>
<dd>為每個參數(shù)的類型。可能的類型值是<code>STRING_RESULT</code>、<code>INT_RESULT</code>和<code>REAL_RESULT</code>。為了確保參數(shù)是一種給定的類型,而如果他們不是,返回一個錯誤,在初始化函數(shù)中檢查<code>arg_type</code>數(shù)組。例如:<pre>if (args->arg_type[0] != STRING_RESULT
&& args->arg_type[1] != INT_RESULT)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -