云服务器内容精选

  • 示例 CREATE OR REPLACE FUNCTION func1 RETURN INT AS BEGIN RETURN 1; END; / CREATE FUNCTION CREATE OR REPLACE PACKAGE pkg IS PROCEDURE proc1(); END pkg; / CREATE PACKAGE CREATE OR REPLACE PACKAGE BODY pkg IS PROCEDURE proc1() AS BEGIN RAISE INFO 'proc1'; END; END pkg; / CREATE PACKAGE BODY -- 运行失效重编译高级包。 CALL pkg_util.gs_compile_schema('public', false, 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) -- 执行函数。 SELECT func1(); func1 ------- 1 (1 row) CALL pkg.proc1(); INFO: proc1 proc1 ------- (1 row) -- 删除已创建的对象。 DROP FUNCTION func1; DROP FUNCTION DROP PACKAGE pkg; NOTICE: drop cascades to function public.proc1() DROP PACKAGE
  • 示例 -- 创建包头包体。 CREATE OR REPLACE PACKAGE pkg_1 AS var1 int; var2 int; PROCEDURE proc1; END pkg_1; / CREATE PACKAGE CREATE OR REPLACE PACKAGE BODY pkg_1 AS PROCEDURE proc1 AS BEGIN var1 := var1 + var2; END; END pkg_1; / CREATE PACKAGE BODY -- 重新创建包头。 CREATE OR REPLACE PACKAGE pkg_1 AS var1 int; var2 int; var3 int; PROCEDURE proc1; END pkg_1; / CREATE PACKAGE -- 查询状态,包体定义未被删除。 SELECT * FROM gs_package WHERE pkgname='pkg_1'; pkgnamespace | pkgowner | pkgname | pkgspecsrc | pkgbodydeclsrc | pkgbodyinitsrc | pkgacl | pkgsecdef --------------+----------+---------+--------------------+----------------------+----------------+--------+----------- 2200 | 10 | pkg_1 | PACKAGE DECLARE +| PACKAGE DECLARE +| | | f | | | var1 int; +| procedure proc1 as +| | | | | | var2 int; +| begin +| | | | | | var3 int; +| var1 := var1 + var2;+| | | | | | procedure proc1; +| end; +| | | | | | end | end | | | (1 row) -- 包体对象被置为无效。 SELECT * FROM pg_object WHERE object_oid = (SELECT oid FROM gs_package WHERE pkgname='pkg_1'); object_oid | object_type | creator | ctime | mtime | createcsn | changecsn | valid ------------+-------------+---------+-------------------------------+-------------------------------+-----------+-----------+------- 171138 | B | 10 | 2024-12-31 16:50:29.923577+08 | 2025-01-17 15:56:42.271533+08 | | 183936 | f 171138 | S | 10 | 2024-12-24 16:09:29.527485+08 | 2025-01-17 15:56:42.271533+08 | | 183936 | t (2 rows) -- 删除已创建的对象。 DROP PACKAGE pkg_1; NOTICE: drop cascades to function public.proc1() DROP PACKAGE -- 包头包体定义被删除。 SELECT * FROM gs_package WHERE pkgname='pkg_1'; pkgnamespace | pkgowner | pkgname | pkgspecsrc | pkgbodydeclsrc | pkgbodyinitsrc | pkgacl | pkgsecdef --------------+----------+---------+------------+----------------+----------------+--------+----------- (0 rows) SELECT * FROM pg_object WHERE object_oid = (SELECT oid FROM gs_package WHERE pkgname='pkg_1'); object_oid | object_type | creator | ctime | mtime | createcsn | changecsn | valid ------------+-------------+---------+-------+-------+-----------+-----------+------- (0 rows)
  • 失效重编译概述 失效重编译提供一次性入库、失效重编译和级联失效功能。 一次性入库:新建存储过程、函数和PACKAGE使用未定义的对象。例如表、函数或类型不存在,可新建成功,打印告警。系统表pg_object对应的valid字段为false。 失效重编译功能:当未定义的对象都存在时,运行失效重编译高级包pkg_util.gs_compile_schema或者alter compile功能时,把对象变为有效,然后正常执行存储过程、函数和PACKAGE。 级联失效功能:当被依赖的对象被删除时,不再级联删除依赖对象,而是失效依赖对象,例如函数出入参依赖表,删除表时,函数失效,但函数未被级联删除。 重新创建包头,不删除原有包体功能:当使用CREATE OR REPLACE PACKAGE覆盖原有包头定义时,已经存在的包体定义不会被删除,而是被失效。支持使用ALTER COMPILE功能,尝试将包体变为有效。 使用该功能,推荐开启如下GUC参数: enable_force_create_obj=on,提供一次性入库功能。 ddl_invalid_mode='invalid',提供级联失效功能。 集中式A兼容模式数据库支持。 开启失效重编参数后,数据库存在用户自定义函数失效对象时,将无法使用\df全量查询或查询单个失效函数,提示存在失效对象报错。 视图依赖函数的场景,重建被依赖函数仅支持自动重建与函数相同schema的视图,其他场景需要手动重建视图。 不支持记录同义词的依赖关系,记录同义词指向的原始对象依赖关系。 不支持记录临时表的依赖关系。 不支持记录物化视图的依赖关系。 PACKAGE和FUNCTION的执行块访问其他对象时,直接调用FUNCTION,直接调用PACKAGE内FUNCTION,直接访问PACKAGE变量记录依赖关系,其他场景不支持记录依赖关系。 PACKAGE和FUNCTION变量的默认值、表达式右值,直接调用FUNCTION,直接调用PACKAGE内FUNCTION,直接访问PACKAGE变量记录依赖关系,其他场景不支持记录依赖关系。 自治事务函数调用,触发依赖对象嵌套编译,依赖对象状态不更新,需要手动ALTER PACKAGE刷新。 匿名块和函数参数的CAST类型转换使用失效PACKAGE的类型时,需要手动ALTER PACKAGE刷新。 父主题: 失效重编译
  • 示例 一次性入库使用示例。 -- 设置如下参数。 SET ddl_invalid_mode='invalid'; SET SET enable_force_create_obj=on; SET -- 新建函数,入参使用的类型不存在。 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 -- 重新创建入参使用的类型。 CREATE TYPE type_not_exist AS (f1 int, f2 text); CREATE TYPE ALTER PACKAGE pkg COMPILE; ALTER PACKAGE 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) 不支持场景报错示例。 view%rowtype、type%rowtype作为函数参数类型使用示例。 -- view%rowtype、type%rowtype作为函数参数类型,正向创建报错。 DROP FUNCTION IF EXISTS func1; DROP VIEW IF EXISTS teview; DROP TABLE IF EXISTS tetab; CREATE TYPE tp1 IS (a int,b int); CREATE TABLE tetab(a int,b int); CREATE OR REPLACE VIEW teview AS SELECT * FROM tetab; gaussdb=# CREATE OR REPLACE FUNCTION func1(a teview%rowtype) gaussdb-# RETURN INTEGER gaussdb-# AS gaussdb$# BEGIN gaussdb$# RETURN 1; gaussdb$# END; gaussdb$# / ERROR: relation does not exist when parse word. DETAIL: relation "teview" referenced by %ROWTYPE does not exist. gaussdb=# CREATE OR REPLACE FUNCTION func1(param1 tp1%rowtype) RETURN INTEGER gaussdb-# AS gaussdb$# BEGIN gaussdb$# RETURN 1; gaussdb$# END; gaussdb$# / ERROR: relation does not exist when parse word. DETAIL: relation "tp1" referenced by %ROWTYPE does not exist. -- 调换顺序后可以入库,无法执行。 DROP FUNCTION IF EXISTS func1; DROP VIEW IF EXISTS teview; DROP TABLE IF EXISTS tetab; CREATE OR REPLACE FUNCTION func1(a teview%rowtype) RETURN INTEGER AS BEGIN RETURN 1; END; / CREATE TABLE tetab(a int,b int); CREATE OR REPLACE VIEW teview AS SELECT * FROM tetab; -- 执行和编译报错。 gaussdb=# SELECT func1((1,2)); ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,2)); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 gaussdb=# ALTER FUNCTION func1 COMPILE; ERROR: relation does not exist when parse word. DETAIL: relation "teview" referenced by %ROWTYPE does not exist. CREATE OR REPLACE FUNCTION func1(param1 tp1%rowtype) RETURN INTEGER AS BEGIN RETURN 1; END; / CREATE TYPE tp1 IS (a int,b int); gaussdb=# SELECT func1((1,2)); ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,2)); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 gaussdb=# ALTER FUNCTION func1 COMPILE; ERROR: relation does not exist when parse word. DETAIL: relation "tp1" referenced by %ROWTYPE does not exist. catalog.schema.type%rowtype、catalog.package.type%rowtype作为函数参数类型使用示例。 -- CATA LOG 相关,跨数据库访问。 DROP DATABASE IF EXISTS tedb1; DROP DATABASE IF EXISTS tedb2; CREATE DATABASE tedb1; CREATE DATABASE tedb2; \c tedb1 CREATE SCHEMA sch1; CREATE TYPE sch1.tp1 IS (a int,b int); CREATE OR REPLACE PACKAGE pkg1 AS TYPE tp1 IS record(a int,b int); END PKG1; / \c tedb2 tedb2=# CREATE OR REPLACE FUNCTION func1(param tedb1.sch1.tp1%rowtype) RETURN INTEGER tedb2-# AS tedb2$# BEGIN tedb2$# RETURN 1; tedb2$# END; tedb2$# / ERROR: cross-database references are not implemented: "tedb1.sch1.tp1" tedb2=# CREATE OR REPLACE FUNCTION func1(param tedb1.pkg1.tp1%rowtype) RETURN INTEGER tedb2-# AS tedb2$# BEGIN tedb2$# RETURN 1; tedb2$# END; tedb2$# / ERROR: cross-database references are not implemented: "tedb1.pkg1.tp1" catalog.package.type作为函数参数类型使用示例。 -- CATALOG相关,跨数据库访问。 DROP DATABASE IF EXISTS tedb1; DROP DATABASE IF EXISTS tedb2; CREATE DATABASE tedb1; CREATE DATABASE tedb2; \c tedb1 CREATE SCHEMA sch1; CREATE TYPE sch1.tp1 IS (a int,b int); CREATE OR REPLACE PACKAGE pkg1 AS TYPE tp1 IS record(a int,b int); END pkg1; / \c tedb2 CREATE OR REPLACE FUNCTION func1(param tedb1.sch1.tp1) RETURN INTEGER AS BEGIN RETURN 1; END; / -- 执行报错,编译无效。 tedb2=# SELECT func1((1,2)); WARNING: Type tp1 does not exist. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement WARNING: Function func1 recompile with compilation errors. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,2)); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 tedb2=# alter function func1 compile WARNING: Type tp1 does not exist. WARNING: Function func1 recompile with compilation errors. ALTER FUNCTION CREATE OR REPLACE FUNCTION func1(param tedb1.pkg1.tp1) RETURN INTEGER AS BEGIN RETURN 1; END; / -- 执行报错,编译无效。 tedb2=# SELECT func1((1,2)); WARNING: Type tp1 does not exist. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement WARNING: Function func1 recompile with compilation errors. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,2)); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 tedb2=# alter function func1 compile; WARNING: Type tp1 does not exist. WARNING: Function func1 recompile with compilation errors. ALTER FUNCTION package.type%rowtype作为函数参数类型使用示例。 -- package.type%rowtype作为函数参数类型。 DROP PACKAGE IF EXISTS pkg1; DROP FUNCTION IF EXISTS func1; CREATE OR REPLACE PACKAGE pkg1 IS TYPE rec IS record(c1 int, c2 varchar); var1 rec; END pkg1; / CREATE OR REPLACE FUNCTION func1(p pkg1.rec%rowtype) RETURN INTEGER IS BEGIN RETURN 1; END; / -- 执行报错,编译无效。 gaussdb=# SELECT func1((1,'var1')); WARNING: relation does not exist when parse word. DETAIL: relation "pkg1.rec" referenced by %ROWTYPE does not exist. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement WARNING: Function func1 recompile with compilation errors. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,'var1')); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 gaussdb=# alter function func1 compile; WARNING: relation does not exist when parse word. DETAIL: relation "pkg1.rec" referenced by %ROWTYPE does not exist. WARNING: Function func1 recompile with compilation errors. ALTER FUNCTION -- 变更顺序。 DROP PACKAGE IF EXISTS pkg1; DROP FUNCTION IF EXISTS func1; CREATE OR REPLACE FUNCTION func1(p pkg1.rec%rowtype) RETURN INTEGER IS BEGIN RETURN 1; END; / CREATE OR REPLACE PACKAGE pkg1 IS TYPE rec IS record(c1 int, c2 varchar); var1 rec; END PKG1; / -- 执行报错,编译无效。 gaussdb=# SELECT func1((1,'var1')); WARNING: relation does not exist when parse word. DETAIL: relation "pkg1.rec" referenced by %ROWTYPE does not exist. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement WARNING: Function func1 recompile with compilation errors. CONTEXT: SQL statement "alter function public.func1 compile" PL/pgSQL function inline_code_block line 11 at SQL statement ERROR: Function func1(record) does not exist. LINE 1: SELECT func1((1,'var1')); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. CONTEXT: referenced column: func1 gaussdb=# alter function func1 compile; WARNING: relation does not exist when parse word. DETAIL: relation "pkg1.rec" referenced by %ROWTYPE does not exist. WARNING: Function func1 recompile with compilation errors. ALTER FUNCTION
  • 失效重编译特性函数 gs_set_object_invalid()/gs_set_object_invalid(schema, objname, objtype) 描述:将PACKAGE和FUNCTION在pg_object中的状态置为false,同时级联将依赖PACKAGE和FUNCTION的对象状态置为false。调用该函数的用户需要具有SYSADMIN权限。 参数:该函数为重载函数。当无入参时,将当前DATABASE内的PACKAGE和FUNCTION对象置为失效。当指定schema、objname、objtype三个参数时可将当前DATABASE内的PACKAGE和FUNCTION对象在pg_object中的状态置为false。其中:schema为对象所属的schema名称;objname为对象名称;objtype为对象类型,对象为package类型时值为“package”,对象为函数或存储过程时值为“function”。 需要将PACKAGE和FUNCTION和依赖PACKAGE和FUNCTION的对象状态置为失效时可以使用该函数。 仅系统管理员可以调用函数。 示例: 该函数不返回失效结果,可通过pg_object系统表查询失效结果,对象有效时查找到对应的valid状态为true,对象失效后对应的valid状态为false。 gs_set_plsql_invalid所属的Schema为pg_catalog,但不指定Schema也可调用该函数。 -- 创建一个包pkg1,pkg2和函数f3,查询pg_object信息,状态为valid。 SET enable_force_create_obj=on; SET SET ddl_invalid_mode=invalid; SET CREATE SCHEMA testInvalidate; CREATE SCHEMA SET CURRENT_SCHEMA TO testInvalidate; SET CREATE OR REPLACE PACKAGE pkg1 AS var1 VARCHAR; FUNCTION f1() RETURN VARCHAR; END pkg1; / CREATE PACKAGE CREATE OR REPLACE PACKAGE BODY pkg1 AS FUNCTION f1() RETURN VARCHAR IS BEGIN var1 := '2'; RETURN var1; END; END pkg1; / CREATE PACKAGE BODY CREATE OR REPLACE PACKAGE pkg2 AS var1 pkg1.var1%TYPE; FUNCTION f2() RETURN VARCHAR; END pkg2; / CREATE PACKAGE CREATE OR REPLACE PACKAGE BODY pkg2 AS FUNCTION f2() RETURN VARCHAR IS BEGIN var1 := '2'; RETURN var1; END; END pkg2; / CREATE PACKAGE BODY CREATE OR REPLACE FUNCTION f3() RETURN VARCHAR IS DECLARE var2 VARCHAR := 'li2'; BEGIN var2='22'; RETURN var2; END / CREATE FUNCTION SELECT pkg1.f1(); f1 ---- 2 (1 row) SELECT pkg2.f2(); f2 ---- 2 (1 row) SELECT f3(); f3 ---- 22 (1 row) -- 调用函数,指定schema、函数名、类型即可将pkg1和pkg2失效,再次查询pg_object,pkg1和pkg2对应的valid为false。 SELECT gs_set_object_invalid('testinvalidate','pkg1','package'); set_object_invalid ------------------------- (1 row) -- 如果要失效function,参数如下所示,查询pg_object,f3对应的valid为false。 SELECT gs_set_object_invalid('testinvalidate','f3','function'); set_object_invalid ------------------------- (1 row) -- 调用时没有入参,则将失效所有缓存对象。 SELECT gs_set_object_invalid(); set_object_invalid ------------------------- (1 row) 父主题: 失效重编译
提示

您即将访问非华为云网站,请注意账号财产安全