我的 Oracle 数据库中有一个 Java 存储过程,我需要知道是谁调用了它。我想根据打电话的人做不同的事情。我在网上搜索了这个,但我没有运气。
问问题
465 次
1 回答
7
这是我自己的解决方案。它主要由两个Oracle特性组成:
(1) SYS_CONTEXT 函数:
SYS_CONTEXT('USERENV', 'SESSION_USER')
返回登录时数据库用户的名称。该值在整个会话期间保持不变。
SYS_CONTEXT('USERENV', 'CURRENT_USER')
返回其权限当前处于活动状态的数据库用户的名称。
根据目的,可以使用这些功能中的任何一个或两个。在我的示例中,我将同时使用两者。
(2)服务器端内部驱动:
服务器端内部驱动程序本质上与 Oracle 数据库和 Java 虚拟机 (JVM) 相关联。驱动程序作为与数据库相同的进程的一部分运行。它还在默认会话中运行,即启动 JVM 的同一会话。
据我所知,如果没有此功能,此演示将无法运行。那是因为要运行SYS_CONTEXT
函数,我首先需要连接到数据库。但是,在这种情况下,我将得到与SESSION_USER
连接数据库相同的结果。另一个问题是,我将失去当前函数调用的上下文。我想要的是获取有关当前函数调用的信息。这个功能给了我我需要的东西。
这是工作示例:
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 包装代码:
CREATE OR REPLACE FUNCTION MyFunc
RETURN VARCHAR2
AS
LANGUAGE JAVA
NAME 'Demo.getUser() return java.lang.String';
此函数是在 下创建的,SYS
并且该EXECUTE
函数的特权被授予SCOTT
。
下面是执行结果:
MYFUNC
----------------------------------
Current User: [SYS] ; Session User: [SCOTT]
于 2013-04-29T13:51:51.407 回答