Phr*_*cus 4 java sql plsql stored-procedures entitymanager
我想通过实体管理器从 Java 程序中调用 PL/SQL 存储过程:
StoredProcedureQuery storedProcedureQuery = entityManager.createStoredProcedureQuery("someProcedure");
Run Code Online (Sandbox Code Playgroud)
现在我的理解是,我必须在此storedProcedureQuery 上调用execute() 才能执行该过程并能够检索OUT 参数。但是,我可以通过简单地调用来检索这些值,而无需调用execute()方法
someValue1 = (Integer)storedProcedureQuery.getOutputParameterValue(1);
someValue2 = (Integer)storedProcedureQuery.getOutputParameterValue(2);
Run Code Online (Sandbox Code Playgroud)
这怎么可能 ?这段代码片段中的存储过程到底什么时候执行?每次调用 getOutputParameterValue() 时都会执行该过程吗?对于这种行为有任何官方文档吗?
我是他所在领域的新手,和你一样对这个问题感到好奇。不过我借此机会对其进行了测试,以下是我的观察结果,
According to the documentation execute() returns:
> Return true if the first result corresponds to a result set,
> and false if it is an update count or if there are no results
> other than through IN OUT and OUT parameters, if any.
Run Code Online (Sandbox Code Playgroud)
因此我想说,返回的 true 或 false 并不意味着执行成功或失败。
同样,我们必须在调用之前注册参数getOutputParameterValue
。如果我们研究 的实现getOutputParameterValue
,我们将能够准确地找到 hibernate 提供程序(在我的例子中是 JPA)调用实际执行的位置。
除了执行发生了多少次之外,我还通过插入调用过程内的另一个表来检查它的方式进行了测试。
create table test_procedure_call(msg varchar2(100));
CREATE OR REPLACE PROCEDURE test (
p_in_1 IN NUMBER,
p_out_1 OUT VARCHAR2,
p_out_2 OUT VARCHAR2
) AS
BEGIN
insert into test_procedure_call values ('Executed..');
commit;
select 'FirstName'||' '||'LastName','HR' into p_out_1,p_out_2
from dual
where p_in_1=1;
END;
/
@Test
public void testStoredProcedureQuery() {
StoredProcedureQuery sp = em.createStoredProcedureQuery("test");
// set parameters
sp.registerStoredProcedureParameter("p_in_1", Integer.class, ParameterMode.IN);
sp.registerStoredProcedureParameter("p_out_1", String.class, ParameterMode.OUT);
sp.registerStoredProcedureParameter("p_out_2", String.class, ParameterMode.OUT);
sp.setParameter("p_in_1", 1);
String name = sp.getOutputParameterValue("p_out_1").toString();
String dept = sp.getOutputParameterValue("p_out_2").toString();
System.out.println("Name : " + name);
System.out.println("Department : " + dept);
}
select * from test_procedure_call;
MSG
----------------------------------------------------------------------------------------
Executed..
Run Code Online (Sandbox Code Playgroud)
通过表 test_procedure_call,我们可以确认它每次测试只执行一次。(正如我们在上面的例子中看到的)。