2013-04-04 62 views
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倍。所以我想避免它。我可以存儲到一個變量並使用它嗎?

+0

你可以在這裏發佈整個存儲過程嗎? – 2013-04-04 10:52:17

回答

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; 

這是您可以工作和重用您喜歡的方式的基本結構。

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; 

內功能的過程中,你可以調用其他函數,結果存儲在一個變量 - 這是使用存儲的函數/過程的主要原因。

+0

我必須用它來計算另一列值。 – Hacker 2013-04-04 11:08:41