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

Yes, you can.

You have to prepare the sentence and then reuse it.

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;

This is the basic structure from which you can work and reuse the way you prefer.

于 2013-04-04T10:48:23.010 回答
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 回答