问题描述
这是我的桌子
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;
以及我们为什么使用 ||或运算符
第二次我在 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 返回 Connection .
我运行后出现这个错误
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*Plus、SQL Developer、TOAD 等。剩下的,根本就没有结果。
看起来你想跑
select accountid,password from accoutns where account_number = 123456
在Java中。然后您应该使用函数而不是过程。它应该返回一个 VARCHAR2
(那个 select
语句),然后你会在 Java 中执行它。如何?说不清;正如我所说,我不会Java。在 Oracle 中,您将使用动态 SQL。
或者,如果它必须是一个过程,那么它应该有一个 OUT
参数,以便它将 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 块以及一个接受该过程返回的结果的变量。
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>
显然,您不想返回表示为字符串的命令,而是该 select
语句生成的结果。正如评论的那样,考虑返回一个refcursor。此外,使用函数而不是过程;它们旨在“返回”一个值。如果它是一个过程,则必须创建 OUT 参数并将它们的值接受为 something(可能是局部变量)。
假设这是表格的内容:
SQL> select * From accounts;
ACCOUNTID PASSWORD ACCOUNT_NUMBER
---------- ---------- --------------------
1 my_pwd 12345
SQL>
返回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>
,
您的过程没有返回值(输出变量)并且您正在尝试获取数据。 这会导致错误。
存储过程输出参数:
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(?,".....");// 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....
}
添加链接: