0

次のような計算を繰り返すストアドプロシージャがあります

DROP PROCEDURE sp_alters;
DELIMITER $$


CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `sp_alters`()
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
    BEGIN
SELECT  
   `fn_getDiscount`(`t_orderitem`.`a_orderitemid`,`t_orderitem`.`a_quantity`)  AS `discount`,

    fn_getnewvalues(`fn_getDiscount`(`t_orderitem`.`a_orderitemid`,`t_orderitem`.`a_quantity`),a_orderitemid) as newvalue

FROM t_orderitem;
    END$$

DELIMITER ;

ここで、同じストアド プロシージャ内で fn_getDiscount を 2 回呼び出していることがわかります。だから避けたい。変数に格納して使用できますか?

4

2 に答える 2

0

完全なステートメントと少なくともプロシージャのヘッダーを示していれば役に立ちましたが、コードとして提示したものを見ると、コードからのスニペットのように見えます.fn_getDiscountはプロシージャではなく関数のようです.

ステートメントを準備しても、ステートメントが参照されるたびにステートメントを解析する必要がなくなるだけです。ステートメントを実行するオーバーヘッドは避けられません。

IIRC、MySQL は現在これを実装していませんが、DETERMINISTIC として宣言された関数 (つまり、特定の入力セットに対して常に同じ出力を副作用なしで生成する) はキャッシュ可能です。これは将来変更される可能性があるため、良い考えです。追加します。

関数が決定的である場合は、サブクエリを使用して複数回呼び出すことを避けることができます。

SELECT func_result
FROM (SELECT expensive_function(your_columns...) AS func_result
      FROM your_table
      WHERE your_column_a BETWEEN 1 AND 100) AS ilv
WHERE func_result > 50;

関数のプロシージャ内で、他の関数を呼び出して結果を変数に格納できます。これが、ストアド関数/プロシージャを使用する主な理由です。

于 2013-04-04T11:00:58.210 に答える
0

はい、できます。

文を準備してから再利用する必要があります。

SET @your_variable = "this is some text you can repeat";
SET @your_query=CONCAT("
INSERT INTO something
", @some_variable,"
WHERE other_things");

PREPARE stmt FROM @your_query;
EXECUTE stmt;

これは、好みの方法で作業および再利用できる基本構造です。

于 2013-04-04T10:48:23.010 に答える