无法对 PLSQL 语句执行提取
Cannot perform fetch on a PLSQL statement
这是我的table
CREATE TABLE accounts (
accountid VARCHAR(255),
name VARCHAR2(255),
phone_number INTEGER,
email_addresses VARCHAR2(255),
account_number VARCHAR(255),
password VARCHAR2(255)
);
现在我创建了一个程序
create or replace PROCEDURE getaccount (
param1 IN VARCHAR2
) AS
BEGIN
DBMS_OUTPUT.PUT_LINE(' SELECT
accountid,
password
FROM
accounts
WHERE
account_number = '||param1) ;
END getaccount;
以及为什么我们使用 ||或运算符
second i 运行 SQLDEVELOPER 中的这段代码
我把这个弄出来
call getaccount('123456');
Call completed.
收到此消息
现在我正在连接 JAVA
这是我的代码 JAVA
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?)}");
pst.setString(1, Number);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
System.out.println(rs.getString(1));
这里 Get.connection return 连接 .
在我 运行 之后我得到这个错误
Enter Account Number : 123456
java.sql.SQLException: Cannot perform fetch on a PLSQL statement: next
at ojdbc10/oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:409)
at bank.services.SignValidator.getBank(SignValidator.java:20)
at bank.services.KingobankMain.getBank(KingobankMain.java:49)
at bank.services.KingobankMain.main(KingobankMain.java:14)
我不知道 Java,但是:您编写的过程会导致屏幕上显示输出,但前提是您用来调用该过程的工具支持它 - 例如SQL*另外,SQL 开发人员、TOAD 等。剩下的,根本不会有结果。
看起来你想要运行
select accountid, password from accoutns where account_number = 123456
在 Java。然后,您应该使用 function 而不是过程。它应该 return 一个 VARCHAR2
(那个 select
语句)然后你会在 Java 中执行它。如何?说不出来;正如我所说,我不知道 Java。在 Oracle 中,您将使用动态 SQL.
或者,如果它必须是一个过程,那么它应该有一个 OUT
参数,以便它 return 向调用者发送 select
语句。但是,调用者必须有“东西”(一个变量?)来接受那个输出。
根据您的要求,带有 OUT
参数的程序:
CREATE OR REPLACE PROCEDURE getaccount (param1 IN VARCHAR2,
par_query OUT VARCHAR2)
AS
BEGIN
par_query :=
'SELECT accountid, password FROM accounts WHERE '
|| ' account_number = '
|| DBMS_ASSERT.enquote_literal (param1);
END getaccount;
注释dbms_assert
,用于防止SQL注入。
为了在 Oracle 中 运行 它,您必须使用一个 PL/SQL 块和一个接受该过程 return 编辑的结果的变量。
SQL> set serveroutput on
SQL>
SQL> create or replace procedure getaccount (param1 in varchar2,
2 par_query out varchar2)
3 as
4 begin
5 par_query :=
6 'SELECT accountid, password FROM accounts WHERE '
7 || ' account_number = '
8 || dbms_assert.enquote_literal (param1);
9 end getaccount;
10 /
Procedure created.
SQL> declare
2 l_out varchar2(200);
3 begin
4 getaccount('12345', l_out);
5 dbms_output.put_line('Result is: ' || l_out);
6 end;
7 /
Result is: SELECT accountid, password FROM accounts WHERE account_number = '12345'
PL/SQL procedure successfully completed.
SQL>
显然,您不想 return 表示为字符串的命令,而是 select
语句产生的结果。正如所评论的,考虑 returning 一个 refcursor。此外,使用函数而不是过程;它们旨在“return”一个值。如果它是一个过程,则必须创建 OUT 参数并将它们的值接受到 something(可能是局部变量)。
假设这是table的内容:
SQL> select * From accounts;
ACCOUNTID PASSWORD ACCOUNT_NUMBER
---------- ---------- --------------------
1 my_pwd 12345
SQL>
returns refcursor 的函数:
SQL> create or replace function getaccount (param1 in varchar2)
2 return sys_refcursor
3 is
4 l_rc sys_refcursor;
5 begin
6 open l_rc for
7 'SELECT accountid, password FROM accounts WHERE '
8 || ' account_number = '
9 || dbms_assert.enquote_literal (param1);
10 return l_rc;
11 end getaccount;
12 /
Function created.
SQL> select getaccount('12345') from dual;
GETACCOUNT('12345')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ACCOUNTID PASSWO
---------- ------
1 my_pwd
SQL>
或者,具有 2 个 OUT 参数的过程:
SQL> create or replace procedure getaccount
2 (param1 in varchar2,
3 p_accid out varchar2,
4 p_pwd out varchar2) is
5 begin
6 select accountid, password
7 into p_accid, p_pwd
8 from accounts
9 where account_number = param1;
10 end;
11 /
Procedure created.
SQL> set serveroutput on
SQL> declare
2 l_id varchar2(20);
3 l_pwd varchar2(20);
4 begin
5 getaccount('12345', l_id, l_pwd);
6 dbms_output.put_line('ID = ' || l_id ||', PWD = ' || l_pwd);
7 end;
8 /
ID = 1, PWD = my_pwd
PL/SQL procedure successfully completed.
SQL>
您的程序没有 return 值(输出变量),您正在尝试获取数据。
这会导致错误。
存储过程输出参数:
reate or replace procedure getaccount (
p_account_number in varchar2,
p_account_id out varchar2,
p_password out varchar2
) as
begin
select
accountid,
password
into
p_account_id,
p_password
from
accounts
where
account_number = p_account_number ;
end getaccount;
/
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?,?,?)}");
pst.setString(1, "....");//set account number
pst.registerOutParameter(2, OracleTypes.VARCHAR);
pst.registerOutParameter(3, OracleTypes.VARCHAR);
pst.execute();
//read the OUT parameter now
System.out.println("AccountID="+pst.getString(2)+",password="+pst.getString(3));
..........your of code....
存储过程 Oracle SYS_REFCURSOR:
create or replace procedure getaccount (
p_account_number in varchar2,
p_cur out sys_refcursor
) as
begin
open p_cur for
select
accountid,
password
from
accounts
where
account_number = p_account_number ;
end getaccount;
/
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?,?)}");
pst.setString(1, ".....");// set account number
pst.registerOutParameter(2, OracleTypes.CURSOR);
pst.execute();
//read the OUT parameter now
rs = (ResultSet) pst.getObject(2);
while(rs.next()){
System.out.println("AccountID="+rs.getString("accountid")+",password="+rs.getString("password"));
..........your of code....
}
添加链接:
这是我的table
CREATE TABLE accounts (
accountid VARCHAR(255),
name VARCHAR2(255),
phone_number INTEGER,
email_addresses VARCHAR2(255),
account_number VARCHAR(255),
password VARCHAR2(255)
);
现在我创建了一个程序
create or replace PROCEDURE getaccount (
param1 IN VARCHAR2
) AS
BEGIN
DBMS_OUTPUT.PUT_LINE(' SELECT
accountid,
password
FROM
accounts
WHERE
account_number = '||param1) ;
END getaccount;
以及为什么我们使用 ||或运算符
second i 运行 SQLDEVELOPER 中的这段代码 我把这个弄出来
call getaccount('123456');
Call completed.
收到此消息
现在我正在连接 JAVA 这是我的代码 JAVA
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?)}");
pst.setString(1, Number);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
System.out.println(rs.getString(1));
这里 Get.connection return 连接 .
在我 运行 之后我得到这个错误
Enter Account Number : 123456
java.sql.SQLException: Cannot perform fetch on a PLSQL statement: next
at ojdbc10/oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:409)
at bank.services.SignValidator.getBank(SignValidator.java:20)
at bank.services.KingobankMain.getBank(KingobankMain.java:49)
at bank.services.KingobankMain.main(KingobankMain.java:14)
我不知道 Java,但是:您编写的过程会导致屏幕上显示输出,但前提是您用来调用该过程的工具支持它 - 例如SQL*另外,SQL 开发人员、TOAD 等。剩下的,根本不会有结果。
看起来你想要运行
select accountid, password from accoutns where account_number = 123456
在 Java。然后,您应该使用 function 而不是过程。它应该 return 一个 VARCHAR2
(那个 select
语句)然后你会在 Java 中执行它。如何?说不出来;正如我所说,我不知道 Java。在 Oracle 中,您将使用动态 SQL.
或者,如果它必须是一个过程,那么它应该有一个 OUT
参数,以便它 return 向调用者发送 select
语句。但是,调用者必须有“东西”(一个变量?)来接受那个输出。
根据您的要求,带有 OUT
参数的程序:
CREATE OR REPLACE PROCEDURE getaccount (param1 IN VARCHAR2,
par_query OUT VARCHAR2)
AS
BEGIN
par_query :=
'SELECT accountid, password FROM accounts WHERE '
|| ' account_number = '
|| DBMS_ASSERT.enquote_literal (param1);
END getaccount;
注释dbms_assert
,用于防止SQL注入。
为了在 Oracle 中 运行 它,您必须使用一个 PL/SQL 块和一个接受该过程 return 编辑的结果的变量。
SQL> set serveroutput on
SQL>
SQL> create or replace procedure getaccount (param1 in varchar2,
2 par_query out varchar2)
3 as
4 begin
5 par_query :=
6 'SELECT accountid, password FROM accounts WHERE '
7 || ' account_number = '
8 || dbms_assert.enquote_literal (param1);
9 end getaccount;
10 /
Procedure created.
SQL> declare
2 l_out varchar2(200);
3 begin
4 getaccount('12345', l_out);
5 dbms_output.put_line('Result is: ' || l_out);
6 end;
7 /
Result is: SELECT accountid, password FROM accounts WHERE account_number = '12345'
PL/SQL procedure successfully completed.
SQL>
显然,您不想 return 表示为字符串的命令,而是 select
语句产生的结果。正如所评论的,考虑 returning 一个 refcursor。此外,使用函数而不是过程;它们旨在“return”一个值。如果它是一个过程,则必须创建 OUT 参数并将它们的值接受到 something(可能是局部变量)。
假设这是table的内容:
SQL> select * From accounts;
ACCOUNTID PASSWORD ACCOUNT_NUMBER
---------- ---------- --------------------
1 my_pwd 12345
SQL>
returns refcursor 的函数:
SQL> create or replace function getaccount (param1 in varchar2)
2 return sys_refcursor
3 is
4 l_rc sys_refcursor;
5 begin
6 open l_rc for
7 'SELECT accountid, password FROM accounts WHERE '
8 || ' account_number = '
9 || dbms_assert.enquote_literal (param1);
10 return l_rc;
11 end getaccount;
12 /
Function created.
SQL> select getaccount('12345') from dual;
GETACCOUNT('12345')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
ACCOUNTID PASSWO
---------- ------
1 my_pwd
SQL>
或者,具有 2 个 OUT 参数的过程:
SQL> create or replace procedure getaccount
2 (param1 in varchar2,
3 p_accid out varchar2,
4 p_pwd out varchar2) is
5 begin
6 select accountid, password
7 into p_accid, p_pwd
8 from accounts
9 where account_number = param1;
10 end;
11 /
Procedure created.
SQL> set serveroutput on
SQL> declare
2 l_id varchar2(20);
3 l_pwd varchar2(20);
4 begin
5 getaccount('12345', l_id, l_pwd);
6 dbms_output.put_line('ID = ' || l_id ||', PWD = ' || l_pwd);
7 end;
8 /
ID = 1, PWD = my_pwd
PL/SQL procedure successfully completed.
SQL>
您的程序没有 return 值(输出变量),您正在尝试获取数据。 这会导致错误。
存储过程输出参数:
reate or replace procedure getaccount (
p_account_number in varchar2,
p_account_id out varchar2,
p_password out varchar2
) as
begin
select
accountid,
password
into
p_account_id,
p_password
from
accounts
where
account_number = p_account_number ;
end getaccount;
/
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?,?,?)}");
pst.setString(1, "....");//set account number
pst.registerOutParameter(2, OracleTypes.VARCHAR);
pst.registerOutParameter(3, OracleTypes.VARCHAR);
pst.execute();
//read the OUT parameter now
System.out.println("AccountID="+pst.getString(2)+",password="+pst.getString(3));
..........your of code....
存储过程 Oracle SYS_REFCURSOR:
create or replace procedure getaccount (
p_account_number in varchar2,
p_cur out sys_refcursor
) as
begin
open p_cur for
select
accountid,
password
from
accounts
where
account_number = p_account_number ;
end getaccount;
/
CallableStatement pst = Get.connection().prepareCall("{call getAccount(?,?)}");
pst.setString(1, ".....");// set account number
pst.registerOutParameter(2, OracleTypes.CURSOR);
pst.execute();
//read the OUT parameter now
rs = (ResultSet) pst.getObject(2);
while(rs.next()){
System.out.println("AccountID="+rs.getString("accountid")+",password="+rs.getString("password"));
..........your of code....
}
添加链接: