2013-10-12 95 views
2

我正在創建一個使用自定義標籤的登錄頁面,在下面的代碼中,我想執行一個存儲的oracle函數,其中該函數將使用2個參數(名稱,密碼)進行身份驗證並返回一個數字。但是,當我編譯下面的代碼,它給出了一個錯誤說(發現:int)不兼容的類型。請告訴我我哪裏錯了?我是否正確調用該函數?下面如何從jdbc調用存儲函數?

package pack.java; 
    import pack.java.MyModel; 
    import java.io.*; 
    import java.lang.*; 
    import javax.servlet.*; 
    import javax.servlet.http.*; 
    import javax.servlet.jsp.*; 
    import javax.servlet.jsp.tagext.*; 
    import java.sql.*; 
    public class MyController extends TagSupport 
    { 

HttpServletRequest request; 
HttpServletResponse response; 

public int doStartTag()throws JspException 
{ 

    request=(HttpServletRequest)pageContext.getRequest();    
    response=(HttpServletResponse)pageContext.getResponse(); 
    return EVAL_PAGE; 
    } 

    public void check() 
    { 

    HttpSession mysession=request.getSession(); 
    Connection con; 
    CallableStatement stmt; 
    JspWriter out=pageContext.getOut(); 
     try 
    { 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
    } 
    catch(ClassNotFoundException ex) 
    { 
    } 
    try 
    {   
     String aa=(String)MyModel.name.trim(); 
    String bb=(String)MyModel.pass.trim(); 
     con= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","gaurav","oracle"); 
    stmt=con.prepareCall("select usercheck1(?,?) from dual"); 
    stmt.setString(1,aa); 
    stmt.setString(2,bb);  
    rs=stmt.executeQuery(); 

    try 
    { 
    while (rs.next()) 
    { 
    String empid=rs.getString (1); 
    mysession.setAttribute("user",empid); 
    if(empid!=null) 
    { 

    response.sendRedirect("/Myjsp/selectaction.jsp"); 
    } 
     else 
    out.println("InValid User"); 
    } 

    catch(Exception ex) 
    { 

    } 

    } 
    catch(SQLException ex) 
     { 
     } 
    } 
     public int doEndTag() throws JspException 
    { 

     check(); 
     return EVAL_PAGE; 
     } 

    } 

是存儲功能

create or replace function usercheck1 
(uname varchar2, upass varchar2) 
return number 
as 
numb number; 
begin 
select (employe_id) into numb from record where name=uname and password=upass; 
return numb; 
end usercheck1; 
/

使用下面的語句

select usercheck1 ('ghg','aa')from dual; 
+0

錯誤報告在哪一行上? – Stephan

+0

它說不兼容的類型 found:int, required:java.sql.ResultSet, on line rs = stmt.executeUpdate(); – Gaurav

+2

在不久的將來,請到[代碼評論](http://codereview.stackexchange.com)進行評論。 –

回答

0

executeUpdate()回報int,見here更多細節執行的功能。我相信你期待之下線ResultSet

變化,

rs=stmt.executeUpdate(); 

rs=stmt.executeQuery();

更多信息,請參見executeQuery

+0

感謝它的工作..雖然我高清使用查詢stmt = con.prepareCall(「選擇usercheck1(?,?)從雙」); – Gaurav

3

首先你說proc返回一個數字,但你的代碼期望結果集返回一個字符串? 無論如何,假設你的proc返回一個int。 這些線路

stmt=con.prepareCall("call usercheck1(?,?)"); 

    stmt.setString(1,aa); 
stmt.setString(2,bb);  
    rs=stmt.executeUpdate(); 

更改爲

stmt=con.prepareCall ("{? = call usercheck1(?, ?)}"); 

    stmt.registerOutParameter (1, Types.INTEGER); 
    stmt.setString(2,aa);  
    stmt.setString(3,bb); 
    stmt.execute(); 
    int output =stmt.getInt (1); 

如果你實際上是在期待一個字符串從PROC結果,然後更改 到

stmt=con.prepareCall ("{? = call usercheck1(?, ?)}"); 

    stmt.registerOutParameter (1, Types.VARCHAR2); 
    stmt.setString(2,aa);  
    stmt.setString(3,bb); 
    stmt.execute(); 
    String output =stmt.getString (1); 

結果集使用遊標,並要求你指定你的輸出參數。 希望有所幫助。

http://docs.oracle.com/cd/A84870_01/doc/java.816/a81354/samapp2.htm

如果您使用的是Oracle的新版本> = 9i中,你可能會想使用開始結束語法。

+0

感謝您的輸入,但是當我嘗試執行代碼通過更改您建議的代碼不起作用,登錄失敗,因爲我認爲函數沒有得到執行。我正在更新我創建的功能,請檢查可能出現的問題 – Gaurav

+0

除非您告訴我發生了什麼以及您現在正在做什麼,否則我不能告訴您發生了什麼問題。也許你應該重新發布你的新代碼... – Sumit

+0

另外,嘗試將你的可調用SQL代碼改爲「begin?:= usercheck1(?,?); end;」這是新的Oracle 9i語法。 – Sumit

3

要執行一個函數,規範的方法是使用CallableStatement。這是PreparedStatement的特例(小類)。

此外,您必須使用registerOutParameter方法之一指定右側輸出參數類型。一旦呼叫完成(execute),您將從語句本身提取輸出值。不通過ResultSet

所有這一切都導致類似:

CallableStatement stmt = con.prepareCall("{? = call usercheck1(?, ?)}"); 
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
# Prepare a `call` 

stmt.registerOutParameter(1, Types.INTEGER); 
# Setup out parameter type ^^^^^^^^^^^^^ 

stmt.setString(2,aa);  
stmt.setString(3,bb); 
stmt.execute(); 
# ^^^^^^^ 
# execute the statement 

int output = stmt.getInt(1); 
#   ^^^^^^^^^^^ 
# Extract the result from the statement itself 

做的完全不同的方式,是實際使用SELECT查詢調用的函數。這是OP在這個問題上提出的建議。這樣一來,你可以使用一個ResultSet照常提取值:

PreparedStatement stmt = con.prepareStatement("SELECT usercheck1(?, ?) FROM DUAL"); 
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
# Prepare a statement 

stmt.setString(2,aa);  
stmt.setString(3,bb); 
ResultSet rs = stmt.executeQuery(); 
#     ^^^^^^^^^^^^ 
# execute the query 

while(rs.next()) { 
    int output = rs.getInt(1); 
    #   ^^^^^^^^^ 
    # Extract the result from the `ResultSet` 

    # ... 
    # do whatever you want with the data 

} 
0

其他建議通過select語句運行查詢,但如果函數的任何DML這會拋出異常。使用CallableStatement是最佳選擇。

相關問題