2016-11-29 408 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