以美元符号作为引号的字符串常量
本章将讨论如何在 PL/pgSQL 编程中使用以美元符号作为引号的字符串常量。块结构
本章将讨论 PL/pgSQL 的块结构,同时也会带你编写第一个 PL/pgSQL 程序。变量
本章将学习 PL/pgSQL 变量的相关知识。行类型
本章将讨论 PL/pgSQL 的行类型。将一个变量声明为行类型之后,它便可以保存数据库中的整行数据。记录类型
本章我们讨论 PostgreSQL 的记录类型,它和行类型相似,也可以存储数据库中的整行信息。常量
本章将讨论 PL/pgSQL 常量。错误和异常处理
本章我们将讨论 PL/pgSQL 的错误和异常处理。控制结构
本章将讨论 PL/pgSQL 的控制结构,包括:IF、CASE、LOOP、WHILE LOOP、FOR LOOP、EXIT和CONTINUE等语句。函数
本章我们将讨论自定义函数的相关知识,包括:创建函数、函数参数的模式、函数重载、返回表的函数以及删除函数等知识。存储过程
本章我们将讨论存储过程。游标
本章我们将讨论 PL/pgSQL 的游标以及如何使用它们逐行处理结果集。触发器
本章将讨论触发器,包括:创建、删除、更新、禁用、启用触发器等知识。
控制结构
- 292
- 2023-08-01 11:34:26
本章将讨论 PL/pgSQL 的控制结构,包括:IF、CASE、LOOP、WHILE LOOP、FOR LOOP、EXIT和CONTINUE等语句。
IF
语句
IF THEN
IF THEN ELSE
IF THEN ELSIF
IF THEN
语句
它的最简单形式是:
if 条件 then
语句;
end if;
示例:
do $$
declare
selected_film film%rowtype;
input_film_id film.film_id%type := 0;
begin
select * from film
into selected_film
where film_id = input_film_id;
if not found then
raise notice'The film % could not be found',
input_film_id;
end if;
end $$;
found
是 PL/pgSQL 中的全局变量,如果分配了行,则SELECT INTO
语句将found
设置为true
;否则,将found
设置为false
IF-THEN-ELSE
语句
语法如下:
if 条件 then
语句;
else
其它语句;
END if;
示例:
do $$
declare
selected_film film%rowtype;
input_film_id film.film_id%type := 100;
begin
select * from film
into selected_film
where film_id = input_film_id;
if not found then
raise notice 'The film % could not be found',
input_film_id;
else
raise notice 'The film title is %', selected_film.title;
end if;
end $$;
IF-THEN-ELSIF
语句
语法如下:
if 条件1 then
语句1;
elsif 条件2 then
语句2;
...
elsif 条件n then
语句n;
else
其它语句;
end if;
示例:
do $$
declare
v_film film%rowtype;
len_description varchar(100);
begin
select * from film
into v_film
where film_id = 100;
if not found then
raise notice 'Film not found';
else
if v_film.length >0 and v_film.length <= 50 then
len_description := 'Short';
elsif v_film.length > 50 and v_film.length < 120 then
len_description := 'Medium';
elsif v_film.length > 120 then
len_description := 'Long';
else
len_description := 'N/A';
end if;
raise notice 'The % film is %.',
v_film.title,
len_description;
end if;
end $$;
CASE
语句
CASE
语句根据条件从 WHEN
列表中选择要执行的部分,它有两种形式:
- 简单的
CASE
语句 - 搜索型
CASE
语句
不要混淆
CASE
语句和CASE
表达式。
不要混淆 CASE
语句和 CASE
表达式。
简单CASE
语句
case 计算表达式
when 表达式1 [, 表达式2, ...] then
语句
[ ... ]
[else
其它语句 ]
END case;
示例:
do $$
declare
rate film.rental_rate%type;
price_segment varchar(50);
begin
select rental_rate into rate
from film
where film_id = 100;
if found then
case rate
when 0.99 then
price_segment = 'Mass';
when 2.99 then
price_segment = 'Mainstream';
when 4.99 then
price_segment = 'High End';
else
price_segment = 'Unspecified';
end case;
raise notice '%', price_segment;
end if;
end $$;
语法:
case
when 布尔表达式1 then
语句1
[ when 布尔表达式2 then
语句2
... ]
[ else
其它语句 ]
end case;
示例:
do $$
declare
total_payment numeric;
service_level varchar(25) ;
begin
select sum(amount) into total_payment
from Payment
where customer_id = 100;
if found then
case
when total_payment > 200 then
service_level = 'Platinum' ;
when total_payment > 100 then
service_level = 'Gold' ;
else
service_level = 'Silver' ;
end case;
raise notice 'Service Level: %', service_level;
else
raise notice 'Customer not found';
end if;
end $$;
LOOP
语句
LOOP
定义一个无限循环,直到被 exit
或 return
语句终止。语法如下:
<<标签>>
loop
语句;
end loop;
通常会在循环体中使用 IF
来根据条件终止循环:
<<标签>>
loop
语句;
if 条件 then
exit;
end if;
end loop;
示例:计算斐波那契数列:
do $$
declare
n integer:= 10;
fib integer := 0;
counter integer := 0 ;
i integer := 0 ;
j integer := 1 ;
begin
if (n < 1) then
fib := 0 ;
end if;
loop
exit when counter = n ;
counter := counter + 1 ;
select j, i + j into i, j ;
end loop;
fib := i;
raise notice '%', fib;
end $$;
WHILE LOOP
语句
[ <<标签>> ]
while 条件 loop
语句;
end loop;
示例:
do $$
declare
counter integer := 0;
begin
while counter < 5 loop
raise notice 'Counter %', counter;
counter := counter + 1;
end loop;
end$$;
FOR LOOP
语句
用于迭代一系列整数值或查询的结果集。
语法一:迭代一系列整数值:
[ <<label>> ]
for loop_counter in [ reverse ] from.. to [ by step ] loop
statements
end loop [ label ];
示例:
do $$
begin
for counter in 1..5 loop
raise notice 'counter: %', counter;
end loop;
end $$;
语法二:迭代查询结果集:
[ <<label>> ]
for target in query loop
statements
end loop [ label ];
示例:
do
$$
declare
f record;
begin
for f in select title, length
from film
order by length desc, title
limit 10
loop
raise notice '%(% mins)', f.title, f.length;
end loop;
end $$;
语法三:迭代动态查询的结果集:
[ <<label>> ]
for row in execute query_expression [ using query_param [, ... ] ]
loop
statements
end loop [ label ];
EXIT
语句
用于终止各种循环,语法:
exit [label] [when boolean_expression]
以下语句是等效的:
EXIT WHEN counter > 10;
-- 等效于
IF counter > 10 THEN
EXIT;
END IF;
除了用于终止循环,还可以用来终止由 BEGIN...END
定义的块:
<<block_label>>
BEGIN
-- some code
EXIT [block_label] [WHEN condition];
-- some more code
END block_label;
示例:
do $$
declare
i int = 0;
j int = 0;
begin
<<outer_loop>>
loop
i = i + 1;
exit when i > 3;
-- inner loop
j = 0;
<<inner_loop>>
loop
j = j + 1;
exit when j > 3;
raise notice '(i,j): (%,%)', i, j;
end loop inner_loop;
end loop outer_loop;
end $$;
示例二:
do $$
begin
<<simple_block>>
begin
exit simple_block;
raise notice '%', 'unreachable!';
end;
raise notice '%', 'End of block';
end $$;
CONTINUE
语句
用于结束当前循环,跳转到下一个循环。语法:
continue [loop_label] [when condition]
示例:打印10以内的奇数
do
$$
declare
counter int = 0;
begin
loop
counter = counter + 1;
exit when counter > 10;
continue when mod(counter,2) = 0;
raise notice '%', counter;
end loop;
end;
$$