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

📄 spi.sgml

📁 PostgreSQL7.4.6 for Linux
💻 SGML
📖 第 1 页 / 共 5 页
字号:
<!--$Header: /cvsroot/pgsql/doc/src/sgml/spi.sgml,v 1.28 2003/10/22 22:28:10 tgl Exp $--><chapter id="spi"> <title>Server Programming Interface</title> <indexterm zone="spi">  <primary>SPI</primary> </indexterm> <para>  The <firstterm>Server Programming Interface</firstterm>  (<acronym>SPI</acronym>) gives writers of user-defined  <acronym>C</acronym> functions the ability to run  <acronym>SQL</acronym> commands inside their functions.  <acronym>SPI</acronym> is a set of  interface functions to simplify access to the parser, planner,  optimizer, and executor. <acronym>SPI</acronym> also does some  memory management. </para> <note>  <para>   The available procedural languages provide various means to   execute SQL commands from procedures.  Some of these are based on or   modelled after SPI, so this documentation might be of use for users   of those languages as well.  </para> </note> <para>  To avoid misunderstanding we'll use the term <quote>function</quote>  when we speak of <acronym>SPI</acronym> interface functions and  <quote>procedure</quote> for a user-defined C-function that is  using <acronym>SPI</acronym>. </para> <para>  Note that if during the execution of a procedure the transaction is  aborted because of an error in a command, then control will not be  returned to your procedure.  Rather, all work will be rolled back  and the server will wait for the next command from the client.  A  related restriction is the inability to execute  <command>BEGIN</command>, <command>COMMIT</command>, and  <command>ROLLBACK</command> (transaction control statements) inside  a procedure.  Both of these restrictions will probably be changed in  the future. </para> <para>  <acronym>SPI</acronym> functions return a nonnegative result on  success (either via a returned integer value or in the global  variable <varname>SPI_result</varname>, as described below).  On  error, a negative result or <symbol>NULL</symbol> will be returned. </para> <para>  Source code files that use SPI must include the header file  <filename>executor/spi.h</filename>. </para><sect1 id="spi-interface"> <title>Interface Functions</title> <refentry id="spi-spi-connect">  <refmeta>   <refentrytitle>SPI_connect</refentrytitle>  </refmeta>  <refnamediv>   <refname>SPI_connect</refname>   <refpurpose>connect a procedure to the SPI manager</refpurpose> </refnamediv> <indexterm><primary>SPI_connect</primary></indexterm> <refsynopsisdiv><synopsis>int SPI_connect(void)</synopsis> </refsynopsisdiv> <refsect1>  <title>Description</title>  <para>   <function>SPI_connect</function> opens a connection from a   procedure invocation to the SPI manager.  You must call this   function if you want to execute commands through SPI.  Some utility   SPI functions may be called from unconnected procedures.  </para>  <para>   If your procedure is already connected,   <function>SPI_connect</function> will return the error code   <returnvalue>SPI_ERROR_CONNECT</returnvalue>.  This could happen if   a procedure that has called <function>SPI_connect</function>   directly calls another procedure that calls   <function>SPI_connect</function>.  While recursive calls to the   <acronym>SPI</acronym> manager are permitted when an SQL command   called through SPI invokes another function that uses   <acronym>SPI</acronym>, directly nested calls to   <function>SPI_connect</function> and   <function>SPI_finish</function> are forbidden.  </para> </refsect1> <refsect1>  <title>Return Value</title>  <variablelist>   <varlistentry>    <term><symbol>SPI_OK_CONNECT</symbol></term>    <listitem>     <para>      on success     </para>    </listitem>   </varlistentry>   <varlistentry>    <term><symbol>SPI_ERROR_CONNECT</symbol></term>    <listitem>     <para>      on error     </para>    </listitem>   </varlistentry>  </variablelist> </refsect1></refentry><!-- *********************************************** --><refentry id="spi-spi-finish"> <refmeta>  <refentrytitle>SPI_finish</refentrytitle> </refmeta> <refnamediv>  <refname>SPI_finish</refname>  <refpurpose>disconnect a procedure from the SPI manager</refpurpose> </refnamediv> <indexterm><primary>SPI_finish</primary></indexterm> <refsynopsisdiv><synopsis>int SPI_finish(void)</synopsis> </refsynopsisdiv> <refsect1>  <title>Description</title>  <para>   <function>SPI_finish</function> closes an existing connection to   the SPI manager.  You must call this function after completing the   SPI operations needed during your procedure's current invocation.   You do not need to worry about making this happen, however, if you   abort the transaction via <literal>elog(ERROR)</literal>.  In that   case SPI will clean itself up automatically.  </para>  <para>   If <function>SPI_finish</function> is called without having a valid   connection, it will return <symbol>SPI_ERROR_UNCONNECTED</symbol>.   There is no fundamental problem with this; it means that the SPI   manager has nothing to do.  </para> </refsect1> <refsect1>  <title>Return Value</title>  <variablelist>   <varlistentry>    <term><symbol>SPI_OK_FINISH</symbol></term>    <listitem>     <para>      if properly disconnected     </para>    </listitem>   </varlistentry>   <varlistentry>    <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>    <listitem>     <para>      if called from an unconnected procedure     </para>    </listitem>   </varlistentry>  </variablelist> </refsect1></refentry><!-- *********************************************** --><refentry id="spi-spi-exec"> <refmeta>  <refentrytitle>SPI_exec</refentrytitle> </refmeta> <refnamediv>  <refname>SPI_exec</refname>  <refpurpose>execute a command</refpurpose> </refnamediv> <indexterm><primary>SPI_exec</primary></indexterm> <refsynopsisdiv><synopsis>int SPI_exec(const char * <parameter>command</parameter>, int <parameter>count</parameter>)</synopsis> </refsynopsisdiv> <refsect1>  <title>Description</title>  <para>   <function>SPI_exec</function> executes the specified SQL command   for <parameter>count</parameter> rows.  </para>  <para>   This function should only be called from a connected procedure.  If   <parameter>count</parameter> is zero then it executes the command   for all rows that it applies to.  If <parameter>count</parameter>   is greater than 0, then the number of rows for which the command   will be executed is restricted (much like a   <literal>LIMIT</literal> clause). For example,<programlisting>SPI_exec("INSERT INTO tab SELECT * FROM tab", 5);</programlisting>   will allow at most 5 rows to be inserted into the table.  </para>  <para>   You may pass multiple commands in one string, and the command may   be rewritten by rules. <function>SPI_exec</function> returns the   result for the command executed last.  </para>  <para>   The actual number of rows for which the (last) command was executed   is returned in the global variable <varname>SPI_processed</varname>   (unless the return value of the function is   <symbol>SPI_OK_UTILITY</symbol>).  If the return value of the   function is <symbol>SPI_OK_SELECT</symbol> then you may the use   global pointer <literal>SPITupleTable *SPI_tuptable</literal> to   access the result rows.  </para>  <para>   The structure <structname>SPITupleTable</structname> is defined   thus:<programlisting>typedef struct{    MemoryContext tuptabcxt;    /* memory context of result table */    uint32      alloced;        /* number of alloced vals */    uint32      free;           /* number of free vals */    TupleDesc   tupdesc;        /* row descriptor */    HeapTuple  *vals;           /* rows */} SPITupleTable;</programlisting>   <structfield>vals</> is an array of pointers to rows.  (The number   of valid entries is given by <varname>SPI_processed</varname>).   <structfield>tupdesc</> is a row descriptor which you may pass to   SPI functions dealing with rows.  <structfield>tuptabcxt</>,   <structfield>alloced</>, and <structfield>free</> are internal   fields not intended for use by SPI callers.  </para>  <para>   <function>SPI_finish</function> frees all   <structname>SPITupleTable</>s allocated during the current   procedure.  You can free a particular result table earlier, if you   are done with it, by calling <function>SPI_freetuptable</function>.  </para> </refsect1> <refsect1>  <title>Arguments</title>  <variablelist>   <varlistentry>    <term><literal>const char * <parameter>command</parameter></literal></term>    <listitem>     <para>      string containing command to execute     </para>    </listitem>   </varlistentry>   <varlistentry>    <term><literal>int <parameter>count</parameter></literal></term>    <listitem>     <para>      maximum number of rows to process or return     </para>    </listitem>   </varlistentry>  </variablelist> </refsect1> <refsect1>  <title>Return Value</title>  <para>   If the execution of the command was successful then one of the   following (nonnegative) values will be returned:   <variablelist>    <varlistentry>     <term><symbol>SPI_OK_SELECT</symbol></term>     <listitem>      <para>       if a <command>SELECT</command> (but not <command>SELECT       ... INTO</>) was executed      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_OK_SELINTO</symbol></term>     <listitem>      <para>       if a <command>SELECT ... INTO</command> was executed      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_OK_DELETE</symbol></term>     <listitem>      <para>       if a <command>DELETE</command> was executed      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_OK_INSERT</symbol></term>     <listitem>      <para>       if an <command>INSERT</command> was executed      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_OK_UPDATE</symbol></term>     <listitem>      <para>       if an <command>UPDATE</command> was executed      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_OK_UTILITY</symbol></term>     <listitem>      <para>       if a utility command (e.g., <command>CREATE TABLE</command>)       was executed      </para>     </listitem>    </varlistentry>   </variablelist>  </para>  <para>   On error, one of the following negative values is returned:   <variablelist>    <varlistentry>     <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>     <listitem>      <para>       if <parameter>command</parameter> is <symbol>NULL</symbol> or       <parameter>count</parameter> is less than 0      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_ERROR_COPY</symbol></term>     <listitem>      <para>       if <command>COPY TO stdout</> or <command>COPY FROM stdin</>       was attempted      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_ERROR_CURSOR</symbol></term>     <listitem>      <para>       if <command>DECLARE</>, <command>CLOSE</>, or <command>FETCH</>       was attempted      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_ERROR_TRANSACTION</symbol></term>     <listitem>      <para>       if <command>BEGIN</>, <command>COMMIT</>, or       <command>ROLLBACK</> was attempted      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_ERROR_OPUNKNOWN</symbol></term>     <listitem>      <para>       if the command type is unknown (shouldn't happen)      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>     <listitem>      <para>       if called from an unconnected procedure      </para>     </listitem>    </varlistentry>   </variablelist>  </para> </refsect1> <refsect1>  <title>Notes</title>  <para>   The functions <function>SPI_exec</function>,   <function>SPI_execp</function>, and   <function>SPI_prepare</function> change both   <varname>SPI_processed</varname> and   <varname>SPI_tuptable</varname> (just the pointer, not the contents   of the structure).  Save these two global variables into local   procedure variables if you need to access the result of   <function>SPI_exec</function> or <function>SPI_execp</function>   across later calls.  </para> </refsect1></refentry><!-- *********************************************** --><refentry id="spi-spi-prepare"> <refmeta>  <refentrytitle>SPI_prepare</refentrytitle> </refmeta> <refnamediv>  <refname>SPI_prepare</refname>  <refpurpose>prepare a plan for a command, without executing it yet</refpurpose> </refnamediv> <indexterm><primary>SPI_prepare</primary></indexterm> <refsynopsisdiv><synopsis>void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>, Oid * <parameter>argtypes</parameter>)</synopsis> </refsynopsisdiv> <refsect1>  <title>Description</title>  <para>   <function>SPI_prepare</function> creates and returns an execution   plan for the specified command but doesn't execute the command.   This function should only be called from a connected procedure.  </para>  <para>   When the same or a similar command is to be executed repeatedly, it   may be advantageous to perform the planning only once.   <function>SPI_prepare</function> converts a command string into an   execution plan that can be executed repeatedly using   <function>SPI_execp</function>.  </para>  <para>   A prepared command can be generalized by writing parameters   (<literal>$1</>, <literal>$2</>, etc.) in place of what would be   constants in a normal command.  The actual values of the parameters   are then specified when <function>SPI_execp</function> is called.   This allows the prepared command to be used over a wider range of   situations than would be possible without parameters.  </para>  <para>   The plan returned by <function>SPI_prepare</function> can be used   only in the current invocation of the procedure since   <function>SPI_finish</function> frees memory allocated for a plan.   But a plan can be saved for longer using the function

⌨️ 快捷键说明

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