mirror of
https://github.com/postgres/postgres.git
synced 2025-05-29 00:03:09 -04:00
Code review for SELECT INTO STRICT patch: use saner choices of error
SQLSTATEs, fix some documentation problems.
This commit is contained in:
parent
3ba3e6c8ce
commit
c892643a3c
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.19 2006/06/16 22:41:45 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.20 2006/06/16 23:29:26 tgl Exp $ -->
|
||||||
|
|
||||||
<appendix id="errcodes-appendix">
|
<appendix id="errcodes-appendix">
|
||||||
<title><productname>PostgreSQL</productname> Error Codes</title>
|
<title><productname>PostgreSQL</productname> Error Codes</title>
|
||||||
@ -1344,6 +1344,18 @@
|
|||||||
<entry>raise_exception</entry>
|
<entry>raise_exception</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>P0002</literal></entry>
|
||||||
|
<entry>NO DATA FOUND</entry>
|
||||||
|
<entry>no_data_found</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>P0003</literal></entry>
|
||||||
|
<entry>TOO MANY ROWS</entry>
|
||||||
|
<entry>too_many_rows</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry spanname="span13"><emphasis role="bold">Class XX — Internal Error</></entry>
|
<entry spanname="span13"><emphasis role="bold">Class XX — Internal Error</></entry>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.96 2006/06/15 18:02:22 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.97 2006/06/16 23:29:26 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="plpgsql">
|
<chapter id="plpgsql">
|
||||||
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
|
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
|
||||||
@ -1076,8 +1076,8 @@ tax := subtotal * 0.06;
|
|||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The result of a <command>SELECT</command> command yielding multiple columns (but
|
The result of a <command>SELECT</command> command yielding multiple
|
||||||
only one row) can be assigned to a record variable, row-type
|
columns (but only one row) can be assigned to a record variable, row-type
|
||||||
variable, or list of scalar variables. This is done by:
|
variable, or list of scalar variables. This is done by:
|
||||||
|
|
||||||
<synopsis>
|
<synopsis>
|
||||||
@ -1126,23 +1126,24 @@ SELECT INTO <optional>STRICT</optional> <replaceable>target</replaceable> <repla
|
|||||||
<replaceable>target</replaceable> will be set to the first row
|
<replaceable>target</replaceable> will be set to the first row
|
||||||
returned by the query, or if the query returned no rows,
|
returned by the query, or if the query returned no rows,
|
||||||
null values are assigned. (Note that <quote>the first row</> is not
|
null values are assigned. (Note that <quote>the first row</> is not
|
||||||
well-defined unless you've used <literal>ORDER BY</>.)
|
well-defined unless you've used <literal>ORDER BY</>.) Any result rows
|
||||||
You can check the special <literal>FOUND</literal> variable to
|
after the first row are discarded.
|
||||||
determine if any rows were found:
|
You can check the special <literal>FOUND</literal> variable (see
|
||||||
|
<xref linkend="plpgsql-statements-diagnostics">) to
|
||||||
|
determine whether a row was returned:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT INTO STRICT myrec * FROM emp WHERE empname = myname;
|
SELECT INTO myrec * FROM emp WHERE empname = myname;
|
||||||
IF NOT FOUND THEN
|
IF NOT FOUND THEN
|
||||||
RAISE EXCEPTION 'employee % not found', myname;
|
RAISE EXCEPTION 'employee % not found', myname;
|
||||||
END IF;
|
END IF;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
If the <literal>STRICT</literal> option is specified, the query must
|
||||||
If the <literal>STRICT</literal> option is specified, a query must
|
|
||||||
return exactly one row or a run-time error will be thrown, either
|
return exactly one row or a run-time error will be thrown, either
|
||||||
<literal>NO_DATA_FOUND</> (no rows) or <literal>TOO_MANY_ROWS</>
|
<literal>NO_DATA_FOUND</> (no rows) or <literal>TOO_MANY_ROWS</>
|
||||||
(more than one row). You can must use exception blocks to determine
|
(more than one row). You can use an exception block if you wish
|
||||||
the number of rows generated by the query:
|
to catch the error, for example:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
BEGIN;
|
BEGIN;
|
||||||
@ -1154,11 +1155,17 @@ BEGIN;
|
|||||||
RAISE EXCEPTION 'employee % not unique', myname;
|
RAISE EXCEPTION 'employee % not unique', myname;
|
||||||
END;
|
END;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Only <command>SELECT INTO STRICT</command> allows you to check if more
|
Successful execution of <command>SELECT INTO STRICT</command>
|
||||||
than one row was retrieved. <command>SELECT INTO STRICT</command>
|
always sets <literal>FOUND</literal> to true.
|
||||||
matches Oracle's PL/SQL <command>SELECT INTO</command> behavior.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
<command>SELECT INTO STRICT</command> matches the behavior of
|
||||||
|
Oracle PL/SQL's <command>SELECT INTO</command> statement.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="plpgsql-statements-perform">
|
<sect2 id="plpgsql-statements-perform">
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.19 2006/03/05 15:59:07 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.20 2006/06/16 23:29:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -331,6 +331,8 @@
|
|||||||
/* Class P0 - PL/pgSQL Error (PostgreSQL-specific error class) */
|
/* Class P0 - PL/pgSQL Error (PostgreSQL-specific error class) */
|
||||||
#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0', '0','0','0')
|
#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0', '0','0','0')
|
||||||
#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0', '0','0','1')
|
#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0', '0','0','1')
|
||||||
|
#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0', '0','0','2')
|
||||||
|
#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0', '0','0','3')
|
||||||
|
|
||||||
/* Class XX - Internal Error (PostgreSQL-specific error class) */
|
/* Class XX - Internal Error (PostgreSQL-specific error class) */
|
||||||
/* (this is for "can't-happen" conditions and software bugs) */
|
/* (this is for "can't-happen" conditions and software bugs) */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.92 2006/06/15 18:02:22 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.93 2006/06/16 23:29:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -157,7 +157,6 @@ static void check_labels(const char *start_label,
|
|||||||
%token K_ELSE
|
%token K_ELSE
|
||||||
%token K_ELSIF
|
%token K_ELSIF
|
||||||
%token K_END
|
%token K_END
|
||||||
%token K_STRICT
|
|
||||||
%token K_EXCEPTION
|
%token K_EXCEPTION
|
||||||
%token K_EXECUTE
|
%token K_EXECUTE
|
||||||
%token K_EXIT
|
%token K_EXIT
|
||||||
@ -187,6 +186,7 @@ static void check_labels(const char *start_label,
|
|||||||
%token K_RETURN_NEXT
|
%token K_RETURN_NEXT
|
||||||
%token K_REVERSE
|
%token K_REVERSE
|
||||||
%token K_SELECT
|
%token K_SELECT
|
||||||
|
%token K_STRICT
|
||||||
%token K_THEN
|
%token K_THEN
|
||||||
%token K_TO
|
%token K_TO
|
||||||
%token K_TYPE
|
%token K_TYPE
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.172 2006/06/16 18:42:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.173 2006/06/16 23:29:27 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1721,7 +1721,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
|
|||||||
{
|
{
|
||||||
if (stmt->strict)
|
if (stmt->strict)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NO_DATA),
|
(errcode(ERRCODE_NO_DATA_FOUND),
|
||||||
errmsg("query returned no rows")));
|
errmsg("query returned no rows")));
|
||||||
|
|
||||||
/* set the target to NULL(s) */
|
/* set the target to NULL(s) */
|
||||||
@ -1732,7 +1732,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
|
|||||||
|
|
||||||
if (n > 1 && stmt->strict)
|
if (n > 1 && stmt->strict)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_CARDINALITY_VIOLATION),
|
(errcode(ERRCODE_TOO_MANY_ROWS),
|
||||||
errmsg("query returned more than one row")));
|
errmsg("query returned more than one row")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.8 2006/06/15 18:02:22 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.9 2006/06/16 23:29:27 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -711,6 +711,14 @@
|
|||||||
"raise_exception", ERRCODE_RAISE_EXCEPTION
|
"raise_exception", ERRCODE_RAISE_EXCEPTION
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"no_data_found", ERRCODE_NO_DATA_FOUND
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"too_many_rows", ERRCODE_TOO_MANY_ROWS
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"internal_error", ERRCODE_INTERNAL_ERROR
|
"internal_error", ERRCODE_INTERNAL_ERROR
|
||||||
},
|
},
|
||||||
@ -722,13 +730,3 @@
|
|||||||
{
|
{
|
||||||
"index_corrupted", ERRCODE_INDEX_CORRUPTED
|
"index_corrupted", ERRCODE_INDEX_CORRUPTED
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"no_data_found", ERRCODE_NO_DATA
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"too_many_rows", ERRCODE_CARDINALITY_VIOLATION
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.51 2006/06/15 18:02:22 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.52 2006/06/16 23:29:27 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -129,7 +129,6 @@ else { return K_ELSE; }
|
|||||||
elseif { return K_ELSIF; }
|
elseif { return K_ELSIF; }
|
||||||
elsif { return K_ELSIF; }
|
elsif { return K_ELSIF; }
|
||||||
end { return K_END; }
|
end { return K_END; }
|
||||||
strict { return K_STRICT; }
|
|
||||||
exception { return K_EXCEPTION; }
|
exception { return K_EXCEPTION; }
|
||||||
execute { return K_EXECUTE; }
|
execute { return K_EXECUTE; }
|
||||||
exit { return K_EXIT; }
|
exit { return K_EXIT; }
|
||||||
@ -158,6 +157,7 @@ return { return K_RETURN; }
|
|||||||
reverse { return K_REVERSE; }
|
reverse { return K_REVERSE; }
|
||||||
row_count { return K_ROW_COUNT; }
|
row_count { return K_ROW_COUNT; }
|
||||||
select { return K_SELECT; }
|
select { return K_SELECT; }
|
||||||
|
strict { return K_STRICT; }
|
||||||
then { return K_THEN; }
|
then { return K_THEN; }
|
||||||
to { return K_TO; }
|
to { return K_TO; }
|
||||||
type { return K_TYPE; }
|
type { return K_TYPE; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user