PL/SQL Hierarchical Profiler in Autonomous Database - oracle

How can I use the PL/SQL hierarchical profiler in an Oracle autonomous database? When I try to run the following code, I get the error "PLS-00201: identifier 'DBMS_HPROF' must be declared":
begin
sys.dbms_hprof.create_tables(force_it => true);
end;
/
The package DBMS_HPROF exists but is not granted to any user:
SQL> select owner,object_name,object_type from dba_objects where object_name='DBMS_HPROF' order by 1,2,3;
OWNER OBJECT_NAME OBJECT_TYPE
------- ------------ -------------
PUBLIC DBMS_HPROF SYNONYM
SYS DBMS_HPROF PACKAGE
SYS DBMS_HPROF PACKAGE BODY
SQL> select * from dba_tab_privs where table_name = 'DBMS_HPROF';
no rows selected
If this was a local database, I would logon as SYS and run grant execute on sys.dbms_hprof to my_username;. But as far as I know, there is no way to run a command as SYS on an Oracle autonomous database.
If this was Amazon RDS, I could probably run a command like RDSADMIN.RDSADMIN_UTIL.GRANT_SYS_OBJECT(.... But as far as I know, there is no such package on an Oracle autonomous database. None of the DBMS_CLOUD* packages seem to have what I'm looking for either.
I'm using Oracle 21c Autonomous Data Warehouse on the Always Free tier.
Is there a way to run the PL/SQL hierarchical profiler on the cloud? Or am I stuck using the older profiler as a work around?

Try following MOS ER: 34369019. As for all MOS documents, this requires a login.

Related

PL/SQL: ORA-01031: insufficient privileges 6/1 PL/SQL: SQL Statement ignored GRANT

Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
I'm getting the above message when trying to create a package.
I can simulate with a very simple procedure and select statement.
My understanding is that have SQL select access for a user does not translate to PL/SQL (package) access for the same user, and that an option is to use roles. This has not worked for me.
This is all done with the same user (not apex_180100).
Showing the issue:
This SQL works. It doesn't make sense, but proves that I can select from the tables.
SELECT 1
FROM apex_180100.wwv_flow_activity_log l,
apex_180100.wwv_flow_worksheet_rpts r
WHERE l.ir_report_id IS NOT NULL
AND l.flow_id = 100
AND l.worksheet_id = r.worksheet_id
AND l.ir_report_id = r.id
AND l.flow_id = r.flow_id
AND l.step_id = r.page_id;
I granted select to a role
GRANT SELECT ON apex_180100.wwv_flow_worksheet_rpts TO PRIV_FULL_TABLE;
GRANT SELECT ON apex_180100.wwv_flow_activity_log TO PRIV_FULL_TABLE;
I grant my role to my procedure (ultimately I will grant to my package)
GRANT PRIV_FULL_TABLE TO PROCEDURE p_test;
I get an error when creating this simple sample procedure.
create OR REPLACE procedure p_test is
V_TEST NUMBER;
begin
SELECT 1
INTO V_TEST
FROM apex_180100.wwv_flow_activity_log l,
apex_180100.wwv_flow_worksheet_rpts r
WHERE l.ir_report_id IS NOT NULL
AND l.flow_id = 100
AND l.worksheet_id = r.worksheet_id
AND l.ir_report_id = r.id
AND l.flow_id = r.flow_id
AND l.step_id = r.page_id;
end;
PL/SQL: ORA-01031: insufficient privileges compilation error
Hm, there's something strange in what you are saying. Usually we grant privileges to users, not procedures.
SQL> create procedure p_test as begin
2 null;
3 end;
4 /
Procedure created.
SQL> create role priv_full_table;
Role created.
SQL> grant priv_full_table to procedure p_test;
grant priv_full_table to procedure p_test
*
ERROR at line 1:
ORA-00991: only MAC privileges may be granted to procedures
SQL>
Apart from that, if I understood you correctly, issue is exactly what you thought that solves it: privileges granted to roles won't work in named stored procedures. p_test is a named procedure:
create OR REPLACE procedure p_test is ...
which means that you'll have to grant those privileges directly to user which will be using them.
Thanks to #Littlefoot
I used a workaround. My procedure is relatively simple, I wanted to insert into a custom table from my "problem" tables. I wanted this to be called by an hourly DB job.
As I can select and insert in SQL, but not PL/SQL procedures, I used a SQL script instead of datbase procedure.
i.e I converted my package into a series of SQL statements. I stored this sql script on the server and ran as a DBA job executable.
Not ideal.
PS 'execute immediate' doesn't work either.

How to see my own actual Oracle SQL statement that is being executed as normal user

How to see my own actual Oracle SQL statement that is being executed as normal user not DBA?
Which grants are needed? v_$session? ...
Oracle v$ views are named V_$VIEWNAME and their synonyms are created as: V$VIEWNAME
You need to give the SELECT rights on it as follows:
SQL> grant select on v_$session to <your_user>;

ORA-00980 synonym translation no longer valid in PLSQL

I've got a synonym on a remote Oracle database that I can access in SQL over a database link, eg,
insert into my_table select * from my_synonym#my_database_link;
If I put the above statement into a PLSQL block, it won't compile, giving the error message "ORA-00980: synonym translation is no longer valid". The standard explanation is the table that the synonym points to has been dropped, etc, but this is not the case because the statement works in SQL.
If something works in SQL but not in PL/SQL then in most cases this is a problem with privileges.
Any privilege that a user received through a role is not active when you enter a PL/SQL block. So most probably the SELECT privilege on the underlying table was granted through a role and thus is not "active" in the PL/SQL block.
The usual cure for this is to grant the privileges directly to the user, not through a role.
Thank you to everyone who tried to help. This turned out to be an Oracle limitation:
https://support.oracle.com/rs?type=doc&id=453754.1
APPLIES TO:
PL/SQL - Version 9.2.0.8 and later Information in this document
applies to any platform.
Checked for relevance on 01-Apr-2015
SYMPTOMS
A PL/SQL block fails with error: ORA-00980: synonym translation is no
longer valid, when selecting data from a remote database. The
following code demonstrates this issue:
On DB3 (create the table)
CONNECT u3/u3 DROP TABLE tab; CREATE TABLE tab(c1 number); INSERT
INTO tab VALUES (1); COMMIT;
On DB2 (create a synonym to the table on DB3)
CONNECT u2/u2 DROP DATABASE LINK dblink2; CREATE DATABASE LINK
dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING 'EMT102U6'; SELECT *
FROM global_name#dblink2; DROP SYNONYM syn2; CREATE SYNONYM syn2
FOR tab#dblink2; SELECT * FROM syn2;
On DB1 (create a synonym to the synonym on DB2)
CONNECT u1/u1 DROP DATABASE LINK dblink1; CREATE DATABASE LINK
dblink1 CONNECT TO u2 IDENTIFIED BY u2 USING 'EMT102W6'; SELECT *
FROM global_name#dblink1; DROP SYNONYM syn1; CREATE SYNONYM syn1
FOR syn2#dblink1; SELECT c1 from syn1;
This works in SQL but fails when called from PL/SQL
DECLARE num NUMBER; BEGIN SELECT c1 INTO num FROM syn1; END;
/
ERROR at line 4: ORA-06550: line 4, column 3: PL/SQL: ORA-00980:
synonym translation is no longer valid ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
CAUSE
This issue was reported in Bug 2829591 QUERING FROM A PL/SQL
PROCEDURE IN 9I -> 8I-> 7.3.4, GETTING ORA-980. This bug was closed
as 'NOT A BUG' for the following reasons
PL/SQL cannot instruct middle database (DB2) to follow the database
link during the compilation phase. Therefore in order for this PL/SQL
block to compile and run, both database links dblink1 and dblink2
should be defined on the front end database - DB1. During runtime
database link dblink2 will be looked up in DB2 as expected.
SOLUTION
To implement the solution, please execute the following steps:
Create a database link dblink2 on DB1 pointing to DB3
SQL> create database link dblink2 connect to u3 identified by u3 using
'EMT102U6';
Create and compile the PL/SQL block on DB1.
CREATE DATABASE LINK dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING
'EMT102U6';
SELECT * FROM global_name#dblink2; DECLARE num NUMBER; BEGIN
SELECT c1 INTO num FROM syn1; END; / PL/SQL procedure successfully
completed.
TIP: Another option is to use dyanmic SQL in the PL/SQL block as a
work around. When using dynamic SQL the database link is not resolved
at compile time but at runtime.
Workaround solution is to use an Oracle view instead.
CREATE VIEW v_my_synomym as (select * from my_synonym#my_database_link);
Then reference the view in your package or procedure i.e.:
insert into my_table select * from v_my_synonym;
Check in remote database grants for "my_synonym" must be almost "select" for the user you use in connect string, check also the object which this synonym points at (maybe someone deleted the table).
I found this issue when owner of the table/view/procedure are not match with owner mentioned in SYNONYM.
Example : If owner of table TABLE_BRACH is ownerA and in Synonym mentioned table owner is something else (Not ownerA).
Solution:
1. Drop the SYNONYM
2. Create that with same name with correct owner.
CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;

Oracle - how to export security policies

Our Oracle DBA is planning to move a number of schemas to new instances. One thing we've noticed - security policies are not being carried over in the exports. Also- they don't seem to count as 'objects' when querying 'all_objects' or 'user_objects'. Different kind of animal I guess.
Any ideas on how to migrate this stuff smoothly?
Personally I use a tool to extract/generate scripts for specific users or roles. Toad can script users, as can other tools. The one I now use is my own, but I cannot promote it here. If you don't have such a tool, there are other options.
Use export or data pump. When you do full system export (using exp or data pump) you will get all of the grants. You can then use the import / impdp utilities to dump all of the DDL for the grants for users of interest. Once you have the dmp file.
impdp system/ full=Y directory=dumpdir dumpfile=full.dmp logfile=dump.txt grants=y
Or for export
imp system/ full=y grants=y file=full.dmp log=dump.txt
This will dump everything to the dump.txt in text form and you can extract the SQL. Not super pretty, but works.
Use DBMS_METADATA to give you the grants for a user or role.
SQL> set long 50000
SQL> select dbms_metadata.get_ddl( 'USER', 'MSMITH' ) from dual;
SQL> select dbms_metadata.get_granted_ddl('SYSTEM_GRANT', 'MSMITH') from dual;
SQL> select dbms_metadata.get_granted_ddl('OBJECT_GRANT', 'MSMITH') from dual;
SQL> select dbms_metadata.get_granted_ddl('ROLE_GRANT', 'MSMITH') from dual;
Or for roles:
SQL> select dbms_metadata.get_ddl( 'ROLE', 'JUNIOR_DBA' ) from dual;
SQL> select dbms_metadata.get_granted_ddl('SYSTEM_GRANT', 'JUNIOR_DBA') from dual;
SQL> select dbms_metadata.get_granted_ddl('OBJECT_GRANT', 'JUNIOR_DBA') from dual;
SQL> select dbms_metadata.get_granted_ddl('ROLE_GRANT', 'JUNIOR_DBA') from dual;

Oracle XE 10g : Job Scheduling w/in a package or procedure : DBA_SCHEDULER_JOBS

I have a package that compiles fine in another 11g environment.
When I try to compile it in my XE 10g environment w/ a DBA User, I get the ORA-00942 error.
FOR r IN (SELECT DISTINCT job_name jname
FROM dba_scheduler_jobs
^
WHERE job_name LIKE p_job_prefix || '%')
LOOP
...
When I execute a direct select on the table there is no issue.
Select * from dba_scheduler_jobs;
Error Text:
Line: 34 Column: 34 Error: PL/SQL: ORA-00942: table or view does not exist
In order to reference an object in a definer's rights stored procedure (the default), the owner of the procedure has to have direct access to the object. The privilege cannot be granted through a role, even a very powerful role like SYSDBA.
You probably want to grant the owner of this procedure the SELECT ANY DICTIONARY privilege
GRANT select any dictionary
TO <<owner of procedure>>
You could also grant the privileges on each object (i.e. DBA_SCHEDULER_JOBS) individually but if you've already granted this user the SYSDBA privilege, you're probably not overly concerned with restricting grants.

Resources