3

ストアド プロシージャの呼び出しで返される行数を返す関数を作成しようとしています。コードの繰り返しを最小限に抑えようとしています(コードのメンテナンス/デバッグを減らすために-プロシージャの選択が長くなります)。

ストアド プロシージャは、特定の基準に一致する行を読み取り専用で選択するだけです (あいまいですが、詳細は質問に重要ではありません)。

プロシージャを関数にコピーして select を count() に変更することもできますが、複数の結合で時間がかかるため、プロシージャを呼び出して行数を返すことができる関数を作成したいと考えていました。目標は最適化された実行ではなく、効率的なコードのメンテナンス、ボイラー プレートの削減です。

私はこれをテストとして試しました:


DELIMITER //

CREATE PROCEDURE IF NOT EXISTS proc_select1()
BEGIN
    SELECT 1;
END //

CREATE FUNCTION IF NOT EXISTS select1_count() RETURNS INT UNSIGNED
BEGIN
    CALL proc_select1();
    RETURN FOUND_ROWS();
END //

DELIMITER ;

しかし、私SELECT select1_count();が戻ってくることを望んでいるときに1、「関数から結果セットを返すことができません」というエラーが表示されます。

変数に代入FOUND_ROWSし、結果セットをクリアしてから変数値を返そうとしましたが、機能しません。

回避策を知っている人はいますか、それとも手順をコピーして貼り付けてSELECT COUNTand 関数に変換する必要がありますか?

私はMySQL 5.5.16(必要に応じてアップグレードできます)、Windows 7(誰もアップグレードしたくないようです:)、HeidiSQLv7.0.0.4053(関連する場合)を使用しています

いつものように、どんな助けも大歓迎です。

4

3 に答える 3

0

関数から結果セットを返すことはできません

このエラーはSELECT、出力値を格納せずにプロシージャでクエリを実行した場合に発生します。SQL_CALC_FOUND_ROWSその他 :見つかった行数を保存するように DBMS に指示することを忘れないでください。

一時変数なしで機能させようとしましたが(SELECTクエリのセットを「返さない」ためのmysqlキーワードが存在する可能性があります)、成功しませんでした。ここでは、一時変数を使用して動作するコードを示します。

    CREATE PROCEDURE  proc_select1()
BEGIN
    DECLARE temp INT;
    SELECT SQL_CALC_FOUND_ROWS 1 INTO temp;   
END //

CREATE FUNCTION select1_count() RETURNS INT UNSIGNED
BEGIN
    CALL proc_select1();
    RETURN FOUND_ROWS();
END //

結果は予想どおり 1 です :-) cf : SQLFiddle

于 2013-05-21T13:17:24.357 に答える
0

最初にdistinctを使用して個別の値を取得し、次にcountを使用します..のように

select count(distinct column_name) from table_name

于 2013-05-21T07:51:10.637 に答える
0

これは不可能のようです。関数呼び出し中のエラーSELECT INTOを回避するには、select ステートメントが必要です。プロシージャで使用されるステートメントcannot return a result set from a functionでこれが不可能または必要でない場合、関数はエラーなしでは実行されません。SELECT

CLEAR QUERY CACHEプロシージャー呼び出しの後にorを使用FLUSH QUERY CACHEしても役に立ちませんでした (そして、とにかく悪い考え/悪いコーディングです)。

于 2013-05-22T11:13:20.820 に答える