oracle - DBMS_METADATA.GET_DDL 在 PROCEDURE 中不起作用
问题描述
我创建了一个脚本来从 DEVBASE 用户复制一个表:
DECLARE
YTABLE_NAME CONSTANT VARCHAR2 (50) := 'TABLE_NAME';
YRECREATE CONSTANT BOOLEAN := FALSE;
--
XCOMMAND CLOB;
FUNCTION TABLE_EXISTS (ZTABLE_NAME IN VARCHAR2)
RETURN BOOLEAN IS
XCOUNT NUMBER;
BEGIN
SELECT COUNT (*)
INTO XCOUNT
FROM USER_TABLES A
WHERE A.TABLE_NAME = ZTABLE_NAME;
RETURN XCOUNT > 0;
END;
BEGIN
IF TABLE_EXISTS (YTABLE_NAME) THEN
IF YRECREATE THEN
EXECUTE IMMEDIATE 'DROP TABLE ' || YTABLE_NAME || ' CASCADE CONSTRAINTS';
ELSE
RAISE_APPLICATION_ERROR (-20000, 'TABLE ' || YTABLE_NAME || ' ALREADY EXISTS');
END IF;
END IF;
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'EMIT_SCHEMA', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_CREATION', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', FALSE);
XCOMMAND := DBMS_METADATA.GET_DDL ('TABLE', YTABLE_NAME, 'DEVUSER');
EXECUTE IMMEDIATE XCOMMAND;
END;
它可以工作,但是如果我使用此代码创建一个过程,我会收到错误“ORA-31603:在模式 DEVUSER 中找不到 TABLE 类型的对象 {表名}”。
CREATE OR REPLACE PROCEDURE COPY_TABLE (YTABLE_NAME IN VARCHAR2, YRECREATE IN BOOLEAN) IS
BEGIN
-- exact same code
END;
为什么会这样?
解决方案
Oracle文档指出:
在存储过程、函数和定义者权限包中,角色被禁用。因此,这样的 PL/SQL 程序只能在自己的模式中获取对象的元数据。如果你想编写一个 PL/SQL 程序来获取不同模式中对象的元数据,你必须使程序调用者权限。
为此,您必须添加authid
到您的过程中。
推荐阅读
- java - 当输入查询只是该数据的一部分时,如何使用 Room 从我的数据库中获取数据?
- sql-server - 在 SQL Server 中格式化 GETDATE()
- mongodb - MongoDB 是否有任何电子池/可扩展性技术?
- algorithm - 同一矩阵上的最大平方 dp
- linux - 使用 scale_npp 过滤器 ffmpeg 调整大小时损坏的输出
- azure-data-factory - 与 ADF 数据流相关的成本
- ios - 当 SwiftUI Picker 选择更改 EnvironmentObject 时,有没有办法调用函数?
- c - 关于 break 语句
- ruby-on-rails - 每当调度 gem 忽略“命令”方法
- asp.net - 使用 web.config 规则重定向到子域