2016-02-04 3 views
0

Проблема в том, что FETCH INTO (в цикле) не помещает значение в переменную. Я просмотрел MYSQL | SP | CURSOR - Fetch cursor into variable return null, но таблица уже заполнена.MySql Вывод курсора в переменную return null

Таблица транзакций выглядит следующим образом:

CREATE TABLE `transactionentry` (
    `transactionid` bigint(20) NOT NULL AUTO_INCREMENT, 
    ... 
    PRIMARY KEY (`transactionid`), 
    ... 
) ENGINE=InnoDB AUTO_INCREMENT=651 DEFAULT CHARSET=utf8; 

Хранимая процедура:

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 

Выполнение хранимой процедуры возвращает этот результат:

+--------------------------+ 
|CONCAT("Count: ", counter)| 
+--------------------------+ 
|     Count: 1| 
+--------------------------+ 

Результат в таблице отладки это:

+------------+---------+-----------------------+ 
|iddebugTable|bigintval|     strval| 
+------------+---------+-----------------------+ 
|   1|  NULL|"transactionId is NULL"| 
+------------+---------+-----------------------+ 

Это означает, что значение не было скопировано в

При запуске SQL (как в хранимой процедуре), она возвращает:

+-------------+ 
|transactionid| 
+-------------+ 
|   591| 
+-------------+ 

ответ

1

Я нашел проблему, и это странно. Он не вызывает ошибок и/или исключений, просто не помещает никаких значений в переменные. Решение состоит в том, чтобы изменить заявление курсора объявлять от:

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

To:

DECLARE txnEntryCur CURSOR FOR 
    SELECT 
     `transactionentry`.`transactionid` 
    FROM 
     `transactionentry` 
    LIMIT 1; 

Не даже в документации указано, что это могло бы быть проблемой (https://dev.mysql.com/doc/refman/5.7/en/declare-cursor.html)

Я только полностью уточнят SELECT (и WHERE) части инструкции SQL, если я выбираю из более чем одной таблицы и, таким образом, никогда не выбирал это для более сложных запросов.

Я надеюсь, что это спасет кого-то в будущем.

+1

Я решил проблему, используя вместо 'table.field' вместо имени поля. Благодаря ! –

0

Попробуйте дать переменное transactionId значения по умолчанию

... 
DECLARE transactionId BIGINT(20) DEFAULT 0 
... 

, а также заменить

DECLARE noEntries INTEGER DEFAULT FALSE; 

с

DECLARE noEntries BOOLEAN DEFAULT FALSE; 

, так как вы хотите использовать его в качестве значения BOOLEAN и установить его на TRUE позже в процедуре.

+0

Благодарим за отзыв. Нет, не работает, запись в таблице отладки теперь 0 (не NULL), но не значение того, что возвращает оператор select, т.е. 591. NoEntries был BOOLEAN, но во всех настройках он оказался как INT, даже исправление, которое не помогло. – TungstenX

Смежные вопросы