-
示例 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 --建表
gaussdb=# CREATE SCHEMA hr;
CREATE SCHEMA
gaussdb=# SET CURRENT_SCHEMA = hr;
SET
gaussdb=# CREATE TABLE staffs
(
section_id INTEGER,
salary INTEGER
);
CREATE TABLE
gaussdb=# INSERT INTO staffs VALUES (30, 10);
INSERT 0 1
gaussdb=# INSERT INTO staffs VALUES (30, 20);
INSERT 0 1
--创建存储过程proc_staffs
gaussdb=# CREATE OR REPLACE PROCEDURE proc_staffs
(
section NUMBER(6),
salary_sum out NUMBER(8,2),
staffs_count out INTEGER
)
IS
BEGIN
SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM hr.staffs where section_id = section;
END;
/
CREATE PROCEDURE
--创建存储过程proc_return.
gaussdb=# CREATE OR REPLACE PROCEDURE proc_return
AS
v_num NUMBER(8,2);
v_sum INTEGER;
BEGIN
proc_staffs(30, v_sum, v_num); --调用语句
dbe_output.print_line(v_sum||'#'||v_num);
RETURN; --返回语句
END;
/
CREATE PROCEDURE
--调用存储过程proc_return.
gaussdb=# CALL proc_return();
30#2.00
proc_return
-------------
(1 row)
--清除存储过程
gaussdb=# DROP PROCEDURE proc_staffs;
DROP PROCEDURE
gaussdb=# DROP PROCEDURE proc_return;
DROP PROCEDURE
gaussdb=# DROP TABLE staffs;
DROP TABLE
-
变量作用域 变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。 变量必须在declare部分声明,即必须建立BEGIN-END块。块结构也强制变量必须先声明后使用,即变量在过程内有不同作用域、不同的生存期。 同一变量可以在不同的作用域内定义多次,内层的定义会覆盖外层的定义。 在外部块定义的变量,可以在嵌套块中使用。但外部块不能访问嵌套块中的变量。 示例 gaussdb=# DECLARE
emp_id INTEGER :=7788; --定义变量并赋值
outer_var INTEGER :=6688; --定义变量并赋值
BEGIN
DECLARE
emp_id INTEGER :=7799; --定义变量并赋值
inner_var INTEGER :=6688; --定义变量并赋值
BEGIN
dbe_output.print_line('inner emp_id ='||emp_id); --显示值为7799
dbe_output.print_line('outer_var ='||outer_var); --引用外部块的变量
END;
dbe_output.print_line('outer emp_id ='||emp_id); --显示值为7788
END;
/
inner emp_id =7799
outer_var =6688
outer emp_id =7788
ANONYMOUS BLOCK EXECUTE
-
变量声明 变量声明语法请参见图1。 图1 declare_variable::= 对以上语法格式的解释如下: variable_name:变量名。 type:变量类型。 value:该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。 示例 1
2
3
4
5
6
7 gaussdb=# DECLARE
emp_id INTEGER := 7788; --定义变量并赋值
BEGIN
emp_id := 5*7784; --变量赋值
END;
/
ANONYMOUS BLOCK EXECUTE
-
语法格式 SELECT select_expressions INTO [STRICT] target FROM ...
SELECT INTO [STRICT] target [FROM ..]
EXECUTE [IMMEDIATE] select_expressions BULK COLLECT INTO target ... 对以上语法格式的解释如下: select_expressions:查询的SQL语句。通过基础SQL命令加INTO子句可以将单行或多列的结果赋值给一个变量(记录、行类型和标量变量列表)。 target :目标变量。可以是一个记录变量、一个行变量或一个有逗号分隔的简单变量和记录/行域列表。 STRICT:可选。在开启参数behavior_compat_options = 'select_into_return_null'的前提下(默认未开启),若指定该选项则该查询必须刚好返回一行不为空的结果集,否则会报错,报错信息可能是NO_DATA_FOUND(没有行)、TOO_MANY_ROWS(多于一行)或QUERY_RETURNED_NO_ROWS (没有数据返回)。若不指定该选项则没有该限定,且支持返回空结果集。 BULK COLLECT INTO只支持批量赋值给数组或集合。集合类型合理使用LIMIT字段避免操作过量数据导致性能下降。 INTO/BULK COLLECT INTO只支持4层以下Record类型直接嵌套。 返回空结果集需要数据库初始化使用PG兼容参数,配置GUC参数behavior_compat_options = 'select_into_return_null'为开启。配置GUC参数behavior_compat_options = ''则关闭。 对于数组变量,小括号“()”将优先识别为下标,因此对于带括号的表达式,不支持写在数组变量后面。如对于select (1+3) into va(5),不支持写为select into va(5) (1+3)或select into va[5] (1+3)。 INSERT INTO、UPDATE INTO、DELETE INTO和EXECUTION INTO不支持返回空结果集。 给多个变量赋值时,由于后面的变量存在语法错误,所以均不赋值。 BULK COLLECT INTO只支持在A兼容性数据库下使用。 IMMEDIATE关键字仅用作语法兼容,无实际意义。
-
变量语法 给变量赋值的语法请参见图1。 图1 assignment_value::= 对以上语法格式的解释如下: variable_name:变量名。 value:可以是值或表达式。值value的类型需要和变量variable_name的类型兼容才能正确赋值。 示例: 1
2
3
4
5
6
7
8
9
10
11
12
13 DECLARE
emp_id INTEGER := 7788;--赋值
BEGIN
emp_id := 5;--赋值
DBE_OUTPUT.PRINT_LINE(emp_id);
emp_id := 5*7784;
DBE_OUTPUT.PRINT_LINE(emp_id);
END;
/
--结果如下:
5
38920
ANONYMOUS BLOCK EXECUTE
-
嵌套赋值 给变量嵌套赋值的语法请参见图2。 图2 nested_assignment_value::= 对以上语法格式的解释如下:图2 variable_name:变量名。 col_name:列名。 subscript:下标,针对数组变量使用,可以是值或表达式,类型必须为INT。 value:可以是值或表达式。值value的类型需要和变量variable_name的类型兼容才能正确赋值。 示例: 1
2
3
4
5
6
7
8
9
10
11 gaussdb=# CREATE TYPE o1 AS (a int, b int);
CREATE TYPE
gaussdb=# DECLARE
TYPE r1 is VARRAY(10) of o1;
emp_id r1;
BEGIN
emp_id(1).a := 5;--赋值
emp_id(1).b := 5*7784;
END;
/
ANONYMOUS BLOCK EXECUTE
-
变量声明 变量声明语法如图1所示。 图1 declare_variable::= 对以上语法格式的解释如下: variable_name,为变量名。 type,为变量类型。 value,是该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。 示例 1
2
3
4
5
6 gaussdb=# DECLARE
emp_id INTEGER := 7788; --定义变量并赋值
BEGIN
emp_id := 5*7784; --变量赋值
END;
/
-
变量作用域 变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。 变量必须在declare部分声明,即必须建立BEGIN-END块。块结构也强制变量必须先声明后使用,即变量在过程内有不同作用域、不同的生存期。 同一变量可以在不同的作用域内定义多次,内层的定义会覆盖外层的定义。 在外部块定义的变量,可以在嵌套块中使用。但外部块不能访问嵌套块中的变量。 示例 1
2
3
4
5
6
7
8
9
10
11
12
13
14 gaussdb=# DECLARE
emp_id INTEGER :=7788; --定义变量并赋值
outer_var INTEGER :=6688; --定义变量并赋值
BEGIN
DECLARE
emp_id INTEGER :=7799; --定义变量并赋值
inner_var INTEGER :=6688; --定义变量并赋值
BEGIN
dbe_output.print_line('inner emp_id ='||emp_id); --显示值为7799
dbe_output.print_line('outer_var ='||outer_var); --引用外部块的变量
END;
dbe_output.print_line('outer emp_id ='||emp_id); --显示值为7788
END;
/
-
变量赋值示例 1
2
3
4
5
6
7
8
9
10
11
12
13 DECLARE
emp_id INTEGER := 7788;--赋值
BEGIN
emp_id := 5;--赋值
DBE_OUTPUT.PRINT_LINE(emp_id);
emp_id := 5*7784;
DBE_OUTPUT.PRINT_LINE(emp_id);
END;
/
--结果如下:
5
38920
ANONYMOUS BLOCK EXECUTE
-
语法格式 SELECT select_expressions INTO [STRICT] target FROM ...
SELECT INTO [STRICT] target [FROM ..]
EXECUTE [IMMEDIATE] select_expressions BULK COLLECT INTO target ... 对以上语法格式的解释如下: select_expressions:查询的SQL语句。通过基础SQL命令加INTO子句可以将单行或多列的结果赋值给一个变量(记录、行类型和标量变量列表)。 target :目标变量。可以是一个记录变量、一个行变量或一个有逗号分隔的简单变量和记录/行域列表。 STRICT:可选。在开启GUC参数behavior_compat_options = 'select_into_return_null'的前提下(默认未开启),若指定该选项则该查询必须刚好返回一行不为空的结果集,否则会报错,报错信息可能是NO_DATA_FOUND(没有行)、TOO_MANY_ROWS(多于一行)或QUERY_RETURNED_NO_ROWS(没有数据返回)。若不指定该选项则没有该限定,且支持返回空结果集。 BULK COLLECT INTO只支持批量赋值给数组或集合类型,合理使用LIMIT字段避免操作过量数据导致性能下降。 INTO/BULK COLLECT INTO只支持4层以下Record类型直接嵌套。 返回空结果集需要数据库初始化使用PG兼容参数,设置GUC参数behavior_compat_options = 'select_into_return_null' 为开启。设置GUC参数behavior_compat_options = '' 则关闭。 对于数组变量,小括号()将优先识别为下标,因此对于带括号的表达式,不支持写在数组变量后面。如对于SELECT (1+3) INTO va(5),不支持写为SELECT INTO va(5) (1+3)或SELECT INTO va[5] (1+3)。 BULK COLLECT INTO 只支持在ORA兼容性数据库下使用。 IMMEDIATE关键字仅用作语法兼容,无实际意义。
-
示例 gaussdb=# DROP TABLE IF EXISTS customers;
gaussdb=# CREATE TABLE customers(id int,name varchar);
gaussdb=# INSERT INTO customers VALUES(1,'ab');
gaussdb=# DECLARE
my_id integer;
BEGIN
select id into my_id from customers limit 1; -- 赋值
END;
/
ANONYMOUS BLOCK EXECUTE
gaussdb=# DECLARE
type id_list is varray(6) of customers.id%type;
id_arr id_list;
BEGIN
select id bulk collect into id_arr from customers order by id DESC limit 20; -- 批量赋值
END;
/
ANONYMOUS BLOCK EXECUTE
gaussdb=# DECLARE
TYPE id_list IS varray(6) OF customers.id%type;
id_arr id_list;
sql_qry varchar2(150);
BEGIN
sql_qry := 'SELECT id FROM customers ORDER BY id DESC LIMIT 20';
EXECUTE IMMEDIATE sql_qry BULK COLLECT INTO id_arr; -- 批量赋值
END;
/
ANONYMOUS BLOCK EXECUTE
-
示例 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 --建表
gaussdb=# CREATE SCHEMA hr;
gaussdb=# SET CURRENT_SCHEMA = hr;
gaussdb=# CREATE TABLE staffs
(
section_id INTEGER,
salary INTEGER
);
gaussdb=# INSERT INTO staffs VALUES (30, 10);
gaussdb=# INSERT INTO staffs VALUES (30, 20);
--创建存储过程proc_staffs
gaussdb=# CREATE OR REPLACE PROCEDURE proc_staffs
(vIM
section NUMBER(6),
salary_sum out NUMBER(8,2),
staffs_count out INTEGER
)
IS
BEGIN
SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM hr.staffs where section_id = section;
END;
/
CREATE PROCEDURE
--创建存储过程proc_return.
gaussdb=# CREATE OR REPLACE PROCEDURE proc_return
AS
v_num NUMBER(8,2);
v_sum INTEGER;
BEGIN
proc_staffs(30, v_sum, v_num); --调用语句
dbe_output.print_line(v_sum||'#'||v_num);
RETURN; --返回语句
END;
/
CREATE PROCEDURE
--调用存储过程proc_return.
gaussdb=# CALL proc_return();
30#2.00
proc_return
-------------
(1 row)
--清除存储过程
gaussdb=# DROP PROCEDURE proc_staffs;
gaussdb=# DROP PROCEDURE proc_return;
--创建函数func_return.
gaussdb=# CREATE OR REPLACE FUNCTION func_return returns void
language plpgsql
AS $$
DECLARE
v_num INTEGER := 1;
BEGIN
dbe_output.print_line(v_num);
RETURN; --返回语句
END $$;
CREATE FUNCTION
-- 调用函数func_return
gaussdb=# CALL func_return();
1
func_return
-------------
(1 row)
-- 清除函数
gaussdb=# DROP FUNCTION func_return;
-- 清除当前数据库模式
gaussdb=# DROP SCHEMA hr CASCADE;
-
示例 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 gaussdb=# DROP SCHEMA IF EXISTS hr CASCADE;
gaussdb=# CREATE SCHEMA hr;
gaussdb=# SET CURRENT_SCHEMA = hr;
gaussdb=# CREATE TABLE staffs
(
section_id NUMBER,
first_name VARCHAR2,
phone_number VARCHAR2,
salary NUMBER
);
gaussdb=# INSERT INTO staffs VALUES (30, 'mike', '13567829252', 5800);
gaussdb=# INSERT INTO staffs VALUES (40, 'john', '17896354637', 4000);
--创建存储过程proc_staffs
gaussdb=# CREATE OR REPLACE PROCEDURE proc_staffs
(
section NUMBER(6),
salary_sum out NUMBER(8,2),
staffs_count out INTEGER
)
IS
BEGIN
SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM hr.staffs where section_id = section;
END;
/
CREATE PROCEDURE
--创建存储过程proc_return.
gaussdb=# CREATE OR REPLACE PROCEDURE proc_return
AS
v_num NUMBER(8,2);
v_sum INTEGER;
BEGIN
proc_staffs(30, v_sum, v_num); --调用语句
dbe_output.print_line(v_sum||'#'||v_num);
RETURN; --返回语句
END;
/
--调用存储过程proc_return.
gaussdb=# CALL proc_return();
5800#1.00
proc_return
-------------
(1 row)
--清除存储过程
gaussdb=# DROP PROCEDURE proc_staffs;
gaussdb=# DROP PROCEDURE proc_return;
--创建函数func_return.
gaussdb=# CREATE OR REPLACE FUNCTION func_return returns void
language plpgsql
AS $$
DECLARE
v_num INTEGER := 1;
BEGIN
dbe_output.print_line(v_num);
RETURN; --返回语句
END $$;
CREATE FUNCTION
-- 调用函数func_return
gaussdb=# CALL func_return();
1
func_return
-------------
(1 row)
-- 清除函数
gaussdb=# DROP FUNCTION func_return;
-
示例 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 gaussdb=# CREATE TABLE staffs ( section_id INTEGER, salary INTEGER );
CREATE TABLE
gaussdb=# INSERT INTO staffs VALUES (30, 10);
INSERT 0 1
gaussdb=# INSERT INTO staffs VALUES (30, 20);
INSERT 0 1
--创建存储过程proc_staffs
gaussdb=# CREATE OR REPLACE PROCEDURE proc_staffs
(
section NUMBER(6),
salary_sum out NUMBER(8,2),
staffs_count out INTEGER
)
IS
BEGIN
SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM staffs where section_id = section;
END;
/
CREATE PROCEDURE
--调用存储过程proc_return.
gaussdb=# CALL proc_staffs(2,8,6);
salary_sum | staffs_count
------------+--------------
| 0
(1 row)
--清除存储过程
gaussdb=# DROP PROCEDURE proc_staffs;
DROP PROCEDURE
DECLARE
DROP TABLE
-
变量赋值示例 1
2
3
4
5
6
7
8
9
10
11
12
13 gaussdb=# DECLARE
emp_id INTEGER := 7788;--赋值
BEGIN
emp_id := 5;--赋值
DBE_OUTPUT.PRINT_LINE(emp_id);
emp_id := 5*7784;
DBE_OUTPUT.PRINT_LINE(emp_id);
END;
/
--结果如下:
5
38920
ANONYMOUS BLOCK EXECUTE