我在使用 CallableStatement 调用 Postgres 存储函数的 Java 应用程序中出现错误。错误如下:
org.postgresql.util.PSQLException: Malformed function or procedure escape syntax at offset 6.
at org.postgresql.jdbc2.AbstractJdbc2Statement.modifyJdbcCall(AbstractJdbc2Statement.java:2390)
at org.postgresql.jdbc2.AbstractJdbc2Statement.<init>(AbstractJdbc2Statement.java:149)
at org.postgresql.jdbc3.AbstractJdbc3Statement.<init>(AbstractJdbc3Statement.java:40)
at org.postgresql.jdbc3g.AbstractJdbc3gStatement.<init>(AbstractJdbc3gStatement.java:26)
at org.postgresql.jdbc3g.Jdbc3gStatement.<init>(Jdbc3gStatement.java:28)
at org.postgresql.jdbc3g.Jdbc3gPreparedStatement.<init>(Jdbc3gPreparedStatement.java:21)
at org.postgresql.jdbc3g.Jdbc3gCallableStatement.<init>(Jdbc3gCallableStatement.java:17)
at org.postgresql.jdbc3g.Jdbc3gConnection.prepareCall(Jdbc3gConnection.java:45)
at org.postgresql.jdbc3.AbstractJdbc3Connection.prepareCall(AbstractJdbc3Connection.java:316)
at org.postgresql.jdbc2.AbstractJdbc2Connection.prepareCall(AbstractJdbc2Connection.java:203)
at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareCall(NewProxyConnection.java:632)
at zm.co.freight.model.user.UserRoleModel.getUserRoleDocumentPermission(UserRoleModel.java:212)
需要注意的是,我使用的是 Postgres 9.2、posgresql-9.1-902.jdbc3.jar 和一个 c3p0-0.9.2-pre4.jar 连接池。
这是我要调用的存储函数:
CREATE OR REPLACE FUNCTION user_role_document_permission_select_all_per_user_role(userroleidin integer)
RETURNS refcursor AS
$BODY$
declare
mycurs refcursor;
begin
open mycurs for
select document._name,
document_user_role_permission.viewing,
document_user_role_permission.processing,
document_user_role_permission.editing,
document_user_role_permission.updating,
document_user_role_permission.user_role_id,
document_user_role_permission.document_id
from document_user_role_permission, document where document_user_role_permission.document_id = document.id and document_user_role_permission.user_role_id = userroleidin;
return mycurs;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
进行调用的 Java 方法:
public ArrayList<UserRoleDocumentPermissionDao> getUserRoleDocumentPermission (int userRoleId){
ArrayList<UserRoleDocumentPermissionDao> result = new ArrayList<UserRoleDocumentPermissionDao>();
try{
cstmt = myConnection.prepareCall("{ ? = \"user_role_document_permission_select_all_per_user_role\"(?)}");
cstmt.registerOutParameter(1, Types.OTHER);
cstmt.setInt(2, userRoleId);
cstmt.execute();
rs = (ResultSet) cstmt.getObject(1);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
UserRoleDocumentPermissionDao udao;
while (rs.next()){
udao = new UserRoleDocumentPermissionDao();
for (int i = 1; i <= columnCount; i++){
if (i == 1){ // document name
udao.setDocumentName(rs.getString(i));
} else if (i == 2){ // view
udao.setViewing(rs.getBoolean(i));
} else if (i == 3){ // process
udao.setProcessing(rs.getBoolean(i));
} else if (i == 4){ // edit
udao.setEditing(rs.getBoolean(i));
} else if (i == 5){ // update
udao.setUpdating(rs.getBoolean(i));
} else if (i == 6){ // userRoleId
udao.setUserRoleId(rs.getInt(i));
} else if (i == 7){ // documentId
udao.setDocumentId(rs.getLong(i));
}
}
result.add(udao);
}
} catch (SQLException e){
System.out.println("SQL Exception: ");
e.printStackTrace();
} finally {
closeConnection();
}
return result;
}
超类中的一些全局变量
protected Connection myConnection;
protected Statement stmt;
protected CallableStatement cstmt;
protected ResultSet rs;
道:
public class UserRoleDocumentPermissionDao {
private String documentName;
private boolean viewing;
private boolean processing;
private boolean editing;
private boolean updating;
private int userRoleId;
private Long documentId;
public UserRoleDocumentPermissionDao(){}
public UserRoleDocumentPermissionDao(String docName, boolean view,
boolean process, boolean edit, boolean update, int userRoleIdin, Long docId){
this.documentName = docName;
this.viewing = view;
this.processing = process;
this.editing = edit;
this.updating = update;
this.userRoleId = userRoleIdin;
this.documentId = docId;
}
/////// getters and setters
我不知道为什么会这样。我已经能够成功地从一个返回 refcursor 的 Postgres 存储函数中获得结果,而且我似乎无法弄清楚该函数/函数调用与这个函数/函数调用之间的任何区别。
任何想法将不胜感激