【问题标题】:MYSQL Query into java jdbc prepared statement, error: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExceptionMYSQL查询成java jdbcprepared statement,报错:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
【发布时间】:2015-09-23 10:31:04
【问题描述】:

我有以下工作的 MYSQL 查询(它对两个表进行枢轴连接):

SET @sql = NULL;
SELECT  
 GROUP_CONCAT(DISTINCT
    CONCAT(
    'MAX(IF(sk.keywords = ''', sk.keywords,''', kr.rank, NULL)) AS ',  CONCAT('`',sk.keywords, '`')
    )
) INTO @sql
 FROM 
     search_keywords sk
    WHERE sk.product_id = 2 AND sk.active = 'Y'; 

SET @sql = CONCAT('SELECT eval_date, ', @sql, '  
                   FROM keyword_ranking AS kr 
                   LEFT JOIN  search_keywords AS sk 
                    ON kr.search_keywords_id = sk.id 
                   GROUP BY eval_date');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

我想将此查询插入到 java 准备好的语句中。如果我只是复制它,我会得到一个错误的 sql 语法错误:

st = connection.prepareStatement(
              "SET @sql = NULL; "
            + "SELECT "
            + "GROUP_CONCAT(DISTINCT "
            + "CONCAT("
            + "'MAX(IF(sk.keywords = ''', sk.keywords,''', kr.rank, NULL)) AS ',  CONCAT('`',sk.keywords, '`')"
            + ") INTO @sql "
            + "FROM search_keywords sk "
            + "WHERE sk.product_id = ? AND sk.active = ?; "
            + "SET @sql = CONCAT('SELECT eval_date, ', @sql, ' "
            + "FROM keyword_ranking AS kr  "
            + "LEFT JOIN  search_keywords AS sk  "
            + "ON kr.search_keywords_id = sk.id  "
            + "GROUP BY eval_date'); "
            + "PREPARE stmt FROM @sql; "
            + "EXECUTE stmt; "
            + "DEALLOCATE PREPARE stmt; "
        );

错误:

错误 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 'SELECT GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(sk.keywords = CONCAT(''', sk.keyword' ) 附近使用正确的语法

【问题讨论】:

  • 只是猜测:Java 可能只允许您在每个查询中执行一条语句。所以在你的情况下,你应该分成多个查询。
  • 谢谢 Sirko,但是当我在第二个查询中使用 @SQL 时,如何在 java 中执行此操作?
  • 您或许可以考虑将您的 SQL 作为存储过程并从 Java 调用此 SP。
  • 请参阅 docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html 以快速了解事务(== 多个连接查询)

标签: mysql jdbc prepared-statement


【解决方案1】:

谢谢@Stan 和@Sirko。我相信你们俩都是对的。我首先尝试了交易,但我也遇到了这个错误,所以要么我处理了错误的交易,要么我仍然不得不以某种方式转义单引号。因为我已经尝试了很多不同的转义变体,所以我想尝试一下存储过程。这行得通!!!

对于其他有兴趣创建存储过程的人,我将在下面粘贴我的代码:

Mysql 中的存储过程:

CREATE DEFINER=`gobiran`@`%` PROCEDURE `getKeywordHistoryByProductId`(IN PRODUCT_ID INT(11))
BEGIN

SET @sql = NULL;

SELECT  
 GROUP_CONCAT(DISTINCT
    CONCAT(
    'MAX(IF(sk.keywords = ''', sk.keywords,''', kr.rank, NULL)) AS ',  CONCAT('`',sk.keywords, '`')
    )
) INTO @sql
 FROM 
     search_keywords sk
    WHERE sk.product_id = PRODUCT_ID AND sk.active = 'Y'; 

SET @sql = CONCAT('SELECT eval_date, ', @sql, '  
                   FROM keyword_ranking AS kr 
                   LEFT JOIN  search_keywords AS sk 
                    ON kr.search_keywords_id = sk.id 
                   GROUP BY eval_date');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

END

调用存储过程:

ResultSet rs = null;
        Connection connection = DataBaseHelper.getConnection();
        CallableStatement stmt = null;
        try {

            stmt = connection.prepareCall("{ call getKeywordHistoryByProductId(?) }");
            stmt.setInt(1, productId);
            rs = stmt.executeQuery();

// Thats it, now work with the Resultset ... 
            ResultSetMetaData md = rs.getMetaData();

            int columns = md.getColumnCount();
            List<Object[]> result = new ArrayList<Object[]>();
            String[] header = new String[columns];
            int index = 0;
            while (rs.next()){
                Object[] entry = new Object[columns];
                for (int i = 0; i < columns; i++) {
                    if(index == 0) {
                        header[i] = md.getColumnName(i+1);
                    }
                    entry[i] = rs.getObject(i+1);
                }
                if(index == 0) {
                    result.add(header);
                }
                result.add(entry);
                index++;                
            }

...只是形式:完成try/catch/finally子句并关闭stmt、connection、rs in finnaly

【讨论】:

    猜你喜欢
    • 2016-10-25
    • 2012-07-20
    • 2013-11-20
    • 2012-04-20
    • 1970-01-01
    • 2017-10-05
    • 2016-07-07
    • 2015-01-22
    • 2018-04-26
    相关资源
    最近更新 更多