从存储过程获取输出参数,而不调用execute()

nsc4cvqm  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(407)

我想通过实体管理器从java程序中调用pl/sql存储过程:

StoredProcedureQuery storedProcedureQuery = entityManager.createStoredProcedureQuery("someProcedure");

现在我的理解是,我必须在这个storedprocedurequiry上调用execute(),以便执行这个过程并能够检索out参数。但是,我可以通过简单地调用

someValue1 = (Integer)storedProcedureQuery.getOutputParameterValue(1);
someValue2 = (Integer)storedProcedureQuery.getOutputParameterValue(2);

这怎么可能?在这个代码段中,存储过程究竟什么时候执行?是否每次调用getoutputparametervalue()时都会执行该过程?这种行为有官方文件吗?

k3bvogb1

k3bvogb11#

我是这个领域的新手,对这个问题和你一样好奇。不过,我借此机会对它进行了测试,下面是我的观察结果,

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.

因此,我想说,返回真或假并不意味着一个成功或不执行。
在调用之前,我们必须再次注册参数 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..

通过这个表外测试过程调用,我们可以确认每个测试只执行一次(正如我们在上面的例子中看到的)。

相关问题