Pregunta

I have a Java Stored Procedure in my Oracle database and I need to know who has called it. I want to do different things based on the person who has called it. I googled this on the net but I had no luck.

¿Fue útil?

Solución

Here is my own solution. It mainly consists of two Oracle features:

(1) SYS_CONTEXT function:

SYS_CONTEXT('USERENV', 'SESSION_USER') returns the name of the database user at logon. This value remains the same throughout the duration of the session.

SYS_CONTEXT('USERENV', 'CURRENT_USER') returns the name of the database user whose privileges are currently active.

Depending on the purpose, any or both of these functions could be used. In my example, I'll use both.

(2) Server-Side Internal Driver:

The server-side internal driver is intrinsically tied to Oracle Database and to the Java Virtual Machine (JVM). The driver runs as part of the same process as the database. It also runs within the default session, the same session in which the JVM was started.

To my knowledge, this demo doesn't work without this feature. That's because to run SYS_CONTEXT function, I need to connect to the database in the first place. However, in that case, I will get the same SESSION_USER that I use to connect to the database. Another issue is, I'll loose the context of the current function call. What I want, is to get information about the current function call. This feature gives me what I need.

Here is the working example:

class Demo{

    public static java.lang.String getUser() 
                                         throws java.sql.SQLException {

    java.sql.Statement stmt = null;
    java.sql.ResultSet rs = null;

    try{
        java.sql.Connection con = 
                java.sql.DriverManager.getConnection("jdbc:default:connection");

        java.lang.String query = 
                  "SELECT SYS_CONTEXT('USERENV', 'CURRENT_USER')," +
                  "SYS_CONTEXT('USERENV', 'SESSION_USER') FROM DUAL";


        stmt  = con.createStatement();
        rs = stmt.executeQuery(query);

        rs.next();

        return "Current User: [" + rs.getString(1) + "] ; " +
               "Session User: [" + rs.getString(2) + "]";
    }
    finally{
        rs.close();
        stmt.close();
    }

    }

}

PL/SQL wrapper code:

CREATE OR REPLACE FUNCTION MyFunc
RETURN VARCHAR2
AS
LANGUAGE JAVA
NAME 'Demo.getUser() return java.lang.String';

This function was created under SYS and the EXECUTE privilege on the function was granted to SCOTT.

Here is the execution result:

MYFUNC
----------------------------------
Current User: [SYS] ; Session User: [SCOTT]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top