web-dev-qa-db-ja.com

「エラー1329:データがありません-ゼロ行がフェッチ、選択、または処理されました」を取り除く方法

値を返す必要のないストアドプロシージャがあります。問題なくスムーズに動作します。ただし、実行が終了するとエラーメッセージが出力されます。

エラー:データなし-ゼロ行がフェッチ、選択、または処理されました

このエラーメッセージを削除するにはどうすればよいですか?

CREATE PROCEDURE `testing_proc`()  
    READS SQL DATA  
BEGIN  
    DECLARE done INT DEFAULT 0;
    DECLARE l_name VARCHAR(20);
    DECLARE my_cur CURSOR FOR
        SELECT name FROM customer_tbl;
    OPEN my_cur;
        my_cur_loop:
        LOOP FETCH my_cur INTO l_name;
            IF done = 1 THEN
                LEAVE my_cur_loop;
            END IF;
            INSERT INTO names_tbl VALUES(l_name);
        END LOOP my_cur_loop;
    CLOSE my_cur;
END
30
Babibo

投稿に次の行を含めるのを忘れただけだと思います。

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

コードは正しいですが、mysqlのバグ/奇妙な動作により、処理された場合でも警告が表示されます。テーブルを呼び出して成功するプロシージャの最後に「ダミー」ステートメントを追加すると、警告がクリアされることを回避できます。 ( http://dev.mysql.com/doc/refman/5.5/en/show-warnings.html を参照)=あなたの場合:

SELECT name INTO l_name FROM customer_tbl LIMIT 1;

ループの終了後。 MySQL 5.5.13では、LinuxおよびWindowsで警告が消えます。 MySQL Bug 60840についてコメントしましたが、将来修正されることを願っています...

39
RobertG

次のような継続ハンドラを定義する必要があります。

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

したがって、次のようになります。

DECLARE done INT DEFAULT 0;
DECLARE l_name VARCHAR(20);
DECLARE my_cur CURSOR FOR
    SELECT name FROM customer_tbl;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN my_cur;
    my_cur_loop:
    LOOP FETCH my_cur INTO l_name;
        IF done = 1 THEN
            LEAVE my_cur_loop;
        END IF;
        INSERT INTO names_tbl VALUES(l_name);
    END LOOP my_cur_loop;
CLOSE my_cur;
27
robm

私はこれに遭遇し、 official mysql docs

MySQL 5.6.3より前では、警告またはエラーを生成するステートメントが条件ハンドラーを呼び出す場合、ハンドラーは診断領域をクリアしない場合があります。これにより、ハンドラーが呼び出されなかったように見える場合があります。次の議論は問題を示し、回避策を提供します。

リンクをクリックして詳細を下にスクロールしますが、修正はCONTINUE HANDLER内の成功した選択を含めることでした:

  DECLARE CONTINUE HANDLER FOR NOT FOUND
    BEGIN
       SELECT 1 INTO @handler_invoked FROM (SELECT 1) AS t;
    END;
8
DanJGer

私はここで解決策を試みましたが、継続ハンドラを含めてどれも私のために働いていませんでした。 MySQLエラーログにまだメッセージが表示されます。 「select ... into ...」でこれを発見しましたが、これは理にかなっていますが、カーソルに対してcontinueハンドラが機能すると本当に思っていました。いずれにせよ、「found_rows()」を使用して、返された行があるかどうかを調べることができました。これは、単純な「select into」ステートメントをカーソルに変換する必要があることを意味しますが、あまり機能せず、問題を解決します。

DECLARE v_rowcount      integer unsigned;
DECLARE cur_entries cursor for
        select app_name, proc_name, error_code, sum(occurrences) occurrences
        from that_table...; 
open cur_entries; 
set v_rowcount = found_rows();
if v_rowcount > 0 then
  fetch cur_entries into v_app_name, v_proc_name, v_error_code, v_occurrences;
  ...
end if;
close cur_entries;

私はここに私の個人的なブログにこれを書きました: http://tinky2jed.wordpress.com/technical-stuff/mysql/mysql-no-data-zero-rows-fetched-how-to-code-for- it /

3
Jed

これでカーソルの問題が解決するかどうかはわかりませんが、ストアド関数でこの警告に遭遇し、以下を使用すると次のことがわかりました:

RETURN (SELECT x From myTable...);

の代わりに

SELECT x into myVar...return myVar

この役立つドキュメントからこれを入手しました: http://bugs.mysql.com/bug.php?id=42834

1
user977109

通常、これはカーソル範囲をオーバーシュートしたときに発生するため、FETCHステートメントがあるループ条件をチェックアウトします

1
Francisco Lemos