2016-06-28 24 views
1

問題は非常にはっきりしていますが、テーブルフィールド以外の変数名を使用するなど、多くの問題を修正しようとしました。カーソルからフェッチされた値は常にnullを返します。カーソルフェッチに割り当てられる値は、同じデータ型(int(11))です。私がやっているのは、カーソルのselectテーブルから取り出したkey_idの値を@my_key_id int(11)変数に代入することですが、nullのままになります。カーソルのフェッチはNULLを返します

 declare my_key_id int(11); /*variable that will be assigned from the  value in cursor*/ 
     DECLARE done INT DEFAULT FALSE; /*for cursor break*/ 

     DECLARE cr_cursor cursor for select key_id from tmp_valuesss;  /*cursor declaration*/ 
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break  thingy*/ 

     open cr_cursor; 

     read_loop: LOOP 

      IF done THEN 
       LEAVE read_loop; 
      END IF; 

      select @my_key_id; 

      FETCH cr_cursor INTO my_key_id; 
     END LOOP; 

     close cr_cursor; 
+1

ドリューのポストがあなたの質問に答えた場合は、あなたの質問を削除しないで答えを受け入れるべきです。 – JAL

+0

私の間違いは、削除するつもりはありませんでした。 –

+1

@MeinHatストアドプロシージャや関連する問題に問題がある場合は、[Campaigns](http://chat.stackoverflow.com/rooms/95290/campaigns)ルームで私とチャットしてみてくださいでる。 – Drew

答えて

4

あなたはローカル変数とユーザー環境変数(@記号を持つもの)(DECLAREを持つもの)を勘違いしています。

ユーザー変数が設定されていないため、常にnullです。

また、すべてのPREPARE変数をDEALLOCATEしてください。

Fetchは、LOOPの先頭に移動するように移動されました。

drop procedure if exists calculate_thingy; 
delimiter $$ 
CREATE PROCEDURE calculate_thingy 
(
    IN table_name VARCHAR(100) 
) 
BEGIN 
    DECLARE SQL_STATEMENT NVARCHAR(8000); 

    drop table if exists tmp_valuesss; 

    SET @SQL_STATEMENT = CONCAT('CREATE TABLE IF NOT EXISTS tmp_valuesss AS  (SELECT * FROM ', table_name, ')');  
    PREPARE STMT FROM @SQL_STATEMENT; 
    EXECUTE STMT; 
    DEALLOCATE PREPARE STMT; -- Drew added ------------------- 

    alter table tmp_valuesss add the_field float; 

    begin 
     declare my_key_id int(11); /*variable that will be assigned from the  value in cursor*/ 
     DECLARE done INT DEFAULT FALSE; /*for cursor break*/ 

     DECLARE cr_cursor cursor for select key_id from tmp_valuesss;  /*cursor declaration*/ 
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break  thingy*/ 

     open cr_cursor; 

     read_loop: LOOP 
      FETCH cr_cursor INTO my_key_id; 
      IF done THEN 
       LEAVE read_loop; 
      END IF; 
      select my_key_id; 
     END LOOP; 
     close cr_cursor; 
    end; 
END $$ 
DELIMITER ; 

注意すべき点がいくつかあります。まず、ブロック全体が上に示されている理由は、DELIMITERの問題が多くの闘争のためにストアドプロシージャを作成することに問題があるかもしれない将来の訪問者をここで助けることです。また、最初のドロップは、2回目以降のprocの編集にとって重要です。

また、これは明らかに、あなたが提示したコンセプトストアドプロシージャのテストです。つまり、LOOP内でselect my_key_id;を実行することにより、コンシューマ側(呼び出し文でストアドプロシージャを呼び出したもの)に結果セットを追加的に作成することになります。コードに複数の結果セットが返ってくるかどうかにかかわらず、これはあなたのレビューに影響を与えます。

また、パラメータとして渡すテーブル名の状態によって駆動されます。したがって、その表に値またはNULLが含まれている場合は、コードおよびその表名を渡す決定に基づいて得られるものが得られます。テーブルkey_idが含まれていると思われる表は、これがストアドプロシージャの作成方法です。

以下のビューは、複数の結果セットで動作します。上記画像は、魚やカエルのためにその中に2行を持っていたテーブルを示すこと

enter image description here

。 2つの結果セットが返されました(つまり、コード化された方法です)。私は2番目の結果セットを強調表示し、それから戻ってくる値(id 2)... LOOPが終了する前に最後に起こった行を示しました。

この回答を3回目に編集するのではなく、あなたの質問の下にあるコメントのリンクでチャットに参加することをおすすめします。

関連する問題