Spring JDBC - 糟糕的SQL语法

时间:2012-08-01 04:53:00

标签: spring jdbc

我正在通过Spring教程,我在JDBC部分遇到了问题。代码是直接从教程本身复制的,并且几次对数据库的调用在失败之前正确运行。谁能帮我?这是我的错误跟踪。

Jul 31, 2012 9:40:03 PM org.springframework.jdbc.core.metadata.GenericCallMetaDataProvider processProcedureColumns
WARNING: Error while retrieving metadata for procedure columns: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
Jul 31, 2012 9:40:03 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
Jul 31, 2012 9:40:03 PM org.springframework.jdbc.support.SQLErrorCodesFactory <init>
INFO: SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]    Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call getrecord()}]; nested exception is com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
        at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:969)
        at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1003)
        at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:391)
        at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:354)
        at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:181)
        at com.tutorialspoint.StudentJDBCTemplate.getStudent(StudentJDBCTemplate.java:32)
        at com.tutorialspoint.MainApp.main(MainApp.java:29)
    Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:3206)
        at com.mysql.jdbc.Statement.executeQuery(Statement.java:1232)
        at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMetaData.java:1607)
        at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData.java:4034)
        at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStatement.java:709)
        at com.mysql.jdbc.CallableStatement.<init>(CallableStatement.java:513)
        at com.mysql.jdbc.Connection.parseCallableStatement(Connection.java:4583)
        at com.mysql.jdbc.Connection.prepareCall(Connection.java:4657)
        at com.mysql.jdbc.Connection.prepareCall(Connection.java:4631)
        at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:167)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:947)
        ... 6 more

以下是我的主要应用程序中出现问题的部分,并且我已经标记了相关的行。

    System.out.println("----Listing Record with ID = 2 -----");
        // Error occurs in next line
    Student student = studentJDBCTemplate.getStudent(2);
    System.out.print("ID : " + student.getId());
    System.out.print(", Name : " + student.getName());
    System.out.println(", Age : " + student.getAge());

StudentJDBCTemplate有这两个变量。

private DataSource dataSource;
private SimpleJdbcCall jdbcCall;

StudentJDCBTemplate像这样设置数据源,这可能是问题的根源,因为我无法弄清楚getRecord所指的是什么。

public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
    this.jdbcCall = new SimpleJdbcCall(dataSource)
            .withProcedureName("getRecord");
}

这个StudentJDBCTemplate方法出现问题。

public Student getStudent(Integer id) {
    SqlParameterSource in = new MapSqlParameterSource().addValue("in_id",
            id);
    Map<String, Object> out = jdbcCall.execute(in);
    Student student = new Student();
    student.setId(id);
    student.setName((String) out.get("out_name"));
    student.setAge((Integer) out.get("out_age"));
    return student;
}

这是我的Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <!-- Initialization for data source -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/TEST" />
        <property name="username" value="root" />
        <property name="password" value="password" />
    </bean> <!-- Definition for studentJDBCTemplate bean -->
    <bean id="studentJDBCTemplate" class="com.tutorialspoint.StudentJDBCTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

这是值得的,这是我的学生班。

package com.tutorialspoint;

public class Student {
    private Integer age;
    private String name;
    private Integer id;

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }
}

4 个答案:

答案 0 :(得分:1)

关注tutorial后,您错过了getRecord存储过程的创建:

DELIMITER $$

DROP PROCEDURE IF EXISTS `TEST`.`getRecord` $$
CREATE PROCEDURE `TEST`.`getRecord` (
IN in_id INTEGER,
OUT out_name VARCHAR(20),
OUT out_age  INTEGER)
BEGIN
   SELECT name, age
   INTO out_name, out_age
   FROM Student where id = in_id;
END $$

DELIMITER ;

答案 1 :(得分:0)

您正在尝试执行存储过程“getrecord”。哪个在数据库中不存在或未正确编译。尝试首先通过SQL Client在数据库端执行。

过程应与签名匹配为2 out参数和一个输入参数。

答案 2 :(得分:0)

Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist..所以检查一次..创建getrecord函数并尝试一次..

答案 3 :(得分:0)

如果有人在2017年遇到这个问题,如果您使用MySQL Connector版本6.x而不是5.x

,则需要更改旧教程

在Beans.xml中,这一行应该是:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
    <h2>Dropdowns</h2>
    <p>The .dropdown class is used to indicate a dropdown menu.</p>
    <p>Use the .dropdown-menu class to actually build the dropdown menu.</p>
    <p>To open the dropdown menu, use a button or a link with a class of .dropdown-toggle and data-toggle="dropdown".</p>
    <div class="dropdown">
        <!--<button class="my-btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example-->
            <button class="my-btn my-btn-primary my-dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
            <span class="caret"></span></button>
        <ul class="dropdown-menu">
            <li><a href="#">HTML</a></li>
            <li><a href="#">CSS</a></li>
            <li><a href="#">JavaScript</a></li>
        </ul>
    </div>
</div>

</body>
</html>

代替:  <property name="url" value="jdbc:mysql://localhost:3306/test?nullNamePatternMatchesAll=true" />

SQL错误非常具有误导性,声称&#34; out_name&#34;参数未定义。

这是由于MySQL Connector从版本5.x更改为6.x,注释为here 原来的答案是here