我在Oracle中创建了此过程,根据营销表的成绩列中存储的成绩为用户分配角色。但是,当我运行它时,我会收到错误。
初始问题
CREATE OR REPLACE PROCEDURE proc_assign_role IS
vn_grade NUMBER(5);
CURSOR cur_user_grade IS
SELECT grade, username
FROM marketing
WHERE grade BETWEEN 1 AND 3;
BEGIN
FOR rec_cur_user_grade IN cur_user_grade
vn_grade:=
IF grade= 1
THEN
GRANT ROLE admin_staff;
ELSIF grade= 2 THEN
GRANT ROLE marketing_staff;
ELSIF grade= 3 THEN
GRANT ROLE event_staff;
END IF;
DBMS_OUTPUT.PUT_LINE(username||'YOU ARE A GRADE '||vn_grade|| 'USER');
END proc_assign_role;
/
这是我得到的错误:
ERROR at line 11: PLS-00103: Encountered the symbol "VN_GRADE" when expecting one of the following:
. ( * @ % & - + / at loop mod remainder range rem ..
|| multiset
1. CREATE OR REPLACE PROCEDURE proc_assign_role IS
2. vn_grade NUMBER(5);
答案 0 :(得分:2)
vn_grade:=
您需要为该行指定一个值,或者删除它。您不能将IF语句分配给数字变量。可能摆脱它,然后改变你的IF语句来查看光标的等级。你还需要结束循环。
此外,您无法直接在PL / SQL代码块中执行授权。您必须使用execute immediate语句。你必须告诉它你是谁给予了这个角色。
FOR rec_cur_user_grade IN cur_user_grade LOOP
IF rec_cur_user_grade.grade= 1 THEN
execute immediate 'GRANT ROLE admin_staff to ' || rec_cur_user_grade.username;
ELSIF rec_cur_user_grade.grade= 2 THEN
execute immediate 'GRANT ROLE marketing_staff to ' || rec_cur_user_grade.username;
ELSIF rec_cur_user_grade.grade= 3 THEN
execute immediate 'GRANT ROLE event_staff to ' || rec_cur_user_grade.username;
END IF;
DBMS_OUTPUT.PUT_LINE(username||'YOU ARE A GRADE '||rec_cur_user_grade.grade|| 'USER');
END LOOP;
答案 1 :(得分:1)
我看到一些可以防止这种情况发生的事情:
FOR
语句之后,没有LOOP
语句(错误是抱怨的)。 END LOOP
之后也没有DBMS_OUTPUT
。vn_grade
之后是:=
赋值运算符,但没有赋值给它。GRANT
语句写为裸DDL,PL / SQL中不允许这样做。它们需要包含在EXECUTE IMMEDIATE
。grade
和username
需要通过游标变量进行限定(例如rec_cur_user_grade.grade
和rec_cur_user_grade.username
)。尝试这样的事情(作为匿名块运行,而不是程序,并使用隐式游标):
BEGIN
FOR rec_cur_user_grade IN (
SELECT grade, username
FROM marketing
WHERE grade BETWEEN 1 AND 3
)
LOOP
CASE rec_cur_user_grade.grade
WHEN 1 THEN
EXECUTE IMMEDIATE 'GRANT ROLE admin_staff TO ' || rec_cur_user_grade.username;
WHEN 2 THEN
EXECUTE IMMEDIATE 'GRANT ROLE marketing_staff TO ' || rec_cur_user_grade.username;
WHEN 3 THEN
EXECUTE IMMEDIATE 'GRANT ROLE event_staff TO ' || rec_cur_user_grade.username;
END CASE;
DMBS_OUTPUT.PUT_LINE(rec_cur_user_grade.username || ' YOU ARE A GRADE ' || rec_cur_user_grade.grade || ' USER');
END LOOP;
END;
/
答案 2 :(得分:0)
grant
是DDL,因此无法直接在PL / SQL中使用。为了实现这一点,需要使用execute immediately
动态执行DDL。此外,grant
始终要求您指定角色的收件人。结果将是这样的:
execute immediate 'GRANT ROLE admin_staff to ' || rec_cur_user_grade.username;
ORA-00990: missing or invalid privilege
错误相当自我描述:过程的所有者没有必要的权限来执行过程尝试的操作。
这里最可能的罪魁祸首是角色:角色授予的权限不能在过程中使用。您应该采取的第一步是确保已明确授予该过程的所有者管理所涉及角色的权限。