从 java、table 到 return 的 Postgres 存储过程调用
Postgres stored procedure call from java, table to return
我做了一个Postgres存储过程:
CREATE OR REPLACE FUNCTION GetUser(ipUserId integer)
RETURNS setof users AS $$
BEGIN
IF ipUserId is null THEN
return query select * from users A order by modifieddate desc;
END IF;
return query select * from users where iduser = ipUserId;
END;
$$ LANGUAGE plpgsql;
我试过在 java 中这样使用它:
StoredProcedureQuery query = entityManager.createStoredProcedureQuery("GetUser").
registerStoredProcedureParameter("ipUserId",
Integer.class, ParameterMode.IN)
.registerStoredProcedureParameter("users",
List.class, ParameterMode.OUT)
.setParameter("postId", 1);
或
StoredProcedureQuery query = entityManager.createStoredProcedureQuery("GetUser")
.registerStoredProcedureParameter(1,void.class, ParameterMode.REF_CURSOR)
.registerStoredProcedureParameter(2,Integer.class, ParameterMode.IN)
.setParameter(2, ipIdUser);
我想将结果存储在列表中。
我应该怎么办,因为我遇到了各种错误?
更新:
这些是错误:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults
Caused by: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.result.internal.OutputsImpl.convert(OutputsImpl.java:79)
at org.hibernate.result.internal.OutputsImpl.<init>(OutputsImpl.java:56)
at org.hibernate.procedure.internal.ProcedureOutputsImpl.<init>(ProcedureOutputsImpl.java:34)
at org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs(ProcedureCallImpl.java:453)
at org.hibernate.procedure.internal.ProcedureCallImpl.getOutputs(ProcedureCallImpl.java:404)
at org.hibernate.procedure.internal.ProcedureCallImpl.outputs(ProcedureCallImpl.java:663)
at org.hibernate.procedure.internal.ProcedureCallImpl.getResultList(ProcedureCallImpl.java:751)
... 21 more
Caused by: org.postgresql.util.PSQLException: A CallableStatement was executed with an invalid number of parameters
您可以尝试使用 CallableStatement。
假设您的连接变量正常:
CallableStatement stmt = con.prepareCall("{call SCHEMA.PROCEDURE_NAME (?, ?)}");
stmt.setInt(1, custom_var);
stmt.registerOutParameter(2, OracleTypes.INTEGER);
stmt.execute();
得到结果:stmt.getInt(3); stmt.getString(4)
如果你不能成功尝试使用 JdbcTemplate:
SimpleJdbcCall call = new SimpleJdbcCall(this.jdbcTemplate).withSchemaName(SCHEMA).withProcedureName(PROC);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("ipUserId", custom_var);
Map out = call.execute(params);
要获得单个结果:Integer.parseInt("" + out.get("OUT_PARAM_NAME")); (String) out.get("OUT_PARAM_NAME2"));
或者您可以将所有结果保存在一个列表中以便稍后处理:
SimpleJdbcCall call = new SimpleJdbcCall(this.jdbcTemplate);
List<Map<String, Object>> rows = call.getJdbcTemplate().queryForList(PROC_STRING, new Object[] { param1, param2 });
我找到了一个非常简单的解决方案,只需创建一个 SQL 查询以使用休眠调用该过程。
String SqlString = "select * from GetUser({0})";
if (ipIdUser == null )
SqlString = MessageFormat.format(SqlString, "NULL");
else
SqlString = MessageFormat.format(SqlString, ipIdUser);
LOGGER.info("SqlSting =" + SqlString);
return entityManager.createNativeQuery(SqlString, User.class)
.getResultList();
为什么不在 StoredProcedureQuery
上使用 getResultList
?这避免了必须进行字符串操作。
List<User> users = entityManager.createStoredProcedureQuery("GetUser")
.registerStoredProcedureParameter("ipUserId", Integer.class, ParameterMode.IN)
.setParameter("ipUserId", ipIdUser)
.getResultList();
我做了一个Postgres存储过程:
CREATE OR REPLACE FUNCTION GetUser(ipUserId integer)
RETURNS setof users AS $$
BEGIN
IF ipUserId is null THEN
return query select * from users A order by modifieddate desc;
END IF;
return query select * from users where iduser = ipUserId;
END;
$$ LANGUAGE plpgsql;
我试过在 java 中这样使用它:
StoredProcedureQuery query = entityManager.createStoredProcedureQuery("GetUser").
registerStoredProcedureParameter("ipUserId",
Integer.class, ParameterMode.IN)
.registerStoredProcedureParameter("users",
List.class, ParameterMode.OUT)
.setParameter("postId", 1);
或
StoredProcedureQuery query = entityManager.createStoredProcedureQuery("GetUser")
.registerStoredProcedureParameter(1,void.class, ParameterMode.REF_CURSOR)
.registerStoredProcedureParameter(2,Integer.class, ParameterMode.IN)
.setParameter(2, ipIdUser);
我想将结果存储在列表中。
我应该怎么办,因为我遇到了各种错误?
更新:
这些是错误:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults
Caused by: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.result.internal.OutputsImpl.convert(OutputsImpl.java:79)
at org.hibernate.result.internal.OutputsImpl.<init>(OutputsImpl.java:56)
at org.hibernate.procedure.internal.ProcedureOutputsImpl.<init>(ProcedureOutputsImpl.java:34)
at org.hibernate.procedure.internal.ProcedureCallImpl.buildOutputs(ProcedureCallImpl.java:453)
at org.hibernate.procedure.internal.ProcedureCallImpl.getOutputs(ProcedureCallImpl.java:404)
at org.hibernate.procedure.internal.ProcedureCallImpl.outputs(ProcedureCallImpl.java:663)
at org.hibernate.procedure.internal.ProcedureCallImpl.getResultList(ProcedureCallImpl.java:751)
... 21 more
Caused by: org.postgresql.util.PSQLException: A CallableStatement was executed with an invalid number of parameters
您可以尝试使用 CallableStatement。 假设您的连接变量正常:
CallableStatement stmt = con.prepareCall("{call SCHEMA.PROCEDURE_NAME (?, ?)}");
stmt.setInt(1, custom_var);
stmt.registerOutParameter(2, OracleTypes.INTEGER);
stmt.execute();
得到结果:stmt.getInt(3); stmt.getString(4)
如果你不能成功尝试使用 JdbcTemplate:
SimpleJdbcCall call = new SimpleJdbcCall(this.jdbcTemplate).withSchemaName(SCHEMA).withProcedureName(PROC);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("ipUserId", custom_var);
Map out = call.execute(params);
要获得单个结果:Integer.parseInt("" + out.get("OUT_PARAM_NAME")); (String) out.get("OUT_PARAM_NAME2"));
或者您可以将所有结果保存在一个列表中以便稍后处理:
SimpleJdbcCall call = new SimpleJdbcCall(this.jdbcTemplate);
List<Map<String, Object>> rows = call.getJdbcTemplate().queryForList(PROC_STRING, new Object[] { param1, param2 });
我找到了一个非常简单的解决方案,只需创建一个 SQL 查询以使用休眠调用该过程。
String SqlString = "select * from GetUser({0})";
if (ipIdUser == null )
SqlString = MessageFormat.format(SqlString, "NULL");
else
SqlString = MessageFormat.format(SqlString, ipIdUser);
LOGGER.info("SqlSting =" + SqlString);
return entityManager.createNativeQuery(SqlString, User.class)
.getResultList();
为什么不在 StoredProcedureQuery
上使用 getResultList
?这避免了必须进行字符串操作。
List<User> users = entityManager.createStoredProcedureQuery("GetUser")
.registerStoredProcedureParameter("ipUserId", Integer.class, ParameterMode.IN)
.setParameter("ipUserId", ipIdUser)
.getResultList();