バグの第24章「MySQLはなります知っている必要があります」

第二十四第二十章へ

XXIV

時々、1つ以上の行に前方または後方に移動させる必要がカーソルであり、行を取得、カーソルがSELECT文、サーバ上のMySQLデータベースクエリでない記憶されているが、文が取り出された結果セット

カーソルが主にインタラクティブなアプリケーションに使用され、ユーザーが閲覧または変更するには、画面上のデータをスクロールすることができます

MySQLのカーソルは、ストアドプロシージャ(及び機能)のためにのみ使用することができます

手順を使用します

1、ステートメント(定義)カーソル

図2に示すように、カーソルをオープンし、このプロセスは、取得実際のデータであります

必要に応じて、図3に示すように、各行を取得するために検索しました

図4に示すように、カーソルをクローズ

作成し、開いているカーソルをクローズし、

CREATE PROCEDURE processorders()
BEGIN
	-- 定义游标
	DECLARE ordernumbers CURSOR
	FOR
	SELECT order_num FROM orders;
	
	-- 打开游标
	OPEN ordernumbers;
	
	-- 关闭游标
	CLOSE ordernumbers;
	
END;

OPEN xxxのを注意すべきである、CLOSE xxxの文は(... ENDをBEGINの間)、単独で使用するかどうかが与えられている手順に格納する必要があります

次のフェッチ文はという繰り返し読み出しを確保しないように次のラインを取得するように、カーソルの内側前方に、別の訪問を行ポインタの動きを各列を使用してFETCH

CREATE PROCEDURE processorders()
BEGIN
	--定义一个局部变量
	DECLARE o INT;
	
	DECLARE ordernumbers CURSOR
	FOR
	SELECT order_num FROM orders;
	
	OPEN ordernumbers;
	
	--检索第一行
	FETCH ordernumbers INTO o;
	
	CLOSE ordernumbers;

END;

oをローカル変数に格納された検索ではなく、処理の最初の行

サイは、最後の行に最初の行からデータを取得します

CREATE PROCEDURE processorders()
BEGIN

	--定义局部变量,必须在定义游标之前定义
	DECLARE done BOOLEAN DEFAULT 0;
	DECLARE o INT;
	
	DECLARE ordernumbers CURSOR
	FOR
	SELECT order_num FROM orders;
	
	DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
	
	OPEN ordernumbers;
	
	--循环每一行
	REPEAT
		FETCH ordernumbers INTO o;
	UNTIL done END REPEAT;
	
	CLOSE ordernumbers;
	
END;

行われるまで本実施の形態では、繰り返し実行される真フェッチ、それが定義された開始DEFAULT 0で行われ、そして完了したらとしては真であります

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

REPEATループは継続することができないため、それ以上行がない場合は、このステートメントは、SQLSTATE「02000」は発生したときに、SETが行わHANDLER、= 1をCONTINUE定義し、SQLSTATE「02000」が見つかりません条件で、この条件が発生します

処理データが取得さ

-- 上一章学习过的存储过程,待会要用到
CREATE PROCEDURE ordertotal(
	IN onumber INT,
	IN taxable BOOLEAN,
	OUT ototal DECIMAL(8,2)
)	COMMENT 'Obtain order total, optionally adding tax'
BEGIN

	DECLARE total DECIMAL(8,2);
	DECLARE taxrate INT DEFAULT 6;
	
	SELECT Sum(item_price*quantity)
	FROM orderitems
	WHERE order_num = onumber
	INTO total;
	
	IF taxable THEN
		SELECT total+(total/100*taxrate) INTO total;
	END IF;
	
	SELECT total INTO ototal;
	
END;
-- 如果已经存在该过程,先删除
DROP PROCEDURE IF EXISTS processorders;

CREATE PROCEDURE processorders()
BEGIN
    -- Declare local variables
    DECLARE done BOOLEAN DEFAULT 0;
    DECLARE o INT;
    DECLARE t DECIMAL(8, 2);
    
    -- Declare the cursor
    DECLARE ordernumbers CURSOR
    FOR
    SELECT order_num FROM orders;
    
    -- Declare continue handler
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
    
    -- 如果表已经存在,先删除
	DROP TABLE IF EXISTS ordertotals;
    -- 创建表
    CREATE TABLE IF NOT EXISTS ordertotals (order_num INT, total DECIMAL(8, 2));
    
    -- Open the cursor
    OPEN ordernumbers;
    
    -- Loop through all rows
    REPEAT
    
        -- 取第一行
        FETCH ordernumbers INTO o;
        
        -- done仍为0
		IF NOT done THEN
        	-- 调用存储过程,将结果赋值给t 
			CALL ordertotal(o, 1, t);
        	-- 插入一行到新建的表中
			INSERT INTO ordertotals(order_num, total)
						VALUES(o, t);
				
		END IF;
 
    -- End of loop
    UNTIL done END REPEAT;
    
    -- Close the cursor  
    CLOSE ordernumbers;
END;

-- CREATE只相当于声明一个过程,CALL是调用,若没有该语句而执行接下来的SELECT语句,报错:表不存在
CALL processorders;

-- 查看该表
SELECT *
FROM ordertotals;

我々は一緒に税と各注文を格納するために使用する変数tを追加し、結果ordertotalsテーブルには、生成され

最後の二つの結果の出力ラインが得られ、異なるコードブックとコード、コードブックのバグ、コードの外観のバグをここに

REPEAT
	FETCH ordernumbers INTO o;
	
	CALL ordertotal(o, 1, t);
	
	INSERT INTO ordertotals(order_num, total)
	VALUES(o, t);
	
UNTIL done END REPEAT;

おそらく、次のような理由から、最終行の後に、サイクルの最初に戻っては、MySQLの試みが新しい行をフェッチするが、この時点で、それ以上の行を取得することはできない理論的には、1に行われ、この時間を持って、それがエラーを終了する必要がありますサイクルはなく、MySQLのように、しかし、サイクルを継続し、このサイクルが行われた後のための表で得O、周期値Tの値は、最後の2行を複製有する1したがって、それはもはやその後の操作1のために行われていない場合、1つのより多くの時間を判断するために、なぜ体自身のコードを循環しているループを抜けます

詳細な説明とサプリメント

公開された84元の記事 ウォン称賛7 ビュー10000 +

おすすめ

転載: blog.csdn.net/weixin_43569916/article/details/104541183