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

📄 plpgsql.sgml

📁 PostgreSQL7.4.6 for Linux
💻 SGML
📖 第 1 页 / 共 5 页
字号:
    referenced by another name inside a trigger procedure.  See also    <literal>ALIAS</literal>.   </para>   <para>    Examples:<programlisting>RENAME id TO user_id;RENAME this_var TO that_var;</programlisting>   </para>    <note>     <para>      <literal>RENAME</literal> appears to be broken as of      <productname>PostgreSQL</> 7.3.  Fixing this is of low priority,      since <literal>ALIAS</literal> covers most of the practical uses      of <literal>RENAME</literal>.     </para>    </note>   </sect2>  </sect1>  <sect1 id="plpgsql-expressions">  <title>Expressions</title>    <para>     All expressions used in <application>PL/pgSQL</application>     statements are processed using the server's regular     <acronym>SQL</acronym> executor. Expressions that appear to     contain constants may in fact require run-time evaluation     (e.g., <literal>'now'</literal> for the <type>timestamp</type>     type) so it is impossible for the     <application>PL/pgSQL</application> parser to identify real     constant values other than the key word <literal>NULL</>. All expressions are     evaluated internally by executing a query<synopsis>SELECT <replaceable>expression</replaceable></synopsis>     using the <acronym>SPI</acronym> manager. For evaluation,     occurrences of <application>PL/pgSQL</application> variable     identifiers are replaced by parameters, and the actual values from     the variables are passed to the executor in the parameter array.     This allows the query plan for the <command>SELECT</command> to     be prepared just once and then reused for subsequent     evaluations.    </para>    <para>     The evaluation done by the <productname>PostgreSQL</productname>     main parser has some side     effects on the interpretation of constant values. In detail there     is a difference between what these two functions do:<programlisting>CREATE FUNCTION logfunc1(text) RETURNS timestamp AS '    DECLARE        logtxt ALIAS FOR $1;    BEGIN        INSERT INTO logtable VALUES (logtxt, ''now'');        RETURN ''now'';    END;' LANGUAGE plpgsql;</programlisting>     and<programlisting>CREATE FUNCTION logfunc2(text) RETURNS timestamp AS '    DECLARE        logtxt ALIAS FOR $1;        curtime timestamp;    BEGIN        curtime := ''now'';        INSERT INTO logtable VALUES (logtxt, curtime);        RETURN curtime;    END;' LANGUAGE plpgsql;</programlisting>    </para>    <para>     In the case of <function>logfunc1</function>, the      <productname>PostgreSQL</productname> main parser knows when      preparing the plan for the <command>INSERT</command>, that the string      <literal>'now'</literal> should be interpreted as      <type>timestamp</type> because the target column of <classname>logtable</classname>     is of that type. Thus, it will make a constant from it at this     time and this constant value is then used in all invocations of      <function>logfunc1</function> during the lifetime of the     session. Needless to say that this isn't what the     programmer wanted.    </para>    <para>     In the case of <function>logfunc2</function>, the      <productname>PostgreSQL</productname> main parser does not know     what type <literal>'now'</literal> should become and therefore      it returns a data value of type <type>text</type> containing the string      <literal>now</literal>. During the ensuing assignment     to the local variable <varname>curtime</varname>, the     <application>PL/pgSQL</application> interpreter casts this     string to the <type>timestamp</type> type by calling the     <function>text_out</function> and <function>timestamp_in</function>     functions for the conversion.  So, the computed time stamp is updated     on each execution as the programmer expects.    </para>    <para>     The mutable nature of record variables presents a problem in this     connection.  When fields of a record variable are used in     expressions or statements, the data types of the fields must not     change between calls of one and the same expression, since the     expression will be planned using the data type that is present     when the expression is first reached.  Keep this in mind when     writing trigger procedures that handle events for more than one     table.  (<command>EXECUTE</command> can be used to get around     this problem when necessary.)    </para>  </sect1>  <sect1 id="plpgsql-statements">  <title>Basic Statements</title>   <para>    In this section and the following ones, we describe all the statement    types that are explicitly understood by    <application>PL/pgSQL</application>.    Anything not recognized as one of these statement types is presumed    to be an SQL command and is sent to the main database engine to execute    (after substitution of any <application>PL/pgSQL</application> variables    used in the statement).  Thus,    for example, the SQL commands <command>INSERT</>, <command>UPDATE</>, and    <command>DELETE</> may be considered to be statements of    <application>PL/pgSQL</application>, but they are not specifically    listed here.   </para>      <sect2 id="plpgsql-statements-assignment">    <title>Assignment</title>    <para>     An assignment of a value to a variable or row/record field is     written as:<synopsis><replaceable>identifier</replaceable> := <replaceable>expression</replaceable>;</synopsis>     As explained above, the expression in such a statement is evaluated     by means of an SQL <command>SELECT</> command sent to the main     database engine.  The expression must yield a single value.    </para>    <para>     If the expression's result data type doesn't match the variable's     data type, or the variable has a specific size/precision     (like <type>char(20)</type>), the result value will be implicitly     converted by the <application>PL/pgSQL</application> interpreter using     the result type's output-function and      the variable type's input-function. Note that this could potentially     result in run-time errors generated by the input function, if the     string form of the result value is not acceptable to the input function.    </para>    <para>     Examples:<programlisting>user_id := 20;tax := subtotal * 0.06;</programlisting>    </para>   </sect2>   <sect2 id="plpgsql-select-into">    <title><command>SELECT INTO</command></title>    <indexterm zone="plpgsql-select-into">     <primary>SELECT INTO</primary>     <secondary>in PL/pgSQL</secondary>    </indexterm>    <para>     The result of a <command>SELECT</command> command yielding multiple columns (but     only one row) can be assigned to a record variable, row-type     variable, or list of scalar variables.  This is done by:<synopsis>SELECT INTO <replaceable>target</replaceable> <replaceable>select_expressions</replaceable> FROM ...;</synopsis>     where <replaceable>target</replaceable> can be a record variable, a row     variable, or a comma-separated list of simple variables and     record/row fields.  The <replaceable>select_expressions</replaceable>     and the remainder of the command are the same as in regular SQL.    </para>    <para>     Note that this is quite different from     <productname>PostgreSQL</>'s normal interpretation of     <command>SELECT INTO</command>, where the <literal>INTO</> target     is a newly created table.  If you want to create a table from a     <command>SELECT</> result inside a     <application>PL/pgSQL</application> function, use the syntax     <command>CREATE TABLE ... AS SELECT</command>.    </para>    <para>     If a row or a variable list is used as target, the selected values     must exactly match the structure of the target, or a run-time error     occurs.  When a record variable is the target, it automatically     configures itself to the row type of the query result columns.    </para>    <para>     Except for the <literal>INTO</> clause, the <command>SELECT</>     statement is the same as a normal SQL <command>SELECT</> command     and can use its full power.    </para>    <para>     If the query returns zero rows, null values are assigned to the     target(s).  If the query returns multiple rows, the first     row is assigned to the target(s) and the rest are discarded.     (Note that <quote>the first row</> is not well-defined unless you've     used <literal>ORDER BY</>.)    </para>    <para>     At present, the <literal>INTO</> clause can appear almost anywhere in the <command>SELECT</command>     statement, but it is recommended to place it immediately after the <literal>SELECT</literal>     key word as depicted above.  Future versions of     <application>PL/pgSQL</application> may be less forgiving about     placement of the <literal>INTO</literal> clause.    </para>    <para>     You can use <literal>FOUND</literal> immediately after a <command>SELECT     INTO</command> statement to determine whether the assignment was successful     (that is, at least one row was was returned by the query). For example:  <programlisting>SELECT INTO myrec * FROM emp WHERE empname = myname;IF NOT FOUND THEN    RAISE EXCEPTION ''employee % not found'', myname;END IF;</programlisting>    </para>    <para>     To test for whether a record/row result is null, you can use the     <literal>IS NULL</literal> conditional.  There is, however, no     way to tell whether any additional rows might have been     discarded.  Here is an example that handles the case where no     rows have been returned:<programlisting>DECLARE    users_rec RECORD;    full_name varchar;BEGIN    SELECT INTO users_rec * FROM users WHERE user_id=3;    IF users_rec.homepage IS NULL THEN        -- user entered no homepage, return "http://"        RETURN ''http://'';    END IF;END;</programlisting>    </para>   </sect2>   <sect2 id="plpgsql-statements-perform">    <title>Executing an Expression or Query With No Result</title>    <para>     Sometimes one wishes to evaluate an expression or query but     discard the result (typically because one is calling a function     that has useful side-effects but no useful result value).  To do     this in <application>PL/pgSQL</application>, use the     <command>PERFORM</command> statement:<synopsis>PERFORM <replaceable>query</replaceable>;</synopsis>     This executes <replaceable>query</replaceable>, which must be a     <command>SELECT</command> statement, and discards the     result. <application>PL/pgSQL</application> variables are     substituted in the query as usual.  Also, the special variable     <literal>FOUND</literal> is set to true if the query produced at     least one row or false if it produced no rows.    </para>    <note>     <para>      One might expect that <command>SELECT</command> with no      <literal>INTO</> clause would accomplish this result, but at      present the only accepted way to do it is      <command>PERFORM</command>.     </para>    </note>    <para>     An example:<programlisting>PERFORM create_mv(''cs_session_page_requests_mv'', my_query);</programlisting>    </para>   </sect2>      <sect2 id="plpgsql-statements-executing-dyn">    <title>Executing Dynamic Commands</title>        <para>     Oftentimes you will want to generate dynamic commands inside your     <application>PL/pgSQL</application> functions, that is, commands     that will involve different tables or different data types each     time they are executed.  <application>PL/pgSQL</application>'s     normal attempts to cache plans for commands will not work in such     scenarios.  To handle this sort of problem, the     <command>EXECUTE</command> statement is provided:<synopsis>EXECUTE <replaceable class="command">command-string</replaceable>;</synopsis>     where <replaceable>command-string</replaceable> is an expression     yielding a string (of type     <type>text</type>) containing the command     to be executed.  This string is fed literally to the SQL engine.    </para>    <para>     Note in particular that no substitution of <application>PL/pgSQL</>     variables is done on the command string.  The values of variables must     be inserted in the command string as it is constructed.    </para>    <para>    When working with dynamic commands you will have to face    escaping of single quotes in <application>PL/pgSQL</>. Please refer to the    overview in <xref linkend="plpgsql-quote-tips">,    which can save you some effort.    </para>         <para>     Unlike all other commands in <application>PL/pgSQL</>, a command     run by an <command>EXECUTE</command> statement is not prepared     and saved just once during the life of the session.  Instead, the     command is prepared each time the statement is run. The command     string can be dynamically created within the function to perform     actions on variable tables and columns.    </para>      <para>     The results from <command>SELECT</command> commands are discarded     by <command>EXECUTE</command>, and <command>SELECT INTO</command>     is not currently supported within <command>EXECUTE</command>.     There are two ways to extract a result from a dynamically-created     <command>SELECT</command>: one is to use the <command>FOR-IN-EXECUTE</>     loop form described in <xref linkend="plpgsql-records-iterating">,     and the other is to use a cursor with <command>OPEN-FOR-EXECUTE</>, as     described in <xref linkend="plpgsql-cursor-opening">.    </para>    <para>     An example:<programlisting>

⌨️ 快捷键说明

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