云服务器内容精选

  • RETURN NEXT及RETURN QUERY 语法 创建函数时需要指定返回值SETOF datatype。 return_next_clause::= return_query_clause::= 对以上语法的解释如下: 当需要函数返回一个集合时,使用RETURN NEXT或者RETURN QUERY向结果集追加结果,然后继续执行函数的下一条语句。随着后续的RETURN NEXT或RETURN QUERY命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。 RETURN NEXT可用于标量和复合数据类型。 RETURN QUERY有一种变体RETURN QUERY EXECUTE,后面还可以增加动态查询,通过USING向查询插入参数。 示例 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 CREATE TABLE t1(a int); INSERT INTO t1 VALUES(1),(10); --RETURN NEXT CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; call fun_for_return_next(); a --- 1 10 (2 rows)
  • RETURN 语法 返回语句的语法请参见图1。 图1 return_clause::= 对以上语法的解释如下: 用于将控制从存储过程或函数返回给调用者。 示例 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 --创建存储过程proc_staffs 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; / --创建存储过程proc_return. CREATE OR REPLACE PROCEDURE proc_return AS v_num NUMBER(8,2); v_sum INTEGER; BEGIN proc_staffs(30, v_sum, v_num); --调用语句 dbms_output.put_line(v_sum||'#'||v_num); RETURN; --返回语句 END; / --调用存储过程proc_return. CALL proc_return(); --清除存储过程 DROP PROCEDURE proc_staffs; DROP PROCEDURE proc_return; --创建函数func_return. CREATE OR REPLACE FUNCTION func_return returns void language plpgsql AS $$ DECLARE v_num INTEGER := 1; BEGIN dbms_output.put_line(v_num); RETURN; --返回语句 END $$; -- 调用函数func_return CALL func_return(); 1 -- 清除函数 DROP FUNCTION func_return;
  • FORALL批量查询语句 语法图 图5 forall::= label declaration ::= 变量index会自动定义为integer类型并且只在此循环里存在。index的取值介于low_bound和upper_bound之间。 如果声明了SAVE EXCEPTIONS,则会将循环体DML执行过程中每次遇到的异常保存在SQL&BULK_EXCEPTIONS中,并在执行结束后统一抛出一个异常,循环过程中没有异常的执行的结果在当前子事务内不会回滚。 示例 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 gaussdb=# CREATE TABLE hdfs_t1 ( title NUMBER(6), did VARCHAR2(20), data_period VARCHAR2(25), kind VARCHAR2(25), interval VARCHAR2(20), time DATE, isModified VARCHAR2(10) ); CREATE TABLE gaussdb=# INSERT INTO hdfs_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' ); INSERT 0 1 gaussdb=# CREATE OR REPLACE PROCEDURE proc_forall() AS BEGIN FORALL i IN 100..120 update hdfs_t1 set title = title + 100*i; END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL proc_forall(); proc_forall ------------- (1 row) --查询存储过程调用结果 gaussdb=# SELECT * FROM hdfs_t1; title | did | data_period | kind | interval | time | ismodified --------+--------+-------------+----------+--------------+---------------------+------------ 231008 | Donald | OConnell | DOCONNEL | 650.507.9833 | 1999-06-21 00:00:00 | SH_CLERK (1 row) --删除存储过程和表 gaussdb=# DROP PROCEDURE proc_forall; DROP PROCEDURE gaussdb=# DROP TABLE hdfs_t1; DROP TABLE
  • FOR_LOOP(integer变量)语句 语法图 图3 for_loop::= label declaration ::= 变量name会自动定义为integer类型并且只在此循环里存在。变量name介于lower_bound和upper_bound之间。 当使用REVERSE关键字时,lower_bound必须大于等于upper_bound,否则循环体不会被执行。 示例 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 --从0到5进行循环 gaussdb=# CREATE OR REPLACE PROCEDURE proc_for_loop() AS BEGIN FOR I IN 0..5 LOOP DBE_OUTPUT.PRINT_LINE('It is '||to_char(I) || ' time;') ; END LOOP; END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL proc_for_loop(); It is 0 time; It is 1 time; It is 2 time; It is 3 time; It is 4 time; It is 5 time; proc_for_loop --------------- (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE proc_for_loop; DROP PROCEDURE
  • FORALL批量查询语句 语法图 forall::=语句图图9所示。 图9 forall::= label declaration ::语句如图10所示。 图10 label declaration ::= 变量index会自动定义为integer类型并且只在此循环里存在。index的取值介于low_bound和upper_bound之间。 示例 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 gaussdb=# CREATE TABLE TEST_t1 ( title NUMBER(6), did VARCHAR2(20), data_period VARCHAR2(25), kind VARCHAR2(25), interval VARCHAR2(20), time DATE, isModified VARCHAR2(10) ) DISTRIBUTE BY hash(did); CREATE TABLE gaussdb=# INSERT INTO TEST_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' ); INSERT 0 1 gaussdb=# CREATE OR REPLACE PROCEDURE proc_forall() AS BEGIN FORALL i IN 100..120 update TEST_t1 set title = title + 100*i; END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL proc_forall(); proc_forall ------------- (1 row) --查询存储过程调用结果 gaussdb=# SELECT * FROM TEST_t1; title | did | data_period | kind | interval | time | ismodified --------+--------+-------------+----------+--------------+---------------------+------------ 231008 | Donald | OConnell | DOCONNEL | 650.507.9833 | 1999-06-21 00:00:00 | SH_CLERK (1 row) --删除存储过程和表 gaussdb=# DROP PROCEDURE proc_forall; DROP PROCEDURE gaussdb=# DROP TABLE TEST_t1; DROP TABLE
  • FOR_LOOP查询语句 语法图 for_loop_query::=语句如图7所示。 图7 for_loop_query::= label declaration ::=语句如如图8所示。 图8 label declaration ::= 变量target会自动定义,类型和query的查询结果的类型一致,并且只在此循环中有效。target的取值就是query的查询结果。 query可以使用EXECUTE增加动态查询,通过USING向查询插入参数。详见示例中的动态查询相关内容。 示例 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 --循环输出查询结果。 gaussdb=# CREATE OR REPLACE PROCEDURE proc_for_loop_query() AS record VARCHAR2(50); BEGIN FOR record IN SELECT spcname FROM pg_tablespace LOOP dbe_output.print_line(record); END LOOP; END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL proc_for_loop_query(); pg_default pg_global proc_for_loop_query --------------------- (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE proc_for_loop_query; DROP PROCEDURE --动态查询 gaussdb=# CREATE TABLE t1(id int); gaussdb=# INSERT INTO t1 VALUES(1); gaussdb=# DECLARE a int := 1; item t1%rowtype; BEGIN FOR item IN EXECUTE 'SELECT * FROM t1 WHERE id = :1' USING a LOOP RAISE INFO '%', item; END LOOP; END; / INFO: (1) ANONYMOUS BLOCK EXECUTE gaussdb=# DROP TABLE t1;
  • FOR_LOOP(integer变量)语句 语法图 for_loop::=语句如图5所示。 图5 for_loop::= label declaration ::=语句如图6所示。 图6 label declaration ::= 变量name会自动定义为integer类型并且只在此循环里存在。变量name介于lower_bound和upper_bound之间。 当使用REVERSE关键字时,lower_bound必须大于等于upper_bound,否则循环体不会被执行。 示例 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 --从0到5进行循环 gaussdb=# CREATE OR REPLACE PROCEDURE proc_for_loop() AS BEGIN FOR I IN 0..5 LOOP DBE_OUTPUT.PRINT_LINE('It is '||to_char(I) || ' time;') ; END LOOP; END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL proc_for_loop(); It is 0 time; It is 1 time; It is 2 time; It is 3 time; It is 4 time; It is 5 time; proc_for_loop --------------- (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE proc_for_loop; DROP PROCEDURE
  • RETURN NEXT及RETURN QUERY 语法 创建函数时需要指定返回值SETOF datatype。 return_next_clause::= return_query_clause::= 对以上语法的解释如下: 当需要函数返回一个集合时,使用RETURN NEXT或者RETURN QUERY向结果集追加结果,然后继续执行函数的下一条语句。随着后续的RETURN NEXT或RETURN QUERY命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。 RETURN NEXT可用于标量和复合数据类型。 RETURN QUERY有一种变体RETURN QUERY EXECUTE,后面还可以增加动态查询,通过USING向查询插入参数。 示例 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 CREATE TABLE t1(a int); INSERT INTO t1 VALUES(1),(10); --RETURN NEXT CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; call fun_for_return_next(); a --- 1 10 (2 rows)
  • RETURN 语法 返回语句的语法请参见图1。 图1 return_clause::= 对以上语法的解释如下: 用于将控制从存储过程或函数返回给调用者。 示例 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 --创建存储过程proc_staffs 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; / --创建存储过程proc_return. CREATE OR REPLACE PROCEDURE proc_return AS v_num NUMBER(8,2); v_sum INTEGER; BEGIN proc_staffs(30, v_sum, v_num); --调用语句 dbms_output.put_line(v_sum||'#'||v_num); RETURN; --返回语句 END; / --调用存储过程proc_return. CALL proc_return(); --清除存储过程 DROP PROCEDURE proc_staffs; DROP PROCEDURE proc_return; --创建函数func_return. CREATE OR REPLACE FUNCTION func_return returns void language plpgsql AS $$ DECLARE v_num INTEGER := 1; BEGIN dbms_output.put_line(v_num); RETURN; --返回语句 END $$; -- 调用函数func_return CALL func_return(); 1 -- 清除函数 DROP FUNCTION func_return;
  • RETURN NEXT及RETURN QUERY 语法 创建函数时需要指定返回值SETOF datatype。 return_next_clause::= return_query_clause::= 对以上语法的解释如下: 当需要函数返回一个集合时,使用RETURN NEXT或者RETURN QUERY向结果集追加结果,然后继续执行函数的下一条语句。随着后续的RETURN NEXT或RETURN QUERY命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。 RETURN NEXT可用于标量和复合数据类型。 RETURN QUERY有一种变体RETURN QUERY EXECUTE,后面还可以增加动态查询,通过USING向查询插入参数。 示例 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 CREATE TABLE t1(a int); INSERT INTO t1 VALUES(1),(10); --RETURN NEXT CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; call fun_for_return_next(); a --- 1 10 (2 rows)
  • RETURN 语法 返回语句的语法请参见图1。 图1 return_clause::= 对以上语法的解释如下: 用于将控制从存储过程或函数返回给调用者。 示例 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 --创建存储过程proc_staffs 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; / --创建存储过程proc_return. CREATE OR REPLACE PROCEDURE proc_return AS v_num NUMBER(8,2); v_sum INTEGER; BEGIN proc_staffs(30, v_sum, v_num); --调用语句 dbms_output.put_line(v_sum||'#'||v_num); RETURN; --返回语句 END; / --调用存储过程proc_return. CALL proc_return(); --清除存储过程 DROP PROCEDURE proc_staffs; DROP PROCEDURE proc_return; --创建函数func_return. CREATE OR REPLACE FUNCTION func_return returns void language plpgsql AS $$ DECLARE v_num INTEGER := 1; BEGIN dbms_output.put_line(v_num); RETURN; --返回语句 END $$; -- 调用函数func_return CALL func_return(); 1 -- 清除函数 DROP FUNCTION func_return;
  • 示例 gaussdb=# DECLARE v_num integer default NULL; BEGIN IF v_num IS NOT NULL THEN raise info 'v_num is NULL'; ELSE NULL; -- 不需要处理任何数据。 END IF; 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 gaussdb=# CREATE OR REPLACE PROCEDURE proc_case_branch(pi_result in integer, pi_return out integer) AS BEGIN CASE pi_result WHEN 1 THEN pi_return := 111; WHEN 2 THEN pi_return := 222; WHEN 3 THEN pi_return := 333; WHEN 6 THEN pi_return := 444; WHEN 7 THEN pi_return := 555; WHEN 8 THEN pi_return := 666; WHEN 9 THEN pi_return := 777; WHEN 10 THEN pi_return := 888; ELSE pi_return := 999; END CASE; raise info 'pi_return : %',pi_return ; END; / CREATE PROCEDURE gaussdb=# CALL proc_case_branch(3,0); INFO: pi_return : 333 pi_return ----------- 333 (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE proc_case_branch; DROP PROCEDURE
  • 示例 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 gaussdb=# CREATE OR REPLACE PROCEDURE proc_case_branch(pi_result in integer, pi_return out integer) AS BEGIN CASE pi_result WHEN 1 THEN pi_return := 111; WHEN 2 THEN pi_return := 222; WHEN 3 THEN pi_return := 333; WHEN 6 THEN pi_return := 444; WHEN 7 THEN pi_return := 555; WHEN 8 THEN pi_return := 666; WHEN 9 THEN pi_return := 777; WHEN 10 THEN pi_return := 888; ELSE pi_return := 999; END CASE; raise info 'pi_return : %',pi_return ; END; / CREATE PROCEDURE gaussdb=# CALL proc_case_branch(3,0); INFO: pi_return : 333 pi_return ----------- 333 (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE proc_case_branch; DROP PROCEDURE
  • FORALL批量查询语句 语法图 图5 forall::= 变量index会自动定义为integer类型并且只在此循环里存在。index的取值介于low_bound和upper_bound之间。 如果声明了SAVE EXCEPTIONS,则会将循环体DML执行过程中每次遇到的异常保存在SQL&BULK_EXCEPTIONS中,并在执行结束后统一抛出一个异常,循环过程中没有异常的执行的结果在当前子事务内不会回滚。 示例 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 CREATE TABLE hdfs_t1 ( title NUMBER(6), did VARCHAR2(20), data_period VARCHAR2(25), kind VARCHAR2(25), interval VARCHAR2(20), time DATE, isModified VARCHAR2(10) ); INSERT INTO hdfs_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' ); CREATE OR REPLACE PROCEDURE proc_forall() AS BEGIN FORALL i IN 100..120 update hdfs_t1 set title = title + 100*i; END; / --调用函数 CALL proc_forall(); --查询存储过程调用结果 SELECT * FROM hdfs_t1 WHERE title BETWEEN 100 AND 120; --删除存储过程和表 DROP PROCEDURE proc_forall; DROP TABLE hdfs_t1;