2011-11-29 112 views
3

我想调用一个执行更新(语言sql,返回void)的PL/pgSQL函数。我得到这个异常:JPA和PostgreSQL:如何调用带有void返回类型的存储过程?

Internal Exception: org.postgresql.util.PSQLException: A result was returned when none was expected.

的persistence.xml:

<named-native-query name="Clinic.deactivateByNotFoundInIncomingClinic"> 
    <query> 
     <![CDATA[ 
      select apply_incoming_clinic_deletions(?) 
     ]]> 
    </query> 
</named-native-query> 

DAO:

public void deactivateByNotFoundInIncomingClinic(long clinicSystemId) 
{ 
    em.createNamedQuery("Clinic.deactivateByNotFoundInIncomingClinic") 
      .setParameter(1, clinicSystemId) 
      .executeUpdate(); 
} 

帮助!

更新:

使用EclipeseLink在GlassFish 3.1.1通过PostgreSQL的9.0-801 JDBC驱动程序4交谈的PostgreSQL数据库9.0。

+0

如果你可以直接运行SQL语句(psql或pgAdminII我),您可以将问题与数据库或中间代码隔离。其他要检查的内容:函数的返回值是否与声明的返回类型相匹配?尽管出现错误消息,是否执行更新? JPA和PostgreSQL是最新的吗?您是否尝试增加日志级别或调试级别以获取更多信息? –

+0

@Catcall请再次阅读该问题。该函数没有返回类型。 SQL语句('select apply_incoming_clinic_deletions(1)')运行得很好。 –

+0

该函数具有返回类型;它的类型是'void'。在函数返回(或试图返回)非声明类型的东西时,早期版本的PostgreSQL中有相同的错误消息。 –

回答

1

的DAO代码更改为这工作:

public void deactivateByNotFoundInIncomingClinic(long clinicSystemId) 
{ 
    em.createNamedQuery("Clinic.deactivateByNotFoundInIncomingClinic") 
      .setParameter(1, clinicSystemId) 
      .getSingleResult(); 
} 
2

不知道这是从哪里来的。问题中缺少你的函数定义。
但是,您可以尝试plpgsql函数而不是sql。声明为RETURNS void时,它们的返回类型略有不同。考虑这个演示:

CREATE OR REPLACE FUNCTION f_sql() 
    RETURNS void AS 
'UPDATE foo SET id = id+1 WHERE id = 34567' 
    LANGUAGE sql; 

CREATE OR REPLACE FUNCTION f_plpgsql() 
    RETURNS void AS 
$$ 
BEGIN 
UPDATE foo SET id = id+1 WHERE id = 34567; 
END; 
$$ LANGUAGE plpgsql; 

现在,VOID是虚构类型。虽然plpgsql函数实际返回VOID,但SQL函数似乎返回NULL。我不确定这是为什么。

db=# SELECT f_sql() IS NULL; 
?column? 
---------- 
t 

db=# SELECT f_plpgsql() IS NULL; 
?column? 
---------- 
f 
+0

不知道这是OP的问题的根源,而是注意到收益差异的+1。 –

+0

@Catcall:我自己很困惑。我实际上发布了一个[有关更多详细信息的问题](http://stackoverflow.com/q/8319986/939860)。 –

+0

是的,在JPA之外执行是有区别的,但是从JPA内部获得了相同的结果(GlassFish 3.1.1上的EclipeseLink使用PostgreSQL 9.0-801 JDBC 4驱动程序与PostgreSQL 9.0数据库对话)。但是,当我将'executeUpdate()'改成'getSingleResult()'时,它使用语言plpgsql。到那时,我已经改变了函数的主体,以至于我无法恢复到'language sql'来查看是否有一部分可以在这里使用。我将很快用另一个函数进行测试。 –

1

程序

DROP FUNCTION updatename(bigint); 
CREATE OR REPLACE FUNCTION updatename(var_id bigint) 
RETURNS void AS $$ 
DECLARE 


BEGIN 
    update person set 
     name ='lucas' 
    where id=var_id; 

RETURN; 

END;$$ 
LANGUAGE 'plpgsql'; 

//调用程序

Long id=50; 
Query query = emProvider.get().createNativeQuery("SELECT updatename(?1)") ; 
     query.setParameter(1,id); 
     query.executeUpdate();