【问题标题】:PLS-00103: Encountered the symbol ")"PLS-00103:遇到符号“)”
【发布时间】:2018-01-23 16:24:32
【问题描述】:

我正在创建一个需要连接到数据库并获取各种类型报告的类别的网络应用程序。在通过 java 中的存储过程执行我的 SQL 时,我遇到了一个奇怪的错误。 SELECT * FROM RPT_CTGR; 是我提交的 sql,但是当我查看堆栈跟踪时,它会返回如下:

 org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call SELECT * FROM RPT_CTGR;(?)}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 38:
PLS-00103: Encountered the symbol ")" when expecting one of the following:

   . ( * @ % & = - + < / > at in is mod remainder not rem
   <an exponent (**)> <> or != or ~= >= <= <> and or like like2
   like4 likec as between || indicator multiset member
   submultiset

    org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:969)
    org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1003)
    org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144)
    org.ifmc.qies.reportaudit.impl.CataImpl.search(CataImpl.java:59)
    org.ifmc.qies.reportaudit.web.CataAction.execute(CataAction.java:31)
    org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
    org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
    org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
    org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

由于某种原因,将额外的“(?)”附加到导致错误的语句末尾。有什么想法吗?

代码

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.ifmc.qies.reportaudit.dao.CataDao;
import org.ifmc.qies.reportaudit.model.Catagory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import oracle.jdbc.OracleTypes;

public class CataImpl extends JdbcDaoSupport implements CataDao {
    protected static ApplicationContext ctx = null;
//BaseStoredProcedure extends StoredProcedure
    public class CataProc extends BaseStoredProcedure{

        public CataProc(DataSource ds, String name) {
            super(ds,name);
            System.out.println(name);
            System.out.println(getSql());
            declareParameter(new SqlOutParameter("catagories", OracleTypes.CURSOR,
                    new RowMapper() {
                        public Object mapRow(ResultSet rs, int rowNum)
                                throws SQLException {

                            Catagory t = new Catagory();
                            t.setCatId(rs.getString(1));
                            t.setCat_name(rs.getString(2));
                            System.out.println(t.getCat_name());
                            return t;
                        }
                    }));
        }


    }
@Override
    public List search() {
    String[] paths = {"V:path/to/applicationcontext.xml"};
    Map params=new HashMap();
    ctx = new FileSystemXmlApplicationContext(paths);
    DataSource ds = (DriverManagerDataSource)ctx.getBean("dataSource");
        CataProc proc = new CataProc(ds,"SELECT * FROM RPT_CTGR;");
        Map results = proc.execute(params);
        List catagory = (List)results.get("catagories");
        //Test
        System.out.println(catagory.get(1).toString());
        return catagory;
    }



}

除了catagories.get(1).toString 之外,我的所有print 语句都能正确返回我提交的SQL

【问题讨论】:

  • 请发布完整的堆栈跟踪
  • 什么是declareParameter?听起来像是在语句末尾添加(?)。另外,分号是多余的吗? IIRC 曾经要求您省略分号,但已经很长时间了,所以我不确定。
  • declareParameter 按照它说的做。声明分类将是保存 sql 输出的参数,在本例中为分类对象。但我确实把它拿出来了,因为它似乎没有必要,但同样的问题只是发生了,而不是(?)它只是()。我取出了 sqlout 参数,但这并没有改变任何东西。此外,就在这个网站docs.spring.io/spring/docs/current/spring-framework-reference/… 上,它确实说我必须为每个新的 sqlparameter 提供声明参数。
  • 您似乎正在发送调用存储过程的请求,而您正在发送选择语句。您正在发送 SELECT * FROM RPT_CTGR; 作为存储过程的 name

标签: java sql spring oracle web-applications


【解决方案1】:

您应该在 Oracle 数据库中创建一个 Store Procedure 来执行您的 SELECT 语句。 您可以参考this question 来了解如何操作。

例如

CREATE OR REPLACE PROCEDURE getCatagories(categories in out sys_refcursor) is
  ...
  SELECT * FROM RPT_CTGR;
  ...

之后,您需要按名称调用存储过程。

public List search() {
  ...
  DataSource ds = (DriverManagerDataSource) ctx.getBean("dataSource");
  CataProc proc = new CataProc(ds,"getCatagories");
  Map results = proc.execute(params);
  List catagory = (List)results.get("catagories");
  ... 
}

【讨论】:

    猜你喜欢
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多