比較的単純な質問ですが、私のすべての調査から、まともな答えを見つけることができませんでした。
技術的に正しいのは、ハンドラーが定義された後、または実際にカーソルを使用する前にカーソルを開くことです。
例えば、
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO a, b;
FETCH cur2 INTO c;
IF done THEN
LEAVE read_loop;
END IF;
IF b < c THEN
INSERT INTO test.t3 VALUES (a,b);
ELSE
INSERT INTO test.t3 VALUES (a,c);
END IF;
END LOOP;
CLOSE cur1;
CLOSE cur2;
END;
上記のステートメントはほとんどの例で標準のようですが、それは可能でしょうか
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SELECT x,y,z INTO @X, @Y, @Z FROM TableA WHERE X=1;
IF (@X >= @Y) THEN
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO a, b;
FETCH cur2 INTO c;
IF done THEN
LEAVE read_loop;
END IF;
IF b < c THEN
INSERT INTO test.t3 VALUES (a,b);
ELSE
INSERT INTO test.t3 VALUES (a,c);
END IF;
END LOOP;
CLOSE cur1;
CLOSE cur2;
ELSE
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO a, b;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO test.t3 VALUES (a,b);
END LOOP;
CLOSE cur1;
END IF;
END;
2番目のコードが何をしているのかわかります。特定の条件が満たされた場合にのみ2つのカーソルを開き、満たされていない場合は1つのカーソルのみを開きます。大丈夫なはずの私見。
実際、本 MySQLストアドプロシージャプログラミング には、例5-17の110〜111ページにこのサンプルコードがあります。
DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_customer=1;
SET l_last_customer=0;
OPEN customer_csr;
cust_loop:LOOP
FETCH customer_crs INTO l_customer_id;
IF l_last_customer=1 THEN LEAVE cust_loop; END IF;
SET l_customer_count=l_customer_count+1;
sales_block: BEGIN
DECLARE l_last_sale INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_sale=1;
OPEN sales_csr;
sales_loop:LOOP
FETCH sales_csr;
IF l_last_sale=1 THEN LEAVE sales_look; END IF;
CALL check_sale(l_sales_id);
SET l_sales_count=l_sales_count+1
END LOOP sales_loop;
END sales_block;
END LOOP cust_loop;
SET l_last_customer=0;
CLOSE customer_csr;
コード内で、BEGIN...END
ブロック内のカーソルの開閉に注意してください。あなたはあなたのコードで大丈夫なはずです。 mysqlが文句を言う場合は、THENコードとELSEコードをBEGIN...END
ブロック内に配置します。