更新时间:2025-08-19 GMT+08:00
分享

IMMUTABLE和SHIPPABLE

IMMUTABLE是存储过程的一个属性,用于声明该存储过程的结果仅依赖于输入参数,而不依赖于数据库的当前状态。在某些场景下,使用 IMMUTABLE 属性的存储过程可能会被优化为仅执行一次,如果使用不当,可能会造成不符合预期的结果。

SHIPPABLE是存储过程的另一个属性,用于表示该存储过程是否可以下推到 DN(数据节点)执行。如果下推的存储过程访问表或数据库状态,可能会导致数据不一致。

建议在使用 IMMUTABLE 和 SHIPPABLE 属性的存储过程和函数时,避免访问表或数据库信息,以确保其行为符合预期并维护数据一致性。属性详情请参见《开发指南》中“SQL参考 > SQL语法 > C > CREATE FUNCTION”章节。

gaussdb=# create schema best_practices_for_procedure;
CREATE SCHEMA
gaussdb=# create table best_practices_for_procedure.tb1(a int, b int);
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.
CREATE TABLE
gaussdb=# create or replace procedure best_practices_for_procedure.proc1(a int, b int) immutable as
begin
insert into best_practices_for_procedure.tb1 values(a, b); --仅做示例,不推荐使用。
end;
/
CREATE PROCEDURE
gaussdb=# call best_practices_for_procedure.proc1(2, 5);
ERROR:  INSERT is not allowed in a non-volatile function
CONTEXT:  SQL statement "insert into best_practices_for_procedure.tb1 values(a, b)"
PL/pgSQL function best_practices_for_procedure.proc1(integer,integer) line 3 at SQL statement
gaussdb=# create or replace function best_practices_for_procedure.func1(a int, b int) return int immutable as
begin
return a * b;
end;
/
CREATE PROCEDURE
gaussdb=# call best_practices_for_procedure.func1(2, 5);
 func1
-------
    10
(1 row)

gaussdb=# create or replace procedure best_practices_for_procedure.proc2(a int, b int) shippable as
begin
insert into best_practices_for_procedure.tb1 values(a, b); --仅做示例,不推荐使用。
end;
/
CREATE PROCEDURE
gaussdb=# call best_practices_for_procedure.proc2(2, 5);
 proc2
-------

(1 row)

gaussdb=# create or replace function best_practices_for_procedure.func2(a int, b int) return int shippable as
begin
return a * b;
end;
/
CREATE PROCEDURE
gaussdb=# call best_practices_for_procedure.func2(2, 5);
 func2
-------
    10
(1 row)

gaussdb=# drop schema best_practices_for_procedure cascade;
NOTICE:  drop cascades to 5 other objects
DETAIL:  drop cascades to table best_practices_for_procedure.tb1
drop cascades to function best_practices_for_procedure.proc1(integer,integer)
drop cascades to function best_practices_for_procedure.func1(integer,integer)
drop cascades to function best_practices_for_procedure.proc2(integer,integer)
drop cascades to function best_practices_for_procedure.func2(integer,integer)
DROP SCHEMA

相关文档