Все операторы DDL (GRANT, REVOKE, CREATE и ALTER) должны быть в EXECUTE IMMEDIATE, например
EXECUTE IMMEDIATE 'REVOKE UNLIMITED TABLESPACE FROM '||:ParamUserName;
и
EXECUTE IMMEDIATE 'ALTER USER '||:ParamUserName||' PASSWORD EXPIRE';
На самом деле, я бы упростилэто немного и поместите все внешние переменные в одном месте в начале.
DECLARE
V_CNT INTEGER;
V_USER VARCHAR2(30);
V_ROLE VARCHAR2(30);
BEGIN
--
V_USER := :ParamUserName;
V_ROLE := :ParamSelectedRole;
V_PWD := :ParamUserPassword;
--
SELECT COUNT(*)
INTO V_CNT
FROM dba_users
WHERE username = v_user
IF (CNT > 0) THEN
IF (INSTR(v_role, 'WRITE') = 0) THEN
EXECUTE IMMEDIATE 'REVOKE UNLIMITED TABLESPACE FROM '||v_user;
EXECUTE IMMEDIATE 'REVOKE READ_WRITE FROM '||v_user;
EXECUTE IMMEDIATE 'GRANT READ_ONLY TO '||v_user;
ELSE
EXECUTE IMMEDIATE 'GRANT UNLIMITED TABLESPACE TO '||v_user;
END IF;
ELSE
EXECUTE IMMEDIATE 'CREATE USER '||v_user||
'DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP '||
'IDENTIFIED BY '||v_pwd||' PROFILE ELEV_USER';
EXECUTE IMMEDIATE 'ALTER USER '||v_user||' PASSWORD EXPIRE;
EXECUTE IMMEDIATE 'GRANT '||v_role||' TO '||v_user;
EXECUTE IMMEDIATE 'GRANT CREATE SESSION TO '||v_user;
IF (INSTR(v_role, 'WRITE') > 0 ) THEN
EXECUTE IMMEDIATE 'GRANT UNLIMITED TABLESPACE TO '||v_user;
END IF;
END IF;
END;