带有多个 PREPARE 语句的 Mysql 过程问题

Posted

技术标签:

【中文标题】带有多个 PREPARE 语句的 Mysql 过程问题【英文标题】:Mysql procedure issue with multiple PREPARE statement 【发布时间】:2017-02-06 07:29:31 【问题描述】:

以下是我在 java 代码中调用的 mysql 存储过程。 我正在动态检查表名和限制值。它在 mysql 命令行中运行。

问题是当我在 java 中调用此过程并尝试从结果集中读取时,它给出了无效列异常。

       `CREATE DEFINER=`root`@`localhost` PROCEDURE `top_gainers`(
            IN sExchange VARCHAR (24),
            IN iLimit INT,
            OUT sStatus VARCHAR(10),
            OUT sMessage VARCHAR(40)
        )
        BEGIN

    SET sStatus = '0';

    IF sExchange = '' OR iLimit = ''
    THEN
        SET sStatus = '1';
        SET sMessage = 'Parameter is missing';
    END IF;

    SET @table_test = CONCAT('SHOW TABLES LIKE \'', sExchange,'\'');
    PREPARE stmnt FROM @table_test;
    EXECUTE stmnt;
    DEALLOCATE PREPARE stmnt;
    IF FOUND_ROWS() = 0
    THEN
        SET sStatus = '2';
        SET sMessage = 'Invalid exchange selected';
    END IF;

    IF sStatus = '0'
    THEN
        SET @text = CONCAT('SELECT * FROM ', sExchange, ' ORDER BY CHANGE_PER DESC LIMIT ', iLimit);
        PREPARE stmnt FROM @text;
        EXECUTE stmnt;
        DEALLOCATE PREPARE stmnt;
        IF FOUND_ROWS() = 0
        THEN
            SET sStatus = '3';
            SET sMessage = 'Could not find relevant data';
        ELSE
            SET sMessage = 'Market movers fetched successfully';
        END IF;
    END IF;

END`

这里是java代码(我的表有SYMBOL和DESCRIPTION列):

conn = DBConnection.getInstance().getConnection();    
String sQuery = "CALL top_gainers(?, ?, ?, ?)";
cstmt = conn.prepareCall(sQuery);
cstmt.setString(1, sExchange); // "NSE"
cstmt.setString(2, sLimit); // "10"
cstmt.registerOutParameter(3, java.sql.Types.VARCHAR);
cstmt.registerOutParameter(4, java.sql.Types.VARCHAR);    
boolean hasResult = cstmt.execute();    
JSONArray jArray = new JSONArray();    
while (hasResult)     
    ResultSet res = cstmt.getResultSet();    
    sStatus = cstmt.getString("sStatus");
    sMessage = cstmt.getString("sMessage");    
    if (sStatus.equals("0"))     
        while (res.next()) 
            JSONObject jObj = new JSONObject();    
            jObj.put("symbol", res.getString("SYMBOL"));
            jObj.put("description", res.getString("DESCRIPTION"));    
            jArray.put(jObj);
        
        
    DBConnection.closeResultSet(res);    
    hasResult = cstmt.getMoreResults();

异常“未找到列 'SYMBOL'。”

这是我的桌子:

+--------------------+---------------+------+-----+---------------------+-------+
| Field              | Type          | Null | Key | Default             | Extra |
+--------------------+---------------+------+-----+---------------------+-------+
| SYMBOL             | varchar(255)  | NO   | PRI |                     |       |
| DESCRIPTION        | varchar(255)  | YES  |     | NULL                |       |
--------------------------------------------------------------------------------+

【问题讨论】:

您介意提供发生的确切异常吗? 请始终包含确切的异常消息 这是我得到的“未找到列 'SYMBOL'。” 【参考方案1】:

发现问题。我的过程返回了 2 个结果集,我试图访问只有表名的第一个集顶部的列 'SYMBOL'(以防有效的表名)

我在 java 代码中添加了以下几行,并在访问值之前检查了列数。

ResultSetMetaData rsmd = res.getMetaData();
int columnsNumber = rsmd.getColumnCount();

while (hasResult) 结果集 res = cstmt.getResultSet();

ResultSetMetaData rsmd = res.getMetaData();
int columnsNumber = rsmd.getColumnCount();

sStatus = cstmt.getString("sStatus");
sMessage = cstmt.getString("sMessage");

if (columnsNumber > 1) 

    while (res.next()) 

    JSONObject jObj = new JSONObject();
    jObj.put(APP_CONSTANT.SYMBOL, res.getString("SYMBOL"));
    jObj.put(APP_CONSTANT.DESCRIPTION, res.getString("DESCRIPTION"));
    jArray.put(jObj);

    


DBConnection.closeResultSet(res);

hasResult = cstmt.getMoreResults();

【讨论】:

以上是关于带有多个 PREPARE 语句的 Mysql 过程问题的主要内容,如果未能解决你的问题,请参考以下文章

mysql_stmt_prepare的说明

MySQL数据库存储过程动态表建立(PREPARE)

MySQL prepare 原理

MySQL-PREPARE语句

mysql prepare疑问

mysql prepare语句使用