試験1:
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE testLoop()
BEGIN
END $$
DELIMITER ;
エラーなし:プロシージャ宣言とデリミタの使用はOKです。
試験2:
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE `testLoop`()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
END $$
DELIMITER ;
エラーなし:手順内の変数の宣言はOKです。
テスト3:
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE `testLoop`()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM `test_dropship_upload` INTO n;
SET i=0;
END $$
DELIMITER ;
エラーなし:SELECT
クエリと変数の割り当てはOKです。
試験4:
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE `testLoop`()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM `test_dropship_upload` INTO n;
SET i=0;
WHILE i<n DO
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
エラーなし:WHILE
ループはOKです。
試験5:
のみテストされていない部分は今INSERTクエリです:
INSERT INTO `test_2` (sku, qty) VALUES(sku, qty) FROM `test_dropship_upload` LIMIT i,1;
INSERTとINSERT ... SELECTのドキュメントを見ると、私たちはあなたのクエリが有効でないことがわかります。それ他のテーブルから値を挿入したい場合は、の部分が表示されています。
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE `testLoop`()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM `test_dropship_upload` INTO n;
SET i=0;
WHILE i<n DO
INSERT INTO `test_2` (sku, qty) SELECT sku, qty FROM `test_dropship_upload` LIMIT i, 1;
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
プロシージャの作成がエラーなく完了しました。
試験6:手順を実行する際に
ただし、SELECT
クエリの構文エラーを取得します:MySQLは変数でLIMIT
を使用して受け付けません。
動作させるには、prepared statementを使用する必要があります。
PREPARE stmt FROM "INSERT INTO `test_2` (sku, qty) SELECT sku, qty FROM `test_dropship_upload` LIMIT ?, 1";
EXECUTE stmt using @i;
DEALLOCATE PREPARE stmt;
It is also not allowed to used local variables in prepared statements:
ローカル変数のみが格納されたプログラム 実行時にスコープ内にあるため、それらへの参照が格納されたプログラム内で作成されたプリペアドステートメント では許可されていません。準備されたステートメントスコープは、ストアされたプログラムではなく、 現在のセッションです。ステートメントは、プログラムが終了した後に実行される になります。その時点で、変数は より長くなります。たとえば、SELECT ... INTO local_varは、 をプリペアドステートメントとして使用できません。この制限は、格納された プロシージャとファンクションのパラメータにも適用されます。
代わりに、ローカル変数i
のセッション変数@i
を使用して、この問題を回避するには、次の
手順の最終バージョン:
DELIMITER $$
DROP PROCEDURE IF EXISTS `testLoop`$$
CREATE PROCEDURE `testLoop`()
BEGIN
DECLARE n INT DEFAULT 0;
SELECT COUNT(*) FROM `test_dropship_upload` INTO n;
SET @i=0;
WHILE @i<n DO
PREPARE stmt FROM "INSERT INTO `test_2`(sku, qty) SELECT sku, qty FROM `test_dropship_upload` LIMIT ?, 1";
EXECUTE stmt USING @i;
DEALLOCATE PREPARE stmt;
SET @i = @i + 1;
END WHILE;
END $$
DELIMITER ;
あなたはデバッグに同じ方法を適用することができます多くの複雑なプログラミングの問題:単純なバージョンのコードから始め、テストします。より多くのコードを使ってテストを再実行する場合は、エラーを見つけて修正してから続行してください。
完全に見て、助けてくれてありがとう、すべてがいい –