PostgreSQL 存储过程不工作
PostgreSQL stored procedure not working
我在 Postgres DBMS 中创建了一个存储过程和一个调用该过程的 Java 函数。
在 运行 Java 函数之后我收到一个错误:
org.postgresql.util.PSQLException: L'indice de la colonne est hors limite : 1, nombre de colonnes : 0.
at org.postgresql.core.v3.SimpleParameterList.registerOutParameter(SimpleParameterList.java:49)
at org.postgresql.jdbc2.AbstractJdbc2Statement.registerOutParameter(AbstractJdbc2Statement.java:1968)
at org.postgresql.jdbc3.AbstractJdbc3Statement.registerOutParameter(AbstractJdbc3Statement.java:1511)
at DAO.FournisseurDAO.getLastId(FournisseurDAO.java:192)
at CONTROLLER.FournisseurController.getLastIdInDataBase(FournisseurController.java:96)
at VIEW.FournisseurUi.spinnerProperties(FournisseurUi.java:183)
at VIEW.FournisseurUi.componentsProperties(FournisseurUi.java:139)
at VIEW.FournisseurUi.<init>(FournisseurUi.java:100)
at VIEW.FournisseurUi.run(FournisseurUi.java:542)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:697)
at java.awt.EventQueue.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
程序代码如下:
CREATE OR REPLACE FUNCTION getlastfournisseurid(OUT lastid integer)
RETURNS integer AS
$BODY$
begin
select last_value into lastid from fournisseur_fournisseurid_seq ;
end;
$BODY$
LANGUAGE plpgsql;
功能代码如下:
public int getLastId() {
String fournisseurLastId = "{ call getLastFournisseurId() }";
int lastid = -1 ;
// Get Connection
Connection connecte = utility.DatabaseConnection.getInstance();
try {
// Create a callableStatement
CallableStatement clblStmt = connecte.prepareCall(fournisseurLastId);
// Process query
clblStmt.registerOutParameter(1, java.sql.Types.INTEGER);
ResultSet result = clblStmt.executeQuery();
result.next();
lastid = clblStmt.getInt(1);
// close used resources
clblStmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
return -1 ;
} finally {
try {
if (connecte != null) {
connecte.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return lastid;
}
}
您应该与该函数的参数进行通信(实际上,它的 return 值),但您将调用定义为:
String fournisseurLastId = "{ call getLastFournisseurId() }";
您应该将其定义为:
String fournisseurLastId = "{ ? = call getLastFournisseurId() }";
否则,JDBC 无法将第一个占位符注册为输出参数 - 那里没有可注册的占位符。
Postgres 函数就是:函数。无需使用 JDBC 的 CallableStatement
,它是为 real 存储过程设计的。
你的函数还可以简化。不需要 PL/pgSQL 函数。一个简单的 SQL 函数就可以做到:
CREATE OR REPLACE FUNCTION getlastfournisseurid()
RETURNS integer AS
$BODY$
select lastvalue from fournisseur_fournisseurid_seq;
$BODY$
LANGUAGE sql;
(假设table中永远不会超过一行fournisseur_fournisseurid_seq
,如果有,则需要在select中添加一个limit 1
声明)
然后这样称呼它:
Statement stmt = connecte.createStatement();
ResultSet rs = stmt.executeQuery("select getlastfournisseurid()");
rs.next();
lastid = rs.getInt(1);
我在 Postgres DBMS 中创建了一个存储过程和一个调用该过程的 Java 函数。
在 运行 Java 函数之后我收到一个错误:
org.postgresql.util.PSQLException: L'indice de la colonne est hors limite : 1, nombre de colonnes : 0.
at org.postgresql.core.v3.SimpleParameterList.registerOutParameter(SimpleParameterList.java:49)
at org.postgresql.jdbc2.AbstractJdbc2Statement.registerOutParameter(AbstractJdbc2Statement.java:1968)
at org.postgresql.jdbc3.AbstractJdbc3Statement.registerOutParameter(AbstractJdbc3Statement.java:1511)
at DAO.FournisseurDAO.getLastId(FournisseurDAO.java:192)
at CONTROLLER.FournisseurController.getLastIdInDataBase(FournisseurController.java:96)
at VIEW.FournisseurUi.spinnerProperties(FournisseurUi.java:183)
at VIEW.FournisseurUi.componentsProperties(FournisseurUi.java:139)
at VIEW.FournisseurUi.<init>(FournisseurUi.java:100)
at VIEW.FournisseurUi.run(FournisseurUi.java:542)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:697)
at java.awt.EventQueue.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
程序代码如下:
CREATE OR REPLACE FUNCTION getlastfournisseurid(OUT lastid integer)
RETURNS integer AS
$BODY$
begin
select last_value into lastid from fournisseur_fournisseurid_seq ;
end;
$BODY$
LANGUAGE plpgsql;
功能代码如下:
public int getLastId() {
String fournisseurLastId = "{ call getLastFournisseurId() }";
int lastid = -1 ;
// Get Connection
Connection connecte = utility.DatabaseConnection.getInstance();
try {
// Create a callableStatement
CallableStatement clblStmt = connecte.prepareCall(fournisseurLastId);
// Process query
clblStmt.registerOutParameter(1, java.sql.Types.INTEGER);
ResultSet result = clblStmt.executeQuery();
result.next();
lastid = clblStmt.getInt(1);
// close used resources
clblStmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
return -1 ;
} finally {
try {
if (connecte != null) {
connecte.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return lastid;
}
}
您应该与该函数的参数进行通信(实际上,它的 return 值),但您将调用定义为:
String fournisseurLastId = "{ call getLastFournisseurId() }";
您应该将其定义为:
String fournisseurLastId = "{ ? = call getLastFournisseurId() }";
否则,JDBC 无法将第一个占位符注册为输出参数 - 那里没有可注册的占位符。
Postgres 函数就是:函数。无需使用 JDBC 的 CallableStatement
,它是为 real 存储过程设计的。
你的函数还可以简化。不需要 PL/pgSQL 函数。一个简单的 SQL 函数就可以做到:
CREATE OR REPLACE FUNCTION getlastfournisseurid()
RETURNS integer AS
$BODY$
select lastvalue from fournisseur_fournisseurid_seq;
$BODY$
LANGUAGE sql;
(假设table中永远不会超过一行fournisseur_fournisseurid_seq
,如果有,则需要在select中添加一个limit 1
声明)
然后这样称呼它:
Statement stmt = connecte.createStatement();
ResultSet rs = stmt.executeQuery("select getlastfournisseurid()");
rs.next();
lastid = rs.getInt(1);