2016-06-23 5 views
0

初めてMySQLカーソルを使用して壁に当てようとしています。コードスニペットの下にはがtStartとtEndの実際の(午前0時ではない)時間値を返すはずですが、私が得るのは「00:00:00」です。テーブルのStartTimeフィールドとEndTimeフィールドはTIME型です。 select文だけを実行すると、期待値が返されます。 Num_rowsは1行が返されたことを示しており、これも期待されています。私が間違っていることを誰かが助けることができますか?コードの下MySQLが値を返さないようにフェッチする

DECLARE tStart TIME; 
DECLARE tEnd TIME; 
DECLARE num_rows INT DEFAULT 0; 

DECLARE curs_1 CURSOR FOR SELECT MIN(asd.StartTime), MAX(asd.EndTime) FROM database.table1 asd WHERE (((asd.varid)='1006') AND ((asd.neededdate)='2016-06-22') AND ((asd.neededint)=3)); 

OPEN curs_1; 
SELECT FOUND_ROWS() INTO num_rows; 
FETCH curs_1 INTO tStart, tEnd; 

テストデータを生成することができる:

CREATE TABLE `table1` (`StartTime` TIME DEFAULT NULL,`EndTime` TIME DEFAULT NULL, `varid` VARCHAR(10) DEFAULT NULL, `neededdate` DATE DEFAULT NULL, `neededint` INT(11) DEFAULT NULL) ENGINE=INNODB; 

INSERT INTO `table1` (`StartTime`,`EndTime`,`varid`,`neededdate`,`neededint`) VALUES ('09:00:00','18:00:00','1006','2016-06-22',3); 
INSERT INTO `table1` (`StartTime`,`EndTime`,`varid`,`neededdate`,`neededint`) VALUES ('09:00:00','18:00:00','1007','2016-06-21',3); 
INSERT INTO `table1` (`StartTime`,`EndTime`,`varid`,`neededdate`,`neededint`) VALUES ('09:00:00','18:00:00','1008','2016-06-20',3); 
INSERT INTO `table1` (`StartTime`,`EndTime`,`varid`,`neededdate`,`neededint`) VALUES ('08:00:00','17:00:00','1006','2016-06-21',2); 
INSERT INTO `table1` (`StartTime`,`EndTime`,`varid`,`neededdate`,`neededint`) VALUES ('11:00:00','20:00:00','1006','2016-06-22',1); 
+0

クエリをテストするためのサンプルデータがありますか? –

答えて

1

カーソルが実際に単一の行を収容しています。

FOUND_ROWS()を使用していますが、SQL_CALC_FOUND_ROWSを使用せずに正常に動作しますが、通常はそれを使用します。しかし、あなたの場合、集計(合計)のために1行しか返されません。だから、ほとんど意味がない。トリッキーなデータセットのように、「カーソル」には何もありません。

私はCURSORを使用しても意味がありません。実際、私は決してカーソルを使用することをお勧めしません。結果を提供するリレーションおよびインデックスとパフォーマンス戦略を持つ高度にチューニングされたSQL Serverのパフォーマンスはひどいです。低性能のメカニズムを、そうでなければ意図的なストリームラインの堅牢なエンジンに投げ込むようなカーソル。キャブレターをコルベットで開き、少数の砂を投げ込むのと同じです。彼らは、手続き的に問題を回避しようとしているので、SQLの新しいデベロッパーと考えています。私はそれを決して使用しないことをお勧めします。

以下はマニュアルページCursorsです。そのカーソル内のデータを移動する独自の条件で行ごとに行があるため、LOOP構造を使用する必要があります。それはそれらを正しく得るためにかなりの忍耐を必要とします。それを他の方法で解決するまでは、たいていの場合アプリごとに1回、コードの最も難しいものをあたかも使ってみてください。パフォーマンスは本当に恐ろしいです、私を信頼してください。

あなたができることは、これらの値を変数に取り入れるだけです。

SELECT MIN(asd.StartTime) , MAX(asd.EndTime) into @myMin,@myMax 
FROM table1 asd 
WHERE (((asd.varid)='1006') AND ((asd.neededdate)='2016-06-22') AND ((asd.neededint)=3)); 

select @myMin,@myMax; -- display them if you want 

幸運にも、私はまだカーソルを使用しないと言いましたか? :p

+0

ありがとうございます。今私は実際にはVBAスクリプトをストアドプロシージャに変換しているので、カーソルを使用しています(レコードセットをすばやく置き換えます)。ステップ2は、機能したら、あなたが提案したように、元に戻って合理化して(可能であればカーソルを削除する)ことです。 – Jake

+0

興味深いことに、select文を使用しても、ローカル変数(DECLARE)の変数であれば、更新しない変数と同じ問題が発生します。これはセッション(@)変数でのみ機能するようです。 – Jake

+0

私は可能な限りローカル変数を避けるため、私はユーザー変数を使用しています。 http://stackoverflow.com/a/37904084を参照してください...その答えは途方もない恒星ではありません。 1つのページャを読んで、それぞれの賛否両論を議論するどこかで私は死ぬだろう。彼らは新しい開発者のために複雑なプログラミングを馬鹿にしてしまいます。 – Drew

関連する問題