What is the difference between USER() and SYS_CONTEXT('USERENV','CURRENT_USER')?

From the manual at: http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions184.htm#SQLRF51825

CURRENT_USER

The name of the database user whose privileges are currently active. This may change during the duration of a session to reflect the owner of any active definer's rights object. When no definer's rights object is active, CURRENT_USER returns the same value as SESSION_USER. When used directly in the body of a view definition, this returns the user that is executing the cursor that is using the view; it does not respect views used in the cursor as being definer's rights.

SESSION_USER

The name of the database user at logon. For enterprise users, returns the schema. For other users, returns the database user name. This value remains the same throughout the duration of the session.

So there is a difference between SESSION_USER and CURRENT_USER especially when CURRENT_USER is used in a stored procedure or function.

I have to admit that I don't know what the term "enterprise user" means though.

Btw: there is a third one:

SESSION_USERID

The identifier of the database user at logon.


sys_context('USERENV', 'CURRENT_SCHEMA') - The schema that is currently being used and as you already found out can be changed with alter session

sys_context('USERENV', 'SESSION_USER') - The user that was used for authentication during the creation of the session and cannot be changed

sys_context('USERENV', 'CURRENT_USER') - Pretty much like "session_user" deprecated (at least according to the 10g documentation)
(editted according to @a_horse_with_no_name's answer and the reference he gave to the 11g docs)

sys_context('USERENV', 'AUTHENTICATED_IDENTITY') - The identity used for authentication, depends on the "AUTHENTICATION_METHOD".
from documentation:

  • Kerberos-authenticated enterprise user: kerberos principal name
  • Kerberos-authenticated external user : kerberos principal name; same as the schema name
  • SSL-authenticated enterprise user: the DN in the user's PKI certificate
  • SSL-authenticated external user: the DN in the user's PKI certificate
  • Password-authenticated enterprise user: nickname; same as the login name
  • Password-authenticated database user: the database username; same as the schema name
  • OS-authenticated external user: the external operating system user name
  • Radius/DCE-authenticated external user: the schema name
  • Proxy with DN : Oracle Internet Directory DN of the client
  • Proxy with certificate: certificate DN of the client
  • Proxy with username: database user name if client is a local database user; nickname if client is an enterprise user.
  • SYSDBA/SYSOPER using Password File: login name
  • SYSDBA/SYSOPER using OS authentication: operating system user name

user pseudo column - I'm not sure, according to documentation I'd think it's like CURRENT_SCHEMA but apparently it's like CURRENT_USER


There is an important note to take into account when using the USER function from PL/SQL. As I have documented in this blog post, STANDARD.USER() is implemented as follows:

function USER return varchar2 is
c varchar2(255);
begin
    select user into c from sys.dual;
    return c;
end;

So, it delegates to evaluating user in the SQL engine, which leads to a hidden PL/SQL to SQL context switch. If you're doing that too often, e.g. from within a trigger, then that can turn out to be quite hurtful in a production system. Try to avoid calling USER() from PL/SQL, and use sys_context('USERENV', 'SESSION_USER') instead.