我正在尝试在pl / sql中编写一个过程,它将告诉我谁对Oracle数据库中的所有应用程序表都有SELECT,INSERT,UPDATE,DELETE权限。
或者:
现在,当我对用户或表名进行硬编码时,我没有遇到使用#2(例如)创建过程的错误。但是当我尝试创建包含所有这些场景的1个过程时,我在DATA_NOT_FOUND时遇到了问题。
我可以处理异常,但程序会在之后退出。无论是否找到数据,我都无法运行代码。 SQL%NOTFOUND对我不起作用,因为在执行SQL%NOTFOUND的代码之前引发了DATA_NOT_FOUND异常。
我想要发生的是:
该程序循环遍历所有用户
如果有直接授权,变量1 ='TRUE'或使用SELECT INTO完成同样的事情
如果有角色授予,变量2 ='TRUE'或使用SELECT INTO完成同样的事情
如果有系统权限授予,变量3 ='TRUE'或使用SELECT INTO完成相同的事情
如果有DBA角色授权,变量4 ='TRUE'或使用SELECT INTO完成同样的事情
该程序为上述每个项目打印表名,用户名,是/否。
如何修改代码,以便如果User_123对Table_ABC具有SELECT权限,则variable1 ='TRUE',否则variable1 ='FALSE'?如果dba_tab_privs中没有User_123的记录,则不应引发DATA_NOT_FOUND异常。
非常感谢你。
DECLARE
by_tab_priv varchar(20);
BEGIN
dbms_output.enable(1000000);
FOR x IN ( SELECT table_name
FROM dba_tables
WHERE owner IN ('NIKUP')
ORDER BY table_name )
LOOP
BEGIN
FOR y IN ( SELECT username from dba_users
ORDER BY username)
LOOP
SELECT grantee
INTO by_tab_priv
FROM dba_tab_privs
WHERE grantee=y.username
and table_name=x.table_name
and privilege in ('SELECT')
MINUS
SELECT granted_role
FROM dba_role_privs
WHERE granted_role in (
SELECT grantee
FROM dba_tab_privs
WHERE grantee=y.username
and table_name=x.table_name
and privilege in ('SELECT'));
BEGIN
dbms_output.put_line(y.username || ' ' || by_tab_priv);
END;
END LOOP;
END;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
by_tab_priv:='FALSE';
END;
答案 0 :(得分:0)
这样的事情:
begin
select ... into ;
var1 :=TRUE;
exception
when NO_DATA_FOUND then -- controlling the case with no_data_found
var1 := FAlSE;
<强>更新强>
LOOP
BEGIN
SELECT grantee
INTO by_tab_priv
FROM dba_tab_privs
WHERE grantee=y.username
and table_name=x.table_name
and privilege in ('SELECT')
MINUS
SELECT granted_role
FROM dba_role_privs
WHERE granted_role in (
SELECT grantee
FROM dba_tab_privs
WHERE grantee=y.username
and table_name=x.table_name
and privilege in ('SELECT'));
dbms_output.put_line(y.username || ' ' || by_tab_priv);
EXCEPTION
WHEN NO_DATA_FOUND THEN
by_tab_priv:='FALSE';
END;
END LOOP;
异常仅链接到循环内的块,它不是全局异常
块具有如下结构:
BEGIN
EXCEPTION
END
你可以在一个函数中有多个块,每个块都可以自己处理异常。
答案 1 :(得分:0)
使用以下技巧来避免异常
SELECT NVL(MAX(grantee), 'FALSE')
INTO by_tab_priv
FROM (
SELECT
...
MINUS
SELECT
...
)
或者您可以使用SIGN(COUNT(grantee))
,它会返回1
或0