我有一个存储过程,我重复计算,如
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次。所以我想避免它。我可以存储到变量中并使用它吗?
答案 0 :(得分: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;
这是您可以按照自己喜欢的方式工作和重用的基本结构。
答案 1 :(得分: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;
在函数的过程中,您可以调用其他函数并将结果存储在变量中 - 这是使用存储函数/过程的主要原因。