【问题标题】:Unable to call stored procedure in oracle through JDBCoracle无法通过JDBC调用存储过程
【发布时间】:2014-02-26 19:35:35
【问题描述】:

我正在尝试调用一个存储过程,我将 7 个值插入到一个表中。但是下面的代码不起作用,请告诉我我做错了什么?

我没有收到任何错误,页面只是保持静态,尽管在成功执行查询后假设重定向到新页面。

   public class admincontrol extends TagSupport
 {

HttpServletRequest request;
HttpServletResponse response;
String msg="";

public int doStartTag() throws JspException
 {
       request=(HttpServletRequest)pageContext.getRequest();
       response=(HttpServletResponse)pageContext.getResponse();
       return EVAL_PAGE;
    }
     public void check ()
     {
       JspWriter out=pageContext.getOut(); 
        Connection con;
       CallableStatement stmt;
       ResultSet rs;
    try
   {
       try
        {
          Class.forName("oracle.jdbc.driver.OracleDriver");
         }
          catch(ClassNotFoundException ex)
       {
          out.println(ex.getMessage());
        }


          HttpSession mysession=request.getSession();
          String sess=(String)mysession.getAttribute("user");

       String  rr=(String)adminmodel.time.trim();
       String tempid=(String)adminmodel.employeid.trim();
       String tdept=(String)adminmodel.department.trim();
       String tsup=(String)adminmodel.supervisor.trim();
       String tact=(String)adminmodel.action.trim();
       String tdate=(String)adminmodel.date.trim();


       HttpSession session1=request.getSession();
       session1.setAttribute("requestnum",rr);

     Random rand = new Random(); 
     int r= rand.nextInt(80001) + 19999;
     String reff = String.valueOf(r); 

    if (!tempid.matches(".*[%#^<>&;'\0-].*") && !tdept.matches(".*

     [%#^<>&;'\0-].*") && !tsup.matches(".*[%#^<>&;'\0-].*"))
  {

   if (tempid.equals(sess) )
  {
  if (adminmodel.department!="" && adminmodel.supervisor!="" && adminmodel.action!="" && adminmodel.date!="" && adminmodel.time!="")
  {
     try
  {
con= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","gaurav","oracle");
 stmt=con.prepareCall("begin requestdetail (?,?,?,?,?,?,?); end;");
    stmt.setString(1,tempid);
    stmt.setString(2,tsup);
    stmt.setString(3,tdept);  
    stmt.setString(4,tact);  
    stmt.setString(5,tdate);  
    stmt.setString(6,rr);
    stmt.setString(7,reff);           
    rs=stmt.executeQuery();
   response.sendRedirect("requestnum.jsp");    
  }
   catch(SQLException ex)
  {
    out.println(ex.getMessage());
  }
   catch(Exception ex)
   {
    out.println(ex.getMessage());
   }
 }
    else 
    out.println("Enter complete details"); 
  }
    else 
    out.println("Incorrect Employee Id"); 
  }
    else
    out.println("Invalid Details "); 
 }

   catch(Exception ex)
 {

  } 
 }

  public int doEndTag() throws JspException
{

  check();
  return super.doEndTag();
 }

}

下面是存储过程

create or replace procedure requestdetail (id number, sup varchar2, department       varchar2,aaction varchar2, adate number,atime number, ref number)
is
begin
insert into myadmin(employe_id,supervisor,department,action,sdate,stime,reference_no)values (id,sup,department,aaction,adate,atime, ref);
end;
/

【问题讨论】:

  • 'Not working' 不是有效或有用的错误消息。请始终说出您遇到的错误或意外行为,以及您期望发生的情况。我假设您从调用本身中得到诸如“错误的参数数量或类型”或“无效的标识符”之类的信息。您的程序也可能无效;第一列真的叫employe_id,而不是employee_id?如果它“编译时出现警告”,则执行 show errorsselect * from user_errors 以查看问题所在。
  • 我已经更新了整个代码,请看一下。我没有收到任何错误,页面只是保持静态,尝试使用 stmt=con.prepareCall("{ call requestdetail (?,?,?,?,?,?,?) }");和 stmt=con.prepareCall("begin; requestdetail (?,?,?,?,?,?,?); end;");没有任何作用
  • msg 会发生什么?如果您没有得到您期望的重定向,那么您似乎可能在某个地方遇到了异常。 tempid 是否真的匹配 sess - 听起来他们在管理页面上会有所不同,但不确定这是在做什么。这似乎是一个 JSP 调试问题,尽管您现在的 DB 调用是错误的......
  • 这就是问题所在,既没有执行查询,也没有出现任何异常。我确保在提交之前满足所有条件但仍然没有运气。
  • 你怎么知道你没有遇到异常 - check 是如何调用的,你如何处理返回的 msg 值;它是否在某处显示或记录?你在做哪些调试来查看方法内部发生了什么?

标签: jdbc oracle10g


【解决方案1】:

您不能在查询中使用过程,只能使用函数。要执行您需要执行的程序:

stmt=con.prepareCall("{ call requestdetail (?,?,?,?,?,?,?) }");
stmt.setString(1,tempid);
stmt.setString(2,tsup);
stmt.setString(3,tdept);  
stmt.setString(4,tact);  
stmt.setString(5,tdate);  
stmt.setString(6,rr);
stmt.setString(7,reff);           
rs=stmt.execute();

如果您愿意,也可以传递一个 PL/SQL 块:

stmt=con.prepareCall("begin; requestdetail (?,?,?,?,?,?,?); end;");

您还需要在某些时候commit,除非您为连接打开了自动提交。

此外,您正在使用setString 设置所有参数,并且您在评论中说该表是使用所有varchar2 列创建的;但是您的程序需要 idadateatime 列的数字:

create or replace procedure requestdetail (id number, sup varchar2,
  department varchar2, aaction varchar2, adate number, atime number,
  ref number) is

如果您为tempidtdaterr 传递的值实际上不是数字,那将得到numeric or value error。看起来您希望 tempid 至少是一个字符串。

但如果它们是数字(或顾名思义,日期)值,那么您的表格列无论如何都应该是适当的类型,而不是所有varchar2。始终使用正确的数据类型;不要尝试将数字或日期存储为字符串,这只会让您以后感到痛苦。它会影响性能,因为 Oracle 无法根据实际数据类型优化执行计划和索引。但更重要的是,因为您可能会获得无效或只是错误的数据,而这些数据您可能会在很久以后才注意到,并且很难纠正。

如果有人在您的“数字”字段中插入一个字符串,没有什么可以阻止他们;但是在某些时候,当您使用where adate = 1 进行查询时,它会抛出一个错误。与日期相同,但更糟糕的是取决于使用的格式 - 即使使用单一格式,如果您认为一切都是 DD/MM/YYYY 并且有人错误地将值输入为 MM/DD/YYYY,那么您又赢了不知道;并且在检索时它会起作用(如果 DD 和 MM 都 DATE,则由插入的人来做正确的事,而不是由您在检索数据时尝试修复错误。

【讨论】:

  • 谢谢.. 你能告诉我为什么不将数字作为字符串存储在数据库中是错误的吗?
  • @user3337264 - 更新了一些背景。 See this as well.
猜你喜欢
  • 2015-04-20
  • 1970-01-01
  • 2011-03-13
  • 2015-05-28
  • 2016-04-05
  • 2020-12-12
  • 2011-12-05
  • 2012-09-05
  • 2016-05-03
相关资源
最近更新 更多