詳細九、カーソル

シンボルは、オプションの別のいずれかを示し|タグは、[]オプションは、含ま示しています。

需要の背景

我々は、セレクトトラバースプロセスの結果を照会する必要がある場合、どのようにそれを達成するには?

この時点で、我々は結果によりカーソルSELECTクエリを設定し、処理のためにデータの行ごとを横切るカーソルを使用する必要があります。

この部分で

  • カーソルの定義

  • イテレータ

  • カーソルのステップを使用します

  • 詳細カーソルの実行

  • シングルカーソルのサンプル

  • ネストされたカーソルのサンプル

データを準備します

  ライブラリーを作成します。javacode2018

  あなたは、テーブルを作成します。TEST1、TEST2、TEST3を

  /*建库javacode2018*/
  drop database if exists javacode2018;
  create database javacode2018;

  /*切换到javacode2018库*/
  use javacode2018;

  DROP TABLE IF EXISTS test1;
  CREATE TABLE test1(a int,b int);
  INSERT INTO test1 VALUES (1,2),(3,4),(5,6);

  DROP TABLE IF EXISTS test2;
  CREATE TABLE test2(a int);
  INSERT INTO test2 VALUES (100),(200),(300);

  DROP TABLE IF EXISTS test3;
  CREATE TABLE test3(b int);
  INSERT INTO test3 VALUES (400),(500),(600);

まず、カーソルの定義

  カーソル(カーソル)は、データを処理するための方法、またはデータを表示するために設定された処理結果である結果のデータ線を介してカーソルを濃縮する能力を提供します。

  カーソルは、ストアド・プロシージャおよび関数に使用することができます。

効果第二に、カーソル

  SQLとして:

  select a,b from test1;

  私たちは、これらのデータの処理を通過したい場合は、上記のクエリは、この時点で我々が動作するようにカーソルを使用することができ、TEST1にデータを返します。

  選択データの最初の行を指し示すカーソルポインタに対応し、以下のデータは、ポインタを移動させることにより横断されてもよいです。

第三に、カーソルを使用するステップ

  カーソルを宣言するカーソル選択クエリを横断する必要性を指定する必要があり、このプロセスは専用カーソルを作成し、カーソルが宣言されたときに、このSQLを実行しません:。

  カーソルを開く:カーソルが対応するselect文を実行します開いているカーソルを。

  データを介して:選択カーソルを用いた結果は、各データ線を介してループし、次いで処理しました。

  カーソルをクローズします:あなたは閉じなければならないカーソルの使用を終了した後。

第四に、カーソルの構文

  カーソルを宣言

  DECLARE 游标名称 CURSOR FOR 查询语句;

Aあなただけのカーソルを宣言することができ、エンドを開始します。

  カーソルを開きます

open 游标名称;

  カーソルを移動します

  fetch 游标名称 into 变量列表;

変数結果に対応する、現在の行の結果を削除し、次のラインのデータにカーソルポインタ。

フェッチ、あなたは現在の行のデータ、データがない場合は、現在の行を取得します呼び出す場合、内部のMySQLにつながるNOT FOUNDエラー。

  カーソルをクローズします

  close 游标名称;

カーソルの後、使用後に閉じなければなりません。

第五に、単一カーソルのサンプル

    TEST1テーブルA、B、およびすべてのフィールドを計算する関数を書きます。

  関数を作成します:

    / *関数* /削除
    存在する場合にはDROP FUNCTIONをFUN1;
    $ /のための/ * *文の終了
    デリミタ$は
    / *関数を作成します* /
    CREATE FUNCTIONの  FUN1 (v_max_aの  INT)
      RETURNSは  int型
      BEGIN
        / *結果を格納するために使用される* /
        DECLAREのv_totalの  int型0 DEFAULT;
        / *現在の行*の値を保持する変数を作成/
        DECLAREのV_A  DEFAULT INT  0;
        / * / b *表の現在の行を保存するために使用される変数を作成
        V_B DECLARE  DEFAULT値int  0;
        / *カーソル終了フラグ変数を作成する* /
        DECLAREのv_done  DEFAULTのFALSE INT;
        / *カーソルを作成する* /
        FORがWHERE <= v_max_a TEST1からSELECT A、Bをcur_test1 DECLAREカーソル。
        / *最後のv_doneにカーソルが真で設定し、カーソルが終わり* / v_doneできるかどうかを判断するために
        、NOT FOUNDを= TRUE v_doneのハンドラにSETを継続DECLAREを
        * / / *設定された初期値v_total
        SETのv_total =  0;
        / *オープン・カーソル* /
        OPEN cur_test1;
        / *ループ*を使用してカーソルをループ/
        :ループ
          / *現在の行のデータを取得し、現在の行がデータでない場合V_A、V_Bが、v_doneに設定するに現在のラインデータ真*に/
          へV_A cur_test1 V_bををFETCH;
          v_doneカーソルがループを終了し、超えているか否かを判断することにより、/ * * /
          v_doneはTHEN IF
            LEAVE;
          END IFを;
          / * v_total累積値処理の* /
          SET v_total = v_total + V_A + V_B;
        END LOOP;
        / *カーソルを閉じます* /
        CLOSE cur_test1;
        / *戻り結果* /
        リターンv_total、
      エンド$
    / *設定ターミネータ; * /
    DELIMITER;
    

    上記のステートメントは、プロセス内で実行され、次の解決、問題がある可能性があります。

    エラーメッセージ:MySQLの関数を作成するには、この関数は、DETERMINISTIC、NOのどれも持っていません表示される SQL、またはSQLデータを読み出し

    この関数は、DETERMINISTIC、NO SQLのいずれを有していない、またはその宣言とバイナリSQLデータを読み出します

    デフォルト設定では、関数のmysqlを作成することはできません

    解決策1:

    実行:

    GLOBAL log_bin_trust_function_creators = 1を設定します。

    しかし、失敗の再起動について

    注意:主のスレーブからコピーするときに、それ以外の場合は、マスター・スレーブの同期の失敗につながる設定する必要があります

    解決策2:

    my.cnfの中で設定し、どの

    ログ・ビン・信託機能-クリエイター= 1を

    しかし、この必要性は、サービスを再起動します

第六に、カーソルプロセスの詳細  

  一例として、上記のサンプルコードでは、のは、カーソルの詳細な実行を見てみましょう。

  開いたときにカーソルが、ときに、カーソルのポインタがあるカーソルSELECT文に対応する実行され、選択ポインタは、最初の行のレコードの結果を指します

  呼び出されたときにfetch 游标名称データがトリガされません場合、データは、現在の行を現在の行を取得しますNOT FOUND例外を。

  トリガーときNOT FOUNDとき異常が、我々はそれをマークするために変数を使用することができ、次のコード:

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done=TRUE;

  場合、カーソルはデータがトリガされないNOT FOUND異常が、変数v_downの値が設定されTURE、ループができを通じて、v_down制御サイクルの終了値。

  :現在のラインデータ、現在の行が対応する変数に格納されたデータ、およびデータの次の行にカーソルポインタ、次のif文

   fetch 游标名称 into 变量列表;

七、ネストされたカーソル

メモリ書き込み手順は、TEST2、TEST3を横断する、フィールドおよびTEST2 TEST3のフィールドbの任意の組み合わせは、TEST1テーブルに挿入されます。

  ストアドプロシージャを作成します。

  /*删除存储过程*/
  DROP PROCEDURE IF EXISTS proc1;
  /*声明结束符为$*/
  DELIMITER $
  /*创建存储过程*/
  CREATE PROCEDURE proc1()
    BEGIN
      /*创建一个变量,用来保存当前行中a的值*/
      DECLARE v_a int DEFAULT 0;
      /*创建游标结束标志变量*/
      DECLARE v_done1 int DEFAULT FALSE;
      /*创建游标*/
      DECLARE cur_test1 CURSOR FOR SELECT a FROM test2;
      /*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test1是否结束了*/
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done1=TRUE;
      /*打开游标*/
      OPEN cur_test1;
      /*使用Loop循环遍历游标*/
      a:LOOP
        FETCH cur_test1 INTO v_a;
        /*通过v_done1来判断游标是否结束了,退出循环*/
        if v_done1 THEN
          LEAVE a;
        END IF;

        BEGIN
          /*创建一个变量,用来保存当前行中b的值*/
          DECLARE v_b int DEFAULT 0;
          /*创建游标结束标志变量*/
          DECLARE v_done2 int DEFAULT FALSE;
          /*创建游标*/
          DECLARE cur_test2 CURSOR FOR SELECT b FROM test3;
          /*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test2是否结束了*/
          DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done2=TRUE;

          /*打开游标*/
          OPEN cur_test2;
          /*使用Loop循环遍历游标*/
          b:LOOP
            FETCH cur_test2 INTO v_b;
            /*通过v_done1来判断游标是否结束了,退出循环*/
            if v_done2 THEN
              LEAVE b;
            END IF;

            /*将v_a、v_b插入test1表中*/
            INSERT INTO test1 VALUES (v_a,v_b);
          END LOOP b;
          /*关闭cur_test2游标*/
          CLOSE cur_test2;
        END;

      END LOOP;
      /*关闭游标cur_test1*/
      CLOSE cur_test1;
    END $
  /*结束符置为;*/
  DELIMITER ;

X.の概要

  1. カーソルが横断するクエリ結果を処理するために使用されます

  2. カーソルを使用するプロセス:カーソルがクローズされ、カーソルを移動、カーソルを開き、カーソルを宣言する

  3. カーソルは、ストアド・プロシージャおよび関数のみを使用することができます

  4. A彼女は唯一のカーソルを宣言することができ、エンドを開始

  5. 単一のネストされたカーソルとカーソルの使用をマスター 

 

おすすめ

転載: www.cnblogs.com/biao/p/11775704.html