在 Oracle 数据库中,我必须从外部 SQL 文件 - create_users.sql 创建用户列表。
我正在尝试自动执行从一个数据库到另一个数据库的数据刷新过程。我在创建用户后成功完成了数据部分。在用户创建过程中,我面临以下问题。
我正在使用每当sqlerror exit 1,并且如果用户存在于数据库中,则其退出。我需要一种方法来处理该异常,如果用户存在,它应该继续,而对于其他错误,假设如果用户不存在表空间,它应该退出。
我正在寻找一种方法来处理这个问题,只有当用户存在错误时才继续,而在出现其他错误时应该退出。
如果这是唯一的方法,我不确定如何将此 sql 提取到 PL/SQL 代码中。
sqlplus -s "/nolog" <<EOF >$WORK_DIR/sqls/${pdbtns}_${DATE}_create_users.log
WHENEVER SQLERROR EXIT 1;
connect / as sysdba
set head off feed off pages 0
set serveroutput on
@create_users.sql
EOF
这是 create_users.sql 的示例,它包含 500 多个用户的用户创建脚本,具有表授权、系统授权和角色授权。
创建用户.sql
create user vijay identified by vijay;
create user ramesh identified by ramesh;
grant select_catalog_role to vijay;
grant select on app1.table_name1 to vijay;
grant select_catalog_role to ramesh;
grant select on app1.table_name1 to ramesh;
sqlcl 只有“WHENEVER SQLERROR”。无法指示单个错误的具体行为。可以在 pl/sql 中捕获特定错误。在 pl/sql 中,DDL 语句可以使用 EXECUTE IMMEDIATE 执行。
首先确定你需要捕获的错误:
Oracle 错误代码是 01920。使用 pragma EXCEPTION_INIT 将用户定义的异常与 Oracle 错误代码关联。然后将错误捕获到异常块中。
DECLARE
e_user_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(e_user_exists, -01920);
l_statement VARCHAR2(1000);
BEGIN
l_statement := 'create user KOEN no authentication temporary tablespace temp default tablespace data';
EXECUTE IMMEDIATE l_statement;
EXCEPTION WHEN e_user_exists THEN
NULL;
END;
/
运行此块并注意错误已按预期被忽略:
另一个错误仍然会导致脚本失败:
一种可能性是创建一个(临时)表并加载表中的语句,然后使用 pl/sql 循环遍历该表并使用上述技术执行所有语句。