1.Structure of PL/pgSQL

The structure of PL/pgSQL is like below:

[ <<label>> ]
[ DECLARE declarations ]
BEGIN
statements
END [ label ];

A label is only needed if you want to identify the block for use in an EXIT statement, or to qualify the names of the variables declared in the block. If a label is given after END, it must match the label at the block’s beginning.

Any statement in the statement section of a block can be a subblock. Variables declared in a subblock mask any similarly-named variables of outer blocks for the duration of the subblock; but you can access the outer variables anyway if you qualify their names with their block’s label. For example:

CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE ’Quantity here is %’, quantity; -- Prints 30
quantity := 50;
--
-- Create a subblock
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE ’Quantity here is %’, quantity; -- Prints 80
RAISE NOTICE ’Outer quantity here is %’, outerblock.quantity; -- Prints 50
END;
RAISE NOTICE ’Quantity here is %’, quantity; -- Prints 50
RETURN quantity;
END;
$$ LANGUAGE plpgsql;

There is actually a hidden “outer block” surrounding the body of any PL/pgSQL function


2.Declarations

All variables used in a block must be declared in the declarations section of the block(for expection: loop variable in FOR for integer and record).

name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ];

Here are some examples of variable declarations:

user_id integer;
quantity numeric(5);
url varchar;
myrow tablename%ROWTYPE;
myfield tablename.columnname%TYPE;
arow RECORD;

2.1 Declaring Function Parameters

Parameters passed to functions are named with the identifiers $1, $2 give a name to the parameter in the CREATE FUNCTION command, for example:

	CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql; The other way is to explicitly declare an alias, using the declaration syntax:
CREATE FUNCTION sales_tax(real) RETURNS real AS $$
DECLARE
subtotal ALIAS FOR $1;
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;

2.2 Copying Types

variable%TYPE
%TYPE provides the data type of a variable or table column.

To declare a variable with the same data type as users.user_id you write:

user_id users.user_id%TYPE;

2.3 Row Types

To declare a variable as the same type of a table row, use:

name table_name%ROWTYPE;
name composite_type_name;

A variable of a composite type is called a row variable (or row-type variable). Such a variable can hold a whole row of a SELECT or FOR query result.

The individual fields of the row value are accessed using the usual dot notation, for example rowvar.field.

2.4 Record Types

To declare a variable to store a unknown table row type, use:

name RECORD;

Record variables are similar to row-type variables, but they have no predefined structure.

The substructure of a record variable can change each time it is assigned to.RECORD is not a true data type, only a placeholder.


3.Expressions

All expressions used in PL/pgSQL statements are processed using the server’s main SQL executor.

For example, when you write a PL/pgSQL statement like:

IF expression THEN ...

PL/pgSQL will evaluate the expression by feeding a query like:

SELECT expression

For example, if we have declared two integer variables x and y, and we write

IF x < y THEN ...

what happens behind the scenes is equivalent to

PREPARE statement_name(integer, integer) AS SELECT $1 < $2;

and then this prepared statement is EXECUTEd for each execution of the IF statement, with the current values of the PL/pgSQL variables supplied as parameter values.


4.Basic Statements

In this section and the following ones, we describe all the statement types that are explicitly understood by PL/pgSQL.

4.1 Assignment

An assignment of a value to a PL/pgSQL variable is written as:
variable { := | = } expression;

4.2 Executing a Command With No Result**

For any SQL command that does not return rows, for example INSERT without a RETURNING clause, you can execute the command within a PL/pgSQL function just by writing the command.

To evaluate an expression or SELECT query but discard the result, use:

PERFORM query;

PERFORM  functionxxx();
PERFORM * from tablexxx;

4.3 Executing a Query with a Single-row Result

The result of a SQL command yielding a single row (possibly of multiple columns) can be assigned to a record variable, row-type variable, or list of scalar variables. This is done by writing the base SQL command and adding an INTO clause. For example,

	SELECT select_expressions INTO [STRICT] target FROM ...;
INSERT ... RETURNING expressions INTO [STRICT] target;
UPDATE ... RETURNING expressions INTO [STRICT] target;
DELETE ... RETURNING expressions INTO [STRICT] target;

(here,INTO means pass a value to the variable target ,but not insert into a table,if you want to do so ,use:

CREATE TABLE ... AS SELECT clause)

The INTO clause can appear almost anywhere in the SQL command. Customarily it is written either just before or just after the list of select_expressions in a SELECT command, or at the end of the command for other command types. It is recommended that you follow this convention in case the PL/pgSQL parser becomes stricter in future versions.

4.4 Executing Dynamic Commands

Oftentimes you will want to generate dynamic commands inside your PL/pgSQL functions, that is, commands that will involve different tables or different data types each time they are executed.

EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];

command-string is an expression yielding a string (of type text) containing the command to be executed.

The optional target is a record variable, a row variable, or a comma-separated list of simple variables and record/row fields, into which the results of the command will be stored.

The optional USING expressions supply values to be inserted into the command.

The INTO clause specifies where the results of a SQL command returning rows should be assigned.

If the STRICT option is given, an error is reported unless the query produces exactly one row.

An example is:

EXECUTE ’SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2’
INTO c
USING checked_user, checked_date;

Note that parameter symbols can only be used for data values — if you want to use dynamically determined table or column names, you must insert them into the command string textually.

to use dynamically determined table or column names, use function quote_ident() to turn text to SQL identifier:

EXECUTE ’SELECT count(*) FROM ’
|| quote_ident(tabname)
|| ’ WHERE inserted_by = $1 AND inserted <= $2’
INTO c
USING checked_user, checked_date;

A cleaner approach is to use format()’s %I specification for table or column names (strings separated by a newline are concatenated):

EXECUTE format(’SELECT count(*) FROM %I ’
’WHERE inserted_by = $1 AND inserted <= $2’, tabname)
INTO c
USING checked_user, checked_date;

Another restriction on parameter symbols is that they only work in SELECT, INSERT, UPDATE, and DELETE commands. In other statement types (generically called utility statements), you must insert values textually even if they are just data values.


5.Obtaining the Result Status

There are several ways to determine the effect of a command(GET DIAGNOSTICS and FOUND).

The first method is to use the GET DIAGNOSTICS command, which has the form:

GET [ CURRENT ] DIAGNOSTICS variable { = | := } item [ , ... ];

This command allows retrieval of system status indicators. CURRENT is a noise word. Each item is a key word identifying a status value to be assigned to the specified variable (which should be of the right data type to receive it). The currently available status items are shown below.

The second method to determine the effects of a command is to check the special variable named FOUND, which is of type boolean. FOUND starts out false within each PL/pgSQL function call. It is set by each of the following types of statements:

  • A SELECT INTO statement sets FOUND true if a row is assigned, false if no row is returned.
  • A PERFORM statement sets FOUND true if it produces (and discards) one or more rows, false if no row is

    produced.
  • UPDATE, INSERT, and DELETE statements set FOUND true if at least one row is affected, false if no row

    is affected.
  • A FETCH statement sets FOUND true if it returns a row, false if no row is returned.
  • A MOVE statement sets FOUND true if it successfully repositions the cursor, false otherwise.
  • A FOR or FOREACH statement sets FOUND true if it iterates one or more times, else false. FOUND is

    set this way when the loop exits; inside the execution of the loop, FOUND is not modified by the loop

    statement, although it might be changed by the execution of other statements within the loop body.
  • RETURN QUERY and RETURN QUERY EXECUTE statements set FOUND true if the query returns at least

    one row, false if no row is returned.

Other PL/pgSQL statements do not change the state of FOUND. Note in particular that EXECUTE changes the output of GET DIAGNOSTICS, but does not change FOUND. FOUND is a local variable within each PL/pgSQL function; any changes to it affect only the current function.


6.Doing Nothing At All

Sometimes a placeholder statement that does nothing is useful. For example, it can indicate that one arm of an if/then/else chain is deliberately empty. For this purpose, use the NULL statement:

NULL;

For example, the following two fragments of code are equivalent:

BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
NULL; -- ignore the error
END;
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN -- ignore the error
END;

Which is preferable is a matter of taste.

postgreSQL PL/SQL编程学习笔记(一)的更多相关文章

  1. postgreSQL PL/SQL编程学习笔记(二)

    Control Structures of PL/SQL Control structures are probably the most useful (and important) part of ...

  2. postgreSQL PL/SQL编程学习笔记(六)——杂七杂八

    1 PL/pgSQL Under the Hood This part discusses some implementation details that are frequently import ...

  3. postgreSQL PL/SQL编程学习笔记(五)——触发器(Triggers)

    Trigger Procedures PL/pgSQL can be used to define trigger procedures on data changes or database eve ...

  4. postgreSQL PL/SQL编程学习笔记(三)——游标(Cursors)

    Cursors Rather than executing a whole query at once, it is possible to set up a cursor that encapsul ...

  5. postgreSQL PL/SQL编程学习笔记(四)

    Errors and Messages 1. Reporting Errors and Messages Use the RAISE statement to report messages and ...

  6. MySql-Mysql技术内幕~SQL编程学习笔记(N)

    1._rowid 类似Oracle的rowid mysql> ; +-------+----+----------------+-------------+---------------+--- ...

  7. MySql-Mysql技术内幕~SQL编程学习笔记(1)

    1.MySQL的历史,一些相关概念. 2.MySQL数据类型 *通常一个页内可以存放尽可能多的行,那么数据库的性能就越好,选择一个正确的数据类型至关重要. 1>UNSIGNED类型: 将数字类型 ...

  8. PL/SQL个人学习笔记(二)

    IF条件 declare cursor s is            select version from city_server t;   s_ city_server.version%type ...

  9. PL/SQL个人学习笔记

    资料1 -- Created on 2014/8/20  declare    -- Local variables here   i integer; begin   i := 12;   -- T ...

随机推荐

  1. SQL Server Database Backup and Restore in C#

    SQL Server Database Backup and Restore in C# Syed Noman Ali Shah,                          7 Feb 201 ...

  2. HashMap与ConcurrentHashMap的区别(转)

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  3. 24-从零玩转JavaWeb-包装类、自动装箱、自动拆箱

    一.什么是包装类 二.对基本数据类型包装的好处 三.装箱操作 四.拆箱操作 五.自动装箱 六.自动拆箱 七.字符串与基本数据类型和包装类的转换   八.包装类的缓存设计

  4. codeforce452DIV2——F. Letters Removing

    题意:给一个字符串和m个操作,每次给出l,r,c,把字符串中l-r这段区间的字符为c的字符删掉,求最后的字符串.(n,m<=2e5)线段树.注意这个区间修改和普通区间修改的区别. 他们都是用树状 ...

  5. [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)

    解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...

  6. 【NOIP2008】传纸条

    [描述] Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就 ...

  7. nginx+django+uwsgi

    最近来了兴致,想搞一下django开发,so,  搭建一下环境 1.安装django,可能通过pip install 或者源码安装(因为环境是python2.6.6的环境,所以这里采用django 1 ...

  8. Spring.Web.Mvc 注入(控制器属性注入)

    1.web.config配置 <?xml version="1.0" encoding="utf-8"?><!-- 有关如何配置 ASP.NE ...

  9. hadoop2.2分布式环境搭建

    hadoop2.2的分布式环境需要配置的参数更多.但是需要安装的系统软件和单节点环境是一样的. 运行hadoop在非安全环境 hadoop的配置文件有两类: 1:只读的默认配置文件: core-def ...

  10. 7.python实现高效端口扫描器之nmap模块

    对于端口扫描,使用的最多的就是nmap这个工具,不想python已经强大到,提供了nmap这个扫描端口的模块. 本片文章主要介绍nmap模块的两个常用类: PortScanner()类,实现一个nma ...