2016-11-29 162 views
0

我正在創建一個包,然後創建一個存儲過程。封裝和程序如下:無效標識符的修復錯誤

create or replace package test_system is 
    type ref_cursor is ref cursor; 
procedure demo_show_students(p_gpa IN STUDENTS.gpa%TYPE,p_ref_cursor OUT ref_cursor); 
end test_system; 
/

create or replace package body test_system is 
procedure demo_show_students(p_gpa IN STUDENTS.gpa%TYPE,p_ref_cursor OUT ref_cursor) 
is 
v_sql_str varchar2(4000); 
begin 
v_sql_str:='select sid,firstname,lastname,status,gpa,email from students where gpa = p_gpa'; 
open p_ref_cursor for v_sql_str; 
end demo_show_students; 
end test_system; 

以下是兩個鏈接的Java代碼,即PL/SQL代碼,但它給了我一個問題:

import java.sql.*; 

import oracle.jdbc.OracleTypes; 

public class ShowStudents { 

public void showStudents() { 

    try { 

     // Connection to Oracle server 
     OracleDataSource ds = new oracle.jdbc.pool.OracleDataSource(); 
     ds.setURL("jdbc:oracle:thin:@localhost:1521:xe"); 
     Connection conn = ds.getConnection("*****", "*****"); 

     String val = '4'+""; 
     CallableStatement cs = conn.prepareCall("{call   
     test_system.demo_show_students(?,?)}"); 
     cs.setString(1, val); 

     cs.registerOutParameter(2, OracleTypes.CURSOR); 
     cs.execute(); 
     ResultSet rs = (ResultSet)cs.getObject(2); 

     while (rs.next()) { 
      System.out.println(rs.getString(1) + "\t" + 
       rs.getString(2) + "\t" + rs.getString(3) + 
       rs.getString(4) + 
       "\t" + rs.getDouble(5) + "\t" + 
       rs.getString(6)); 
     } 


     cs.close(); 

    } catch (SQLException ex) { 
     System.out.println("\n*** SQLException caught ***\n"); 
     ex.printStackTrace(); 
    } catch (Exception e) { 
     System.out.println("\n*** other Exception caught ***\n"); 
    } 
} 
} 



Exception : 

*** SQLException caught *** 
ORA-00904: "P_GPA": invalid identifier 
ORA-06512: at "PROJECT2.TEST_SYSTEM", line 7 
ORA-06512: at line 1 

誰能告訴如何修復這個錯誤。

回答

1

oracle無法識別變量p_gpa。你可以這樣做在兩個方面:

1)把一個佔位符

v_sql_str:='select sid,firstname,lastname,status,gpa,email from students where gpa = :p_gpa'; 

    open p_ref_cursor for v_sql_str using p_gpa; 

2)直接在寫作中查詢:

open p_ref_cursor for 
select sid,firstname,lastname,status,gpa,email 
from students where gpa = p_gpa; 
+1

@Akshay兩個星的解決方案是正確的,但首選的解決方案是靜態的sql版本(第二種解決方案),因爲a)沒有必要使用動態sql和b)動態sql只能在運行時解析,而不是編譯時。這意味着如果你的sql語句有錯誤,在你真的開始運行之前你不會知道它。另外,如果該對象被刪除,程序包將不會失效,並且它也不會在user_dependencies等中顯示出來。如果可以的話,堅持使用靜態SQL,如果您真的需要,只能回退到動態SQL。 – Boneist