【发布时间】:2010-11-14 21:31:51
【问题描述】:
如何在 Oracle 中创建或替换角色(可能存在也可能不存在)?例如,以下内容不起作用:
CREATE OR REPLACE ROLE role_name;
GRANT SELECT ON SCM1_VIEW_OBJECT_VW TO role_name;
在没有 PL/SQL 的情况下有什么方法可以做到这一点?
【问题讨论】:
如何在 Oracle 中创建或替换角色(可能存在也可能不存在)?例如,以下内容不起作用:
CREATE OR REPLACE ROLE role_name;
GRANT SELECT ON SCM1_VIEW_OBJECT_VW TO role_name;
在没有 PL/SQL 的情况下有什么方法可以做到这一点?
【问题讨论】:
解决方案
给定答案和 pragma 控件的组合为 Oracle 10g 完成了这项任务。
CREATE OR REPLACE PROCEDURE create_role( role_name IN VARCHAR2 ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
EXECUTE IMMEDIATE 'CREATE ROLE '||role_name;
EXCEPTION
WHEN OTHERS THEN
-- ORA-01921: If The role name exists, ignore the error.
IF SQLCODE <> -01921 THEN
RAISE;
END IF;
END create_role;
测试
这个序列有效:
DROP ROLE role_name;
CREATE ROLE role_name;
CALL create_role( 'role_name' );
CALL create_role( 'role_name' );
最终的创建角色语句失败,正如预期的那样:
DROP ROLE role_name;
CALL create_role( 'role_name' );
CREATE ROLE role_name;
【讨论】:
最佳实践是尝试创建角色,然后在发生时优雅地处理相应的异常;这意味着您不需要运行可能代价高昂的数据字典查询:
begin
execute immediate 'create role role_name';
exception
when others then
--"ORA-01921: role name 'x' conflicts with another user or role name"
if sqlcode = -01921 then
null;
else
raise;
end if;
end;
是的,您需要 PL/SQL 来执行此操作 - 无论如何,它是完成这项工作的最佳工具。
【讨论】:
DECLARE
v_dummy NUMBER;
BEGIN
SELECT 1
INTO v_dummy
FROM dba_roles
WHERE role = 'MY_ROLE_NAME';
EXCEPTION
WHEN no_data_found THEN
EXECUTE IMMEDIATE 'CREATE ROLE my_role_name';
END;
/
【讨论】:
角色的“创建或替换”没有语法。不确定您的 Oracle 版本,但我记得这并没有太大变化。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_6012.htm
您可以多次向角色授予选择权,只要角色存在,它将每次都接受授予。
如果角色已经存在,或者通过查询 DBA_ROLES 来查看角色是否存在,您可以执行匿名阻止并忽略执行。
【讨论】: