Skip to content
Keep Learning Keep Living
Keep Learning Keep Living

Using “User” function in a scheduled Job

Mustafa Kalaycı, 2020-03-17

Hi there,

I wanted to talk about a problem that I faced recently. Also I thought about the subject because this post is also related with “Session user vs Schema”.  Whenever I use the term of “Job” I will be talking about Dbms_Scheduler Jobs not Dbms_Job!

When you created a job for a different user (if you have create any job privilege) session user and schema become important and might cause some headache. Let’s create 2 users and one of them privileged user (Admin_User) and the other is regular user (Regular_User).

Oracle PL/SQL
1
2
3
4
5
6
7
8
9
10
11
sqlplus / as sysdba
create user admin_user identified by admin_user;
grant dba to admin_user;
grant create any job to admin_user;
grant execute on dbms_lock to admin_user;
 
create user regular_user identified by regular_user;
grant connect to regular_user ;
grant create job to regular_user ;
grant execute on dbms_lock to regular_user ;
grant select on sys.user$ to regular_user;

if you realize I grant select on SYS.USER$ to regular_user and not to admin_user. even if admin_user is a dba user, it has no privilege to select on sys tables. so regular_user now has the privilege to select sys.user$ but not admin_user. I will use that table in my demo.

So admin_user will create a job for regular_user which means job will be created by admin_user but will run under the regular_user(job will belong to regular_user).

Let’s create some sample code to demonstrate.

Oracle PL/SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
Conn admin_user/admin_user
 
create table admin_user.log(mydata varchar2(4000), time timestamp);
 
create or replace procedure admin_user.sp_log(p_data varchar2) as
  pragma autonomous_Transaction;
begin
  insert into admin_user.log values (p_data, systimestamp);
  commit;
end;
/
Grant select on admin_user.log to public;
Grant execute on admin_user.sp_log to public;

this code is just for logging and I will log some information in the job.

My job code is:

Oracle PL/SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
declare
  x_count number;
begin
  Dbms_lock.Sleep(20); --wait 20 seconds
  
  admin_user.sp_log('User: ' || User); -- add current user name to log
  
  Select count(*) Into x_count
  From   sys.user$;
  
  admin_user.sp_log('Number of user$: ' || x_count); -- add Number of user$
end;
/

if you run this code on Admin_User session then you will got an error: “ORA-00942: table or view does not exist” because Admin_User has no select privilege on Sys.User$ and if you run this code using Regular_User session, it will complete successfully and here is the log table content:

Oracle PL/SQL
1
2
3
4
5
select * from admin_user.log order by time;
MYDATA                  TIME  
-------------------------------------------
User: REGULAR_USER 17/03/2020 11.50.29,732000000
Number of user$: 133 17/03/2020 11.50.29,734000000

Now Let’s create jobs using Admin_User and see the result:

Oracle PL/SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
--First For the Admin_User
Begin
  Dbms_Scheduler.Create_Job(Job_Name => 'ADMIN_USER.JOB_ADMIN',
                            Job_Action => q'!declare
  x_count number;
begin
  Dbms_lock.Sleep(20); --wait 20 seconds
  
  admin_user.sp_log('User: ' || User); -- add current user name to log
  
  Select count(*) Into x_count
  From   sys.user$;
  
  admin_user.sp_log('Number of user$: ' || x_count); -- add Number of user$
end;!',
  Job_Type => 'PLSQL_BLOCK',
  enabled=> true);
End;
/
 
select owner, Job_Name, Status, Additional_Info
from   dba_scheduler_job_run_details
Where  Job_Name = 'JOB_ADMIN'
order by log_Date desc;
OWNER           JOB_NAME        STATUS    ADDITIONAL_INFO
-------------------------------------------------------
ADMIN_USER JOB_ADMIN FAILED    "...table or view does not exist"

as expected job failed with table or view does not exists. Now admin_user will create a job for regular_user with same code (of course OWNER of job will be changed:

Oracle PL/SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Conn admin_user/admin_user
 
truncate table admin_user.log;
 
Begin
  Dbms_Scheduler.Create_Job(Job_Name => 'REGULAR_USER.JOB_REGULAR',
                            Job_Action => q'!declare
  x_count number;
begin
  Dbms_lock.Sleep(20); --wait 20 seconds
  
  admin_user.sp_log('User: ' || User); -- add current user name to log
  
  Select count(*) Into x_count
  From   sys.user$;
  
  admin_user.sp_log('Number of user$: ' || x_count); -- add Number of user$
end;!',
  Job_Type => 'PLSQL_BLOCK',
  enabled=> true);
End;
/

I added the Dbms_Lock.Sleep to examine the session of the job. after creating job, let’s check the session:

Oracle PL/SQL
1
2
3
4
Select Username, SchemaName, program from v$session where action = 'JOB_REGULAR';
USERNAME        SCHEMANAME      PROGRAM
-------------------------------------------------
ADMIN_USER REGULAR_USER ORACLE.EXE (J000)

As you see, Job’s session user is ADMIN_USER not regular_user but schema name is REGULAR_USER and since it is running this means job didn’t get “table or view does not exist” error.

After completing job, I check the job log:

Oracle PL/SQL
1
2
3
4
5
6
7
8
select OWNER, JOB_NAME, STATUS, ADDITIONAL_INFO
from   dba_scheduler_job_run_details
Where  Job_Name = 'JOB_REGULAR'
order by log_Date desc;
 
OWNER          JOB_NAME         STATUS          ADDITIONAL_INFO
--------------------------------------------------------------------------
REGULAR_USER JOB_REGULAR SUCCEEDED Null

as you see job completed successfully. when we check our own log:

Oracle PL/SQL
1
2
3
4
5
select * from admin_user.log order by time;
MYDATA                  TIME  
-------------------------------------------
User: ADMIN_USER 17/03/2020 12.11.06,387000000
Number of user$: 133 17/03/2020 12.11.06,387000000

job has run under the ADMIN_USER user but run with REGULAR_USER privileges. This tells us two important things.

1- Privileges are inherited from SchemaName not UserName

2- Using  USER function (or similarly Sys_Context(‘USERENV’, ‘SESSION_USER’) context variable) can cause problems. because since job is belong to REGULAR_USER you might think that job is running as REGULAR_USER but it is ADMIN_USER. so if you want to get job’s owner you must use Sys_Context(‘USERENV’, ‘CURRENT_SCHEMA‘) instead of USER function.

11g 12c 18c 19c Administration job ownerjob privilegessession schemaUSER function in job

Post navigation

Previous post
Next post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • 26ai Alert Log Size
  • What Should Change After Base DB System Clone
  • Using MFA While Logging into the Oracle Database
  • 2 of Most Practical New Features on 23.9
  • Milliseconds are lost after date to tz conversion on 19c

Recent Comments

  1. Mustafa on How to call HTTPS Url Without SSL Wallet in 19c
  2. Donatas on How to call HTTPS Url Without SSL Wallet in 19c
  3. Mustafa on 3 Ways to Migrate a Non-CDB Database to a PDB
  4. ulises lazarini on 3 Ways to Migrate a Non-CDB Database to a PDB
  5. Mustafa on How to call HTTPS Url Without SSL Wallet in 19c

Archives

  • November 2025
  • August 2025
  • July 2025
  • June 2025
  • April 2025
  • November 2024
  • July 2024
  • April 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • October 2021
  • September 2021
  • August 2021
  • April 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • July 2019
  • June 2019
  • May 2019
  • March 2019
  • February 2019
  • June 2018

Categories

  • 11g
  • 12c
  • 18c
  • 19c
  • 21c
  • 23ai
  • 26ai
  • Administration
  • Cloud
  • Compression
  • Development
  • Materialized View
  • Multi-tenant
  • Performance
  • Security
  • SQL / PLSQL
  • Uncategorized
  • Undocumented
  • Useful Scripts
©2025 Keep Learning Keep Living | WordPress Theme by SuperbThemes