云服务器内容精选

  • 操作步骤 执行以下命令,修改数据库名称。 exec msdb.dbo.rds_rename_database N'oldname',N'newname'; oldname为修改前的数据库名称。 newname为修改后的数据库名称。 将名为“ABC”的数据库重命名为“XYZ”,示例如下: exec msdb.dbo.rds_rename_database N'ABC',N'XYZ'; 数据库名称修改成功后,系统将会如下提示: The database name 'XYZ' has been set.
  • 前提条件 成功连接RDS for SQL Server实例。关于连接关系型数据库实例,请参考连接实例。 在您对HA实例重命名之前,请先执行如下命令取消数据库的镜像关系。 alter database [dbname] set partner off 数据库重命名成功后,系统会自动为新的数据库建立镜像关系。 如果对未取消HA实例镜像关系的数据库进行重命名,系统将会如下提示: Database 数据库名 is on mirroring_state. 对于数据库版本为2017 EE的实例,若要进行重命名的数据库已加入到 [AG-RDS-YUN] 可用性组中,必须先将其移出可用性组,才可进行重命名操作。
  • 约束 对于系统库,不可修改名称。如果您试图修改系统库的名称,系统将会如下提示: Error DBName_Source or DBName_Target. Please can not include in ('msdb','master','model','tempdb','rdsadmin','resource') . 不可使用已经存在的数据库名称进行重命名操作。如果重命名的数据库名称已经存在,系统将会如下提示: Database 数据库名 already exists. Cannot rename database with the same name.
  • 示例 示例1:支持在PL/SQL的存储过程内使用COMMIT/ROLLBACK,后续示例依赖此用例。 gaussdb=# DROP TABLE IF EXISTS EXAMPLE1; NOTICE: table "example1" does not exist, skipping DROP TABLE gaussdb=# CREATE TABLE EXAMPLE1(COL1 INT); CREATE TABLE gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE() AS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1(COL1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / CREATE PROCEDURE gaussdb=# CALL TRANSACTION_EXAMPLE(); transaction_example --------------------- (1 row) 示例2: 支持含有EXCEPTION的存储过程使用COMMIT/ROLLBACK。 支持在存储过程的EXCEPTION语句内使用COMMIT/ROLLBACK。 支持DDL在COMMIT/ROLLBACK后的提交/回滚。 gaussdb=# CREATE OR REPLACE PROCEDURE TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK() AS BEGIN DROP TABLE IF EXISTS TEST_COMMIT; CREATE TABLE TEST_COMMIT(A INT, B INT); INSERT INTO TEST_COMMIT SELECT 1, 1; COMMIT; CREATE TABLE TEST_ROLLBACK(A INT, B INT); RAISE EXCEPTION 'RAISE EXCEPTION AFTER COMMIT'; EXCEPTION WHEN OTHERS THEN INSERT INTO TEST_COMMIT SELECT 2, 2; ROLLBACK; END; / CREATE PROCEDURE gaussdb=# CALL TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK(); NOTICE: table "test_commit" does not exist, skipping CONTEXT: SQL statement "DROP TABLE IF EXISTS TEST_COMMIT" PL/pgSQL function test_commit_insert_exception_rollback() line 3 at SQL statement test_commit_insert_exception_rollback --------------------------------------- (1 row) 示例3:支持在事务块里调用含有COMMIT/ROLLBACK的存储过程,即通过BEGIN/START/END等开启控制的外部事务。 gaussdb=# BEGIN; -- TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK定义见示例2 CALL TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK(); END; test_commit_insert_exception_rollback --------------------------------------- (1 row) COMMIT 示例4:支持多数PL/SQL的上下文和语句内调用COMMIT/ROLLBACK,包括常用的IF/FOR/CURSOR LOOP/WHILE。 gaussdb=# CREATE OR REPLACE PROCEDURE TEST_COMMIT2() IS BEGIN DROP TABLE IF EXISTS TEST_COMMIT; CREATE TABLE TEST_COMMIT(A INT); FOR I IN REVERSE 3..0 LOOP INSERT INTO TEST_COMMIT SELECT I; COMMIT; END LOOP; FOR I IN REVERSE 2..4 LOOP UPDATE TEST_COMMIT SET A=I; COMMIT; END LOOP; EXCEPTION WHEN OTHERS THEN INSERT INTO TEST_COMMIT SELECT 4; COMMIT; END; / CREATE PROCEDURE gaussdb=# CALL TEST_COMMIT2(); test_commit2 -------------- (1 row) 示例5:支持存储过程返回值与简单表达式计算。 gaussdb=# CREATE OR REPLACE PROCEDURE exec_func3(RET_NUM OUT INT) AS BEGIN RET_NUM := 1+1; COMMIT; END; / CREATE PROCEDURE gaussdb=# CALL exec_func3(''); ret_num --------- 2 (1 row) gaussdb=# CREATE OR REPLACE PROCEDURE exec_func4(ADD_NUM IN INT) AS SUM_NUM INT; BEGIN SUM_NUM := ADD_NUM + exec_func3(); COMMIT; END; / CREATE PROCEDURE gaussdb=# CALL exec_func4(1); exec_func4 ------------ (1 row) 示例6:支持存储过程内GUC参数的回滚提交。 gaussdb=# SET explain_perf_mode='normal'; SET gaussdb=# SHOW explain_perf_mode; explain_perf_mode ------------------- normal (1 row) gaussdb=# SHOW enable_force_vector_engine; enable_force_vector_engine ---------------------------- off (1 row) gaussdb=# CREATE OR REPLACE PROCEDURE GUC_ROLLBACK() AS BEGIN SET enable_force_vector_engine = on; COMMIT; SET explain_perf_mode TO pretty; ROLLBACK; END; / CREATE PROCEDURE gaussdb=# CALL GUC_ROLLBACK(); guc_rollback -------------- (1 row) gaussdb=# SHOW explain_perf_mode; explain_perf_mode ------------------- normal (1 row) gaussdb=# SHOW enable_force_vector_engine; enable_force_vector_engine ---------------------------- on (1 row) gaussdb=# SET enable_force_vector_engine = off; SET 示例7:不允许Trigger的存储过程包含commit/rollback语句,或调用带有commit/rollback语句的存储过程。 gaussdb=# CREATE OR REPLACE FUNCTION FUNCTION_TRI_EXAMPLE2() RETURN TRIGGER AS EXP INT; BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1(col1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; SELECT COUNT(*) FROM EXAMPLE1 INTO EXP; END; / CREATE FUNCTION gaussdb=# CREATE TRIGGER TRIGGER_EXAMPLE AFTER DELETE ON EXAMPLE1 FOR EACH ROW EXECUTE PROCEDURE FUNCTION_TRI_EXAMPLE2(); CREATE TRIGGER gaussdb=# DELETE FROM EXAMPLE1; ERROR: Can not commit/rollback if it's atomic is true: can not use commit rollback in Complex SQL CONTEXT: PL/pgSQL function function_tri_example2() line 7 at COMMIT 示例8:不支持带有IMMUTABLE以及SHIPPABLE的存储过程调用commit/rollback,或调用带有commit/rollback语句的存储过程。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE1() IMMUTABLE AS EXP INT; BEGIN FOR i IN 0..20 LOOP SELECT COUNT(*) FROM EXAMPLE1 INTO EXP; IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / CREATE PROCEDURE gaussdb=#CALL TRANSACTION_EXAMPLE1(); ERROR: Can not commit/rollback if it's atomic is true: commit/rollback/savepoint is not allowed in a non-volatile function CONTEXT: PL/pgSQL function transaction_example1() line 7 at COMMIT 示例9:不支持存储过程中任何变量的提交,包括存储过程内声明的变量或者传入的参数。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE2(EXP_OUT OUT INT) AS EXP INT:=-1; BEGIN EXP_OUT := 0; EXP := 0; COMMIT; DBE_OUTPUT.PRINT_LINE('EXP IS:'||EXP); DBE_OUTPUT.PRINT_LINE('EXP_OUT IS:'||EXP_OUT); EXP := 1; EXP_OUT := 1; ROLLBACK; DBE_OUTPUT.PRINT_LINE('EXP IS:'||EXP); DBE_OUTPUT.PRINT_LINE('EXP_OUT IS:'||EXP_OUT); END; / CREATE PROCEDURE gaussdb=# CALL TRANSACTION_EXAMPLE2(1); EXP IS:0 EXP_OUT IS:0 EXP IS:1 EXP_OUT IS:1 exp_out --------- 1 (1 row) 示例10:不支持出现在SQL中的调用(除了Select Procedure)。 gaussdb=# CREATE OR REPLACE FUNCTION TRANSACTION_EXAMPLE3() RETURN INT IS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1 (col1) VALUES (i); IF i % 2 = 0 THEN EXECUTE IMMEDIATE 'COMMIT'; ELSE EXECUTE IMMEDIATE 'ROLLBACK'; END IF; END LOOP; RETURN 1; END; / CREATE PROCEDURE gaussdb=# SELECT * FROM example1 WHERE col1=TRANSACTION_EXAMPLE3(); ERROR: cannot call transaction statements in EXECUTE IMMEDIATE statement. CONTEXT: PL/pgSQL function transaction_example3() line 6 at EXECUTE statement 示例11:存储过程头带有GUC参数设置的不允许调用commit/rollback语句。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE4() SET ARRAY_NULLS TO "ON" AS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1 (col1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / CREATE PROCEDURE gaussdb=# CALL TRANSACTION_EXAMPLE4(); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure with GUC setting in option clause is not supported CONTEXT: PL/pgSQL function transaction_example4() line 6 at COMMIT 示例12:游标open的对象不允许为带有commit/rollback语句的存储过程。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE5(INTIN IN INT, INTOUT OUT INT) AS BEGIN INTOUT := INTIN + 1; COMMIT; END; / CREATE PROCEDURE gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE6() AS CURSOR CURSOR1(EXPIN INT) IS SELECT TRANSACTION_EXAMPLE5(EXPIN); INTEXP INT; BEGIN FOR i IN 0..20 LOOP OPEN CURSOR1(i); FETCH CURSOR1 INTO INTEXP; INSERT INTO EXAMPLE1(COL1) VALUES (INTEXP); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; CLOSE CURSOR1; END LOOP; END; / CREATE PROCEDURE gaussdb=# CALL TRANSACTION_EXAMPLE6(); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure used as cursor is not supported CONTEXT: PL/pgSQL function transaction_example5(integer) line 4 at COMMIT referenced column: transaction_example5 PL/pgSQL function transaction_example6() line 8 at FETCH 示例13:不支持CURSOR/EXECUTE语句,以及各类表达式内调用COMMIT/ROLLBACK。 gaussdb=# CREATE OR REPLACE PROCEDURE exec_func1() AS BEGIN CREATE TABLE TEST_exec(A INT); COMMIT; END; / CREATE PROCEDURE gaussdb=# CREATE OR REPLACE PROCEDURE exec_func2() AS BEGIN EXECUTE exec_func1(); COMMIT; END; / CREATE PROCEDURE gaussdb=# CALL exec_func2(); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure used as a expression is not supported CONTEXT: PL/pgSQL function exec_func1() line 4 at COMMIT PL/pgSQL function exec_func2() line 3 at EXECUTE statement
  • 使用场景 支持调用的上下文环境: 支持在PL/SQL的存储过程内使用COMMIT/ROLLBACK/SAVEPOINT。 支持含有EXCEPTION的存储过程使用COMMIT/ROLLBACK/SAVEPOINT。 支持在存储过程的EXCEPTION语句内使用COMMIT/ROLLBACK/SAVEPOINT。 支持在事务块里调用含有COMMIT/ROLLBACK/SAVEPOINT的存储过程,即通过BEGIN/START/END等开启控制的外部事务。 支持在子事务中调用含有SAVEPOINT的存储过程,即存储过程中使用外部定义的SAVEPOINT,回退事务状态到存储过程外定义的SAVEPOINT位置。 支持存储过程外部对存储过程内定义的SAVEPOINT可见,即存储过程外可以将事务修改回滚到存储过程中定义SAVEPOINT的位置。 支持多数PL/SQL的上下文和语句内调用COMMIT/ROLLBACK/SAVEPOINT,包括常用的IF/FOR/CURSOR LOOP/WHILE。 支持存储过程返回值与简单表达式计算中调用含有COMMIT/ROLLBACK/SAVEPOINT的存储过程或者函数。 支持提交/回滚的内容: 支持DDL在COMMIT/ROLLBACK后的提交/回滚。 支持DML的COMMIT/ROLLBACK后的提交。 支持存储过程内GUC参数的回滚提交。
  • 使用限制 不支持调用的上下文环境: 不支持除PL/SQL的其他存储过程中调用COMMIT/ROLLBACK/SAVEPOINT,例如PL/PYTHON等。 不支持函数中调用COMMIT/ROLLBACK/SAVEPOINT,包括函数调用含有COMMIT/ROLLBACK/SAVEPOINT的存储过程。 不支持事务块中调用了SAVEPOINT后,调用含有COMMIT/ROLLBACK的存储过程。 不支持TRIGGER中调用含有COMMIT/ROLLBACK/SAVEPOINT语句的存储过程。 不支持EXECUTE语句中调用COMMIT/ROLLBACK/SAVEPOINT语句。 不支持在CURSOR语句中打开一个含有COMMIT/ROLLBACK/SAVEPOINT的存储过程。 不支持带有IMMUTABLE以及SHIPPABLE的存储过程调用COMMIT/ROLLBACK/SAVEPOINT,或调用带有COMMIT/ROLLBACK/SAVEPOINT语句的存储过程。 不支持SQL中调用含有COMMIT/ROLLBACK/SAVEPOINT语句的存储过程,除了SELECT PROC以及CALL PROC。 存储过程头带有GUC参数设置的不允许调用COMMIT/ROLLBACK/SAVEPOINT语句。 不支持CURSOR/EXECUTE语句,以及各类表达式内调用COMMIT/ROLLBACK/SAVEPOINT。 不支持存储过程中释放存储过程外部定义的保存点。 自治事务和存储过程事务是两个独立的事务,不能互相使用对方事务中定义的保存点。 不支持提交回滚的内容: 不支持存储过程内声明变量以及传入变量的提交/回滚。 不支持存储过程内必须重启生效的GUC参数的提交/回滚。
  • 限制场景 在存储过程使用commit/rollback有以下限制场景: 不允许Trigger的存储过程包含COMMIT/ROLLBACK语句、或调用带有COMMIT/ROLLBACK语句的存储过程。 gaussdb=# DROP TABLE IF EXISTS EXAMPLE1; gaussdb=# CREATE TABLE EXAMPLE1(COL1 INT); gaussdb=# INSERT INTO EXAMPLE1(col1) VALUES (1); gaussdb=# CREATE OR REPLACE FUNCTION FUNCTION_TRI_EXAMPLE2() RETURN TRIGGER AS EXP INT; BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1(col1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; SELECT COUNT(*) FROM EXAMPLE1 INTO EXP; END; / gaussdb=# CREATE TRIGGER TRIGGER_EXAMPLE AFTER DELETE ON EXAMPLE1 FOR EACH ROW EXECUTE PROCEDURE FUNCTION_TRI_EXAMPLE2(); CREATE TRIGGER gaussdb=# DELETE FROM EXAMPLE1; ERROR: Can not commit/rollback if it's atomic is true: can not use commit rollback in Complex SQL CONTEXT: PL/pgSQL function function_tri_example2() line 7 at COMMIT 不支持带有IMMUTABLE以及SHIPPABLE的存储过程调用commitrollback,或调用带有commit/rollback语句的存储过程。 gaussdb=# DROP TABLE IF EXISTS EXAMPLE1; gaussdb=# CREATE TABLE EXAMPLE1(COL1 INT); gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE1() IMMUTABLE AS EXP INT; BEGIN FOR i IN 0..20 LOOP SELECT COUNT(*) FROM EXAMPLE1 INTO EXP; IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / gaussdb=# CALL TRANSACTION_EXAMPLE1(); ERROR: Can not commit/rollback if it's atomic is true: commit/rollback/savepoint is not allowed in a non-volatile function CONTEXT: PL/pgSQL function transaction_example1() line 7 at COMMIT 不支持存储过程中任何变量的提交,包括存储过程内声明的变量或者传入的参数。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE2(EXP_OUT OUT INT) AS EXP INT; BEGIN EXP_OUT := 0; COMMIT; DBE_OUTPUT.PRINT_LINE('EXP IS:'||EXP); EXP_OUT := 1; ROLLBACK; DBE_OUTPUT.PRINT_LINE('EXP IS:'||EXP); END; / gaussdb=# CALL TRANSACTION_EXAMPLE2(100); EXP IS: EXP IS: exp_out --------- 1 (1 row) 不支持出现在SQL中的调用(除了Select Procedure)。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE3() AS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1 (col1) VALUES (i); IF i % 2 = 0 THEN EXECUTE IMMEDIATE 'COMMIT'; ELSE EXECUTE IMMEDIATE 'ROLLBACK'; END IF; END LOOP; END; / gaussdb=# CALL TRANSACTION_EXAMPLE3(); ERROR: cannot call transaction statements in EXECUTE IMMEDIATE statement. CONTEXT: PL/pgSQL function transaction_example3() line 6 at EXECUTE statement 存储过程头带有GUC参数设置的不允许调用commit/rollback语句。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE4() SET ARRAY_NULLS TO "ON" AS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1 (col1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / gaussdb=# CALL TRANSACTION_EXAMPLE4(); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure with GUC setting in option clause is not supported CONTEXT: PL/pgSQL function transaction_example4() line 6 at COMMIT 游标open的对象不允许为带有commit/rollback语句的存储过程。 gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE5(INTIN IN INT, INTOUT OUT INT) AS BEGIN INTOUT := INTIN + 1; COMMIT; END; / gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE6() AS CURSOR CURSOR1(EXPIN INT) IS SELECT TRANSACTION_EXAMPLE5(EXPIN); INTEXP INT; BEGIN FOR i IN 0..20 LOOP OPEN CURSOR1(i); FETCH CURSOR1 INTO INTEXP; INSERT INTO EXAMPLE1(COL1) VALUES (INTEXP); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; CLOSE CURSOR1; END LOOP; END; / gaussdb=# CALL TRANSACTION_EXAMPLE6(); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure used as cursor is not supported CONTEXT: PL/pgSQL function transaction_example5(integer) line 4 at COMMIT referenced column: transaction_example5 PL/pgSQL function transaction_example6() line 8 at FETCH 不支持CURSOR/EXECUTE语句,以及各类表达式内调用COMMIT/ROLLBACK。 gaussdb=# CREATE OR REPLACE PROCEDURE exec_func1() AS BEGIN CREATE TABLE TEST_exec(A INT); COMMIT; END; / gaussdb=# CREATE OR REPLACE PROCEDURE exec_func2() AS BEGIN EXECUTE exec_func1(); COMMIT; END; / gaussdb=# CALL exec_func2(); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_exec(A INT)" PL/pgSQL function exec_func1() line 3 at SQL statement PL/pgSQL function exec_func2() line 3 at EXECUTE statement ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure used as a expression is not supported CONTEXT: PL/pgSQL function exec_func1() line 4 at COMMIT PL/pgSQL function exec_func2() line 3 at EXECUTE statement 不支持存储过程返回值与表达式计算。 gaussdb=# CREATE OR REPLACE PROCEDURE exec_func3(RET_NUM OUT INT) AS BEGIN RET_NUM := 1+1; COMMIT; END; / gaussdb=# CREATE OR REPLACE PROCEDURE exec_func4(ADD_NUM IN INT) AS SUM_NUM INT; BEGIN SUM_NUM := ADD_NUM + exec_func3(); COMMIT; END; / gaussdb=# CALL exec_func4(1); ERROR: Can not commit/rollback if it's atomic is true: transaction statement in store procedure used as a expression is not supported CONTEXT: PL/pgSQL function exec_func3() line 4 at COMMIT PL/pgSQL function exec_func4(integer) line 4 at assignment 不支持存储过程中释放存储过程外部定义的保存点。 gaussdb=# CREATE OR REPLACE PROCEDURE STP_SAVEPOINT_EXAMPLE3() AS BEGIN INSERT INTO EXAMPLE1 VALUES(2); RELEASE SAVEPOINT s1; -- 释放存储过程外部定义的保存点 INSERT INTO EXAMPLE1 VALUES(3); END; / gaussdb=# BEGIN; INSERT INTO EXAMPLE1 VALUES(1); SAVEPOINT s1; CALL STP_SAVEPOINT_EXAMPLE3(); COMMIT; ERROR: cannot release outer savepoint CONTEXT: PL/pgSQL function stp_savepoint_example3() line 4 at RELEASE SAVEPOINT
  • 示例 支持在PL/SQL的存储过程内使用COMMIT/ROLLBACK,后续示例依赖此用例。 gaussdb=# DROP TABLE IF EXISTS EXAMPLE1; gaussdb=# CREATE TABLE EXAMPLE1(COL1 INT); gaussdb=# CREATE OR REPLACE PROCEDURE TRANSACTION_EXAMPLE() AS BEGIN FOR i IN 0..20 LOOP INSERT INTO EXAMPLE1(COL1) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; / gaussdb=# call TRANSACTION_EXAMPLE(); transaction_example --------------------- (1 row) 支持含有EXCEPTION的存储过程使用COMMIT/ROLLBACK。 支持在存储过程的EXCEPTION语句内使用COMMIT/ROLLBACK。 支持DDL在COMMIT/ROLLBACK后的提交/回滚。 gaussdb=# DROP TABLE IF EXISTS EXAMPLE1; gaussdb=# CREATE TABLE EXAMPLE1(COL1 INT); gaussdb=# CREATE OR REPLACE PROCEDURE TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK() AS BEGIN DROP TABLE IF EXISTS TEST_COMMIT; CREATE TABLE TEST_COMMIT(A INT, B INT); INSERT INTO TEST_COMMIT SELECT 1, 1; COMMIT; CREATE TABLE TEST_ROLLBACK(A INT, B INT); RAISE EXCEPTION 'RAISE EXCEPTION AFTER COMMIT'; EXCEPTION WHEN OTHERS THEN INSERT INTO TEST_COMMIT SELECT 2, 2; ROLLBACK; END; / gaussdb=# call TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK(); NOTICE: table "test_commit" does not exist, skipping CONTEXT: SQL statement "DROP TABLE IF EXISTS TEST_COMMIT" PL/pgSQL function test_commit_insert_exception_rollback() line 3 at SQL statement NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_COMMIT(A INT, B INT)" PL/pgSQL function test_commit_insert_exception_rollback() line 4 at SQL statement NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_ROLLBACK(A INT, B INT)" PL/pgSQL function test_commit_insert_exception_rollback() line 7 at SQL statement test_commit_insert_exception_rollback --------------------------------------- (1 row) 支持在事务块里调用含有COMMIT/ROLLBACK的存储过程,即通过BEGIN/START/END等开启控制的外部事务。 gaussdb=# BEGIN; -- TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK定义见示例2 CALL TEST_COMMIT_INSERT_EXCEPTION_ROLLBACK(); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_COMMIT(A INT, B INT)" PL/pgSQL function test_commit_insert_exception_rollback() line 4 at SQL statement NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_ROLLBACK(A INT, B INT)" PL/pgSQL function test_commit_insert_exception_rollback() line 7 at SQL statement test_commit_insert_exception_rollback --------------------------------------- (1 row) gaussdb=# END; COMMIT 支持多数PL/SQL的上下文和语句内调用COMMIT/ROLLBACK,包括常用的IF/FOR/CURSOR LOOP/WHILE。 gaussdb=# CREATE OR REPLACE PROCEDURE TEST_COMMIT2() IS BEGIN DROP TABLE IF EXISTS TEST_COMMIT; CREATE TABLE TEST_COMMIT(A INT); FOR I IN REVERSE 3..0 LOOP INSERT INTO TEST_COMMIT SELECT I; COMMIT; END LOOP; FOR I IN REVERSE 2..4 LOOP UPDATE TEST_COMMIT SET A=I; COMMIT; END LOOP; EXCEPTION WHEN OTHERS THEN INSERT INTO TEST_COMMIT SELECT 4; COMMIT; END; / gaussdb=# call TEST_COMMIT2(); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CONTEXT: SQL statement "CREATE TABLE TEST_COMMIT(A INT)" PL/pgSQL function test_commit2() line 4 at SQL statement test_commit2 -------------- (1 row) 支持存储过程内GUC参数的回滚提交。 gaussdb=# SHOW explain_perf_mode; explain_perf_mode ------------------- normal (1 row) gaussdb=# SHOW enable_force_vector_engine; enable_force_vector_engine ---------------------------- off (1 row) gaussdb=# CREATE OR REPLACE PROCEDURE GUC_ROLLBACK() AS BEGIN SET enable_force_vector_engine = on; COMMIT; SET explain_perf_mode TO pretty; ROLLBACK; END; / gaussdb=# call GUC_ROLLBACK(); guc_rollback -------------- (1 row) gaussdb=# SHOW explain_perf_mode; explain_perf_mode ------------------- normal (1 row) gaussdb=# SHOW enable_force_vector_engine; enable_force_vector_engine ---------------------------- on (1 row) gaussdb=# SET enable_force_vector_engine = off;
  • 示例 一次性入库举例: --设置如下参数: SET ddl_invalid_mode='invalid'; SET enable_force_create_obj=on; --新建函数,入参使用的类型不存在。 CREATE OR REPLACE FUNCTION func1(var type_not_exist) RETURN int IS BEGIN RETURN NULL; END; / --执行结果。 WARNING: Type type_not_exist does not exist. WARNING: Function created with compilation errors. CREATE FUNCTION --查询状态。 SELECT proname,valid FROM pg_object obj JOIN pg_proc proc ON obj.object_oid = proc.oid AND proname = 'func1' AND propackageid = 0; --执行结果。 proname | valid ---------+------- func1 | f (1 row) --新建PACKAGE,入参使用的类型不存在。 CREATE OR REPLACE PACKAGE pkg IS FUNCTION func1(var type_not_exist) RETURN int; END pkg; / --执行结果。 WARNING: Type type_not_exist does not exist. WARNING: Package created with compilation errors. CREATE PACKAGE CREATE OR REPLACE PACKAGE BODY pkg IS FUNCTION func1(var type_not_exist) RETURN int AS DECLARE BEGIN RETURN NULL; END; END pkg; / --执行结果。 WARNING: Type type_not_exist does not exist. WARNING: Package Body created with compilation errors. CREATE PACKAGE BODY --查询状态。 SELECT pkgname,object_type,valid FROM pg_object obj JOIN gs_package pkg ON obj.object_oid = pkg.oid AND pkgname = 'pkg'; pkgname | object_type | valid ---------+-------------+------- pkg | B | f pkg | S | f (2 rows) --重新创建入参使用的类型。 CREATE TYPE type_not_exist AS (f1 int, f2 text); 失效重编译功能举例 --运行失效重编译高级包。 CALL pkg_util.gs_compile_schema('public', false, 1); --执行结果。 INFO: The number of executions is 1 INFO: successful gs_compile_schema ------------------- (1 row) --查询状态。 SELECT proname,valid FROM pg_object obj JOIN pg_proc proc ON obj.object_oid = proc.oid AND proname = 'func1' AND propackageid = 0; proname | valid ---------+------- func1 | t (1 row) SELECT pkgname,object_type,valid FROM pg_object obj JOIN gs_package pkg ON obj.object_oid = pkg.oid AND pkgname = 'pkg'; pkgname | object_type | valid ---------+-------------+------- pkg | S | t pkg | B | t (2 rows) --执行函数。 CALL func1(null); func1 ------- (1 row) CALL pkg.func1(null); func1 ------- (1 row) --删除已创建的对象。 DROP FUNCTION func1; DROP PACKAGE pkg; DROP TYPE type_not_exist; 级联失效功能举例 CREATE TYPE type1 AS (f1 int, f2 text); CREATE OR REPLACE FUNCTION func1(var type1) RETURN varchar IS BEGIN RETURN NULL; END; / SELECT proname,valid FROM pg_object obj JOIN pg_proc proc ON obj.object_oid = proc.oid AND proname = 'func1' AND propackageid = 0; proname | valid ---------+------- func1 | t (1 row) DROP TYPE type1; --查询状态。 SELECT proname,valid FROM pg_object obj JOIN pg_proc proc ON obj.object_oid = proc.oid AND proname = 'func1' AND propackageid = 0; proname | valid ---------+------- func1 | f (1 row) --函数未被删除,函数依然存在。 SELECT proname FROM pg_proc WHERE proname = 'func1' AND propackageid = 0; proname --------- func1 (1 row) --删除已创建的对象。 DROP FUNCTION func1;
  • 数据类型转换 数据库中有些数据类型间允许进行隐式类型转换(例如赋值、函数调用的参数等)、有些数据类型间不允许进行隐式数据类型转换(例如INT和复合类型),可尝试使用 GaussDB 提供的类型转换函数,例如CAST进行数据类型强转。 GaussDB数据库 常见的隐式类型转换如表1所示。 GaussDB支持的DATE的效限范围是:公元前4713年到公元294276年。 表1 隐式类型转换表 原始数据类型 目标数据类型 备注 CHAR VARCHAR2 - CHAR NUMBER 原数据必须由数字组成。 CHAR DATE 原数据不能超出合法日期范围。 CHAR RAW - CHAR CLOB - VARCHAR2 CHAR - VARCHAR2 NUMBER 原数据必须由数字组成。 VARCHAR2 DATE 原数据不能超出合法日期范围。 VARCHAR2 CLOB - NUMBER CHAR - NUMBER VARCHAR2 - DATE CHAR - DATE VARCHAR2 - RAW CHAR - RAW VARCHAR2 - CLOB CHAR - CLOB VARCHAR2 - CLOB NUMBER 原数据必须由数字组成。 INT4 CHAR - 父主题: 存储过程
  • Retry管理 Retry是数据库在SQL或存储过程(包含匿名块)执行失败时,在数据库内部进行重新执行的过程,以提高执行成功率和用户体验。同时也是数据库内部通过检查发生错误时的错误码及Retry相关配置,决定是否进行重试。 失败时回滚之前执行的语句,并重新执行存储过程进行Retry。 示例: 1 2 3 4 5 6 7 8 9 gaussdb=# CREATE OR REPLACE PROCEDURE retry_basic ( IN x INT) AS BEGIN INSERT INTO t1 (a) VALUES (x); INSERT INTO t1 (a) VALUES (x+1); END; / gaussdb=# CALL retry_basic(1); 父主题: 存储过程
  • 语法 RAISE有以下五种语法格式: 图1 raise_format::= 图2 raise_condition::= 图3 raise_sqlstate::= 图4 raise_option::= 图5 raise::= 参数说明: level选项用于指定错误级别,有DEBUG、 LOG 、INFO、NOTICE、WARNING以及EXCEPTION(默认值)。EXCEPTION抛出一个正常终止当前事务的异常,其他的仅产生不同异常级别的信息。特殊级别的错误信息是否报告到客户端、写到服务器日志由log_min_messages和client_min_messages这两个GUC参数控制。 format:格式字符串,指定要报告的错误消息文本。格式字符串后可跟表达式,用于向消息文本中插入。在格式字符串中,%由format后面跟着的参数的值替换,%%用于打印出%。例如: --v_job_id 将替换字符串中的 %: RAISE NOTICE 'Calling cs_create_job(%)',v_job_id; option = expression:向错误报告中添加另外的信息。关键字option可以是MESSAGE、DETAIL、HINT以及ERRCODE,并且每一个expression可以是任意的字符串。 MESSAGE,指定错误消息文本,这个选项不能用于在USING前包含一个格式字符串的RAISE语句中。 DETAIL,说明错误的详细信息。 HINT,用于打印出提示信息。 ERRCODE,向报告中指定错误码(SQLSTATE)。可以使用条件名称或者直接用五位字符的SQLSTATE错误码。 condition_name:错误码对应的条件名。 sqlstate:错误码。 如果在RAISE EXCEPTION命令中既没有指定条件名也没有指定SQLSTATE,默认用RAISE EXCEPTION (P0001)。如果没有指定消息文本,默认用条件名或者SQLSTATE作为消息文本。 当由SQLSTATE指定了错误码,则不局限于已定义的错误码,可以选择任意包含五个数字或者大写的ASCII字母的错误码,而不是00000。建议避免使用以三个0结尾的错误码,因为这种错误码是类别码,会被整个种类捕获。 兼容ORA模式下,SQLCODE等于SQLSTATE。 图5所示的语法不接受任何参数。这种形式仅用于一个BEGIN块中的EXCEPTION语句,它使得错误重新被处理。
  • Retry管理 Retry是数据库在SQL或存储过程(包含匿名块)执行失败时,在数据库内部进行重新执行的过程,以提高执行成功率和用户体验。数据库内部通过检查发生错误时的错误码及Retry相关配置,决定是否进行重试。 失败时回滚之前执行的语句,并重新执行存储过程进行Retry。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 gaussdb=# CREATE OR REPLACE PROCEDURE retry_basic ( IN x INT) AS BEGIN INSERT INTO t1 (a) VALUES (x); INSERT INTO t1 (a) VALUES (x+1); END; / CREATE PROCEDURE gaussdb=# CALL retry_basic(1); ERROR: relation "t1" does not exist on datanode LINE 1: INSERT INTO t1 (a) VALUES (x) ^ QUERY: INSERT INTO t1 (a) VALUES (x) CONTEXT: PL/pgSQL function retry_basic(integer) line 3 at SQL statement 父主题: 存储过程
  • 语法 RAISE语法 有以下五种语法格式: 图1 raise_format::= 图2 raise_condition::= 图3 raise_sqlstate::= 图4 raise_option::= 图5 raise::= 参数说明: level选项用于指定错误级别,有DEBUG、LOG、INFO、NOTICE、WARNING以及EXCEPTION(默认值)。EXCEPTION抛出一个正常终止当前事务的异常,其他的仅产生不同异常级别的信息。特殊级别的错误信息是否报告到客户端、写到服务器日志由log_min_messages和client_min_messages这两个GUC配置参数控制。 format:格式字符串,指定要报告的错误消息文本。格式字符串后可跟表达式,用于向消息文本中插入。在格式字符串中,%由format后面跟着的参数的值替换,%%用于打印出%。例如: --v_job_id 将替换字符串中的 %: RAISE NOTICE 'Calling cs_create_job(%)',v_job_id; option = expression:向错误报告中添加另外的信息。关键字option可以是MESSAGE、DETAIL、HINT以及ERRCODE,并且每一个expression可以是任意的字符串。 MESSAGE,指定错误消息文本,这个选项不能用于在USING前包含一个格式字符串的RAISE语句中。 DETAIL,说明错误的详细信息。 HINT,用于打印出提示信息。 ERRCODE,向报告中指定错误码(SQLSTATE)。可以使用条件名称或者直接用五位字符的SQLSTATE错误码。 condition_name:错误码对应的条件名。 sqlstate:错误码。 如果在RAISE EXCEPTION命令中既没有指定条件名也没有指定SQLSTATE,默认用RAISE EXCEPTION (P0001)。如果没有指定消息文本,默认用条件名或者SQLSTATE作为消息文本。 当由SQLSTATE指定了错误码,则不局限于已定义的错误码,可以选择任意包含五个数字或者大写的ASCII字母的错误码,而不是00000。建议避免使用以三个0结尾的错误码,因为这种错误码是类别码,会被整个种类捕获。 兼容O模式下,SQLCODE等于SQLSTATE。 图5所示的语法不接受任何参数。这种形式仅用于一个BEGIN块中的EXCEPTION语句,它使得错误重新被处理。
  • 基本语句 在编写PL/SQL过程中,会定义一些变量,给变量赋值,调用其他存储过程等。介绍PL/SQL中的基本语句,包括定义变量、赋值语句、调用语句以及返回语句。 尽量不要在存储过程中调用包含密码的SQL语句,因为存储在数据库中的存储过程文本可能被其他有权限的用户看到,从而导致密码信息泄漏。如果存储过程中包含其他敏感信息,也需要配置存储过程的访问权限,以保证敏感信息不会泄漏。 定义变量 赋值语句 调用语句 父主题: 存储过程