首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySql将游标取为变量返回null

MySql将游标取为变量返回null
EN

Stack Overflow用户
提问于 2016-02-04 14:40:42
回答 3查看 3.4K关注 0票数 2

问题是,FETCH (在循环中)没有将值放入变量中。我看过MYSQL | SP | CURSOR - Fetch cursor into variable return null,但是表已经填充了。

事务表如下所示:

代码语言:javascript
复制
CREATE TABLE `transactionentry` (
    `transactionid` bigint(20) NOT NULL AUTO_INCREMENT,
    ...
    PRIMARY KEY (`transactionid`),
    ...
) ENGINE=InnoDB AUTO_INCREMENT=651 DEFAULT CHARSET=utf8;

存储过程:

代码语言:javascript
复制
PROCEDURE `doTxnHouseKeeping`()
BEGIN
    -- Loop invariant
    DECLARE noEntries INTEGER DEFAULT FALSE;
    -- Error codes
    DECLARE code CHAR(5) DEFAULT '00000';
    DECLARE msg TEXT;
    -- Txn vars
    DECLARE transactionId BIGINT(20);
    DECLARE lastTransactionId BIGINT(20) DEFAULT 0;
    -- testing
    DECLARE counter INT(11) DEFAULT 0;

    DEClARE txnEntryCur CURSOR FOR 
        SELECT 
            `transactionid`
        FROM 
            `transactionentry`
        LIMIT 1;

    DECLARE CONTINUE HANDLER FOR 
        NOT FOUND SET noEntries = TRUE;  

    DECLARE EXIT HANDLER FOR
        SQLEXCEPTION
            BEGIN
                GET DIAGNOSTICS CONDITION 1
                code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
                SELECT CONCAT('Error fetching transaction entries code: ', code, ' message: ', msg);
            END;

    OPEN txnEntryCur;

    mainLoop: LOOP
        FETCH 
            txnEntryCur 
        INTO 
            transactionId;

        IF noEntries THEN 
            LEAVE  mainLoop;
        END  IF;

        IF transactionId IS NOT NULL THEN
            INSERT INTO debugTable (`bigintval`) VALUES (transactionId);
        ELSE
            INSERT INTO debugTable (`strval`) VALUES ('transactionId is NULL');
        END IF;

        SET counter = counter + 1;
    END LOOP mainLoop;

    CLOSE txnEntryCur;

    SELECT CONCAT("Count: ", counter);        
END

运行存储过程将返回以下结果:

代码语言:javascript
复制
+--------------------------+
|CONCAT("Count: ", counter)|
+--------------------------+
|                  Count: 1|
+--------------------------+

调试表中的结果是:

代码语言:javascript
复制
+------------+---------+-----------------------+
|iddebugTable|bigintval|                 strval|
+------------+---------+-----------------------+
|           1|     NULL|"transactionId is NULL"|
+------------+---------+-----------------------+

,这意味着值没有复制到

当运行SQL时(就像在存储过程中一样),它返回:

代码语言:javascript
复制
+-------------+
|transactionid|
+-------------+
|          591|
+-------------+
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-05 06:44:17

我发现了这个问题,这很奇怪。它不会导致任何错误和/或异常,只是不会将任何值放入变量中。解决方案是从以下位置更改游标声明语句:

代码语言:javascript
复制
DECLARE txnEntryCur CURSOR FOR 
    SELECT 
        `transactionid`
    FROM 
        `transactionentry`
    LIMIT 1;

至:

代码语言:javascript
复制
DECLARE txnEntryCur CURSOR FOR 
    SELECT 
        `transactionentry`.`transactionid`
    FROM 
        `transactionentry`
    LIMIT 1;

甚至连文档都没有指出这可能是个问题(https://dev.mysql.com/doc/refman/5.7/en/declare-cursor.html)

如果要从多个表中进行选择,并且因此从未在更复杂的查询中获得此部分,则只完全限定SQL语句的SELECT (和WHERE)部分。

我希望这能为将来的人节省一些时间。

票数 17
EN

Stack Overflow用户

发布于 2018-11-08 11:13:11

你的问题是:

代码语言:javascript
复制
DECLARE transactionId BIGINT(20);

您声明一个名为transactionId的变量,因此当您这样做时:

代码语言:javascript
复制
DEClARE txnEntryCur CURSOR FOR 
    SELECT 
        `transactionid`
    FROM 
        `transactionentry`
    LIMIT 1;

您的游标的选择是选择您声明的变量,这就是为什么完全限定字段工作的原因。但是,如果不想完全限定select中的字段,则可以重命名变量。

票数 2
EN

Stack Overflow用户

发布于 2016-02-04 19:27:58

尝试给变量transactionId一个默认值

代码语言:javascript
复制
...
DECLARE transactionId BIGINT(20) DEFAULT 0
...

也取代了

代码语言:javascript
复制
DECLARE noEntries INTEGER DEFAULT FALSE;

使用

代码语言:javascript
复制
DECLARE noEntries BOOLEAN DEFAULT FALSE;

因为您希望将它用作BOOLEAN值,并在后面的过程中将其设置为TRUE

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35203943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档