2012-06-16 42 views
1

我在Coldfusion8/MySQL中調用存儲過程,從產品表中獲取3種最小和最大價格。如何將對象(從MySQL臨時表中)返回到Coldfusion存儲過程?

我在返回臨時表背到MySQL的問題。以下代碼僅返回第一個foundMin值,而不是臨時表本身。

如果我跑這裏面的MySQL結果

foundmin 1st price > returned to Coldfusion 
foundmax 1st price 
foundmin 2nd price 
foundmax 2nd price 
foundmin 3rd price 
foundmax 3rd price 
temporary table 

所以我返回所有單個表條目加表,當我只想表。

這裏是我的代碼:

BEGIN 
    DECLARE filterILN vARCHAR(100); 
    DECLARE localILN vARCHAR(100); 
    DECLARE orderILN vARCHAR(55); 
    #search strings 
    DECLARE p_e  vARCHAR(55) DEFAULT 'art.preis_ek'; 
    DECLARE p_a  vARCHAR(55) DEFAULT 'art.preis_aktuell'; 
    DECLARE p_r  vARCHAR(55) DEFAULT 'art.rabatt'; 
    DECLARE strLen  INT DEFAULT 4; 
    DECLARE strCount INT DEFAULT 1; 
    DECLARE searchFor vARCHAR(55); 
    DECLARE foundMin  DECIMAL(12,2); 
    DECLARE foundMax DECIMAL(12,2); 

    # temp table 
    DROP TEMPORARY TABLE IF EXISTS MinMax; 
    CREATE TEMPORARY TABLE MinMax (
     price vARCHAR(50) DEFAULT '' 
     , minVal DECIMAL(12,2) DEFAULT 0.00  
     , maxVal DECIMAL(12,2) DEFAULT 0.00  
    ) ENGINE=MEMORY; 

    # FILTER 1 
    IF param_reference_iln = 'A' THEN SET filterILN = 'B' 
    ELSEIF param_reference_iln = 'C' THEN SET filterILN = 'D' 
    END IF; 

    # FILTER 2 
    IF param_filter IS NOT NULL AND param_filter != "" 
    THEN SET localILN = CONCAT('AND (iln = "', param_filter, '")'); 
    ELSE SET localILN = '*'; 
    END IF; 

    # FILTER 3 
    IF param_preorder = 'ja' 
    THEN SET orderILN = CONCAT('AND vororder = "',param_preorder, '"'); 
    ELSE SET orderILN = '*'; 
    END IF; 

    #loop over strIDs 
    getPrice: 
     LOOP 
     IF ELT(strCount, p_e, p_a, p_r) = 'art.rabatt' 
     THEN SET searchFor = 'art.preis_ek - art.preis_aktuell)/art.preis_ek'; 
     ELSE SET searchFor = ELT(strCount, p_e, p_a, p_r); 
     END IF; 

     #min 
     SELECT MIN(searchFor) AS foundMin 
     FROM artikelstammdaten AS art 
      WHERE art.aktiv = "ja" 
      AND art.bestand != "0" 
      AND filterILN 
      AND art.modus = CONCAT('OPEN ', param_unlocked_iln) 
      AND localILN 
      AND orderILN 
      LIMIT 1; 
     #max 
     SELECT MAX(searchFor) AS foundMax 
     FROM artikelstammdaten AS art 
      WHERE art.aktiv = "ja" 
      AND art.bestand != "0" 
      AND filterILN  
      AND art.modus = CONCAT('OPEN ', param_unlocked_iln) 
      AND localILN 
      AND orderILN 
      LIMIT 1; 

     # insert into temp table 
     INSERT INTO MinMax (price, minVal, maxVal) 
     VALUES(ELT(strCount, p_e, p_a, p_r), foundMin, foundMax); 

     # increate counter by 1, end if strLen reached 
     SET strCount = strCount+1; 
     IF strCount = strLen 
     THEN LEAVE getPrice; 
     END IF; 

     END LOOP getPrice; 

    #output table 
    SELECT * FROM MinMax; 

    #destroy 
    DROP TABLE MinMax; 

END 

的值計算在臨時表中,他們應該是正確的,並插入。唯一的問題是上述返回表條目和表。

問題
我怎麼只返回臨時表作爲一個結果/結構,我可以再與ColdFusion的工作嗎?

回答

2

IMO真正的問題是你的mySQL程序返回多個結果集(而不是結構)。雖然這在某些情況下可能有用,但您的程序無意中正在進行。既然你不使用你的CF代碼這些成果,更好的解決辦法是消除他們只返回一個結果。即沒有必要浪費資源來返回你不需要的數據。

你的過程返回多個結果的原因是因爲你的循環中的SELECT語句。每個SELECT生成一個單獨的結果集(即查詢對象)。您可以通過刪除兩個SELECT語句消除這些直接插入的最大/最小值到您的臨時表來代替:

INSERT INTO MinMax (price, minVal, maxVal) 
    SELECT ELT(strCount, p_e, p_a, p_r), MIN(searchFor), MAX(searchFor) 
    FROM artikelstammdaten AS art 
    WHERE art.aktiv = "ja" 
     AND art.bestand != "0" 
     AND filterILN 
     AND art.modus = CONCAT('OPEN ', param_unlocked_iln) 
     AND localILN 
     AND orderILN 

然後程序應生成單個ResultSet即SELECT * FROM MinMax;

+0

看起來不錯。謝謝。也指着我朝這個方向發展。我將在明天編輯結構體。 – frequent

+1

另外,您是否按照預期驗證了「where」子句的實際工作情況?因爲我不認爲你可以使用變量來改變SQL。在大多數數據庫中,它需要動態sql。 – Leigh

+0

hm。今天想要測試。它更好地工作,因爲我有大量的通過創建像這樣的參數來生活的cfqueries,並且我想要移入mysql。例如filterIln變量來自cf中的一個循環,它創建了一個有效的用戶標識符字符串,如「iln = 123或iln = 456或iln = 789 ...」,我從另一個通用存儲過程中提取並添加到此處。我想我可以在這裏運行這個,但我做了filterIln一個util-variable-storedproc,導致它在我繼承的應用程序中使用 – frequent

0

我相信沒有任何機制有一個過程/函數返回整個表(表不是一個類型據我所知)。另一方面,只要您在同一個會話中(〜在同一個數據庫連接上)執行,您的程序即可完成後立即從您的應用程序中獲取SELECT * FROM MinMax

+0

應該是可能的。至少這就是我在另一個問題中被告知的:http://stackoverflow.com/questions/11004020/can-i-call-a-stored-procedure-in-a-cfloop-and-output-dynamic-out-參數-在-C/11005545#11005545。 – frequent

+0

有趣的黑客:http://stackoverflow.com/questions/273929/what-is-the-equivalent-of-oracles-ref-cursor-in-mysql-when-using-jdbc/445434#445434。它聞起來,雖然。 – RandomSeed

+0

hm。那麼您是否有另一個想法,我可以如何在單次轉儲中輸出我的值?我不想調用存儲過程3x,我一直試圖使用out參數。只是不工作... – frequent

0

明白了。我需要使用結果集屬性在ColdFusion中,像這樣:

<!--- my stored proc ---> 
<cfstoredproc procedure="proc_search_select_minmax" datasource="db"> 
    <cfprocparam type="in" value="#A#" cfsqltype="cf_sql_varchar" maxlength="13"> 
    <cfprocparam type="in" value="#B#" cfsqltype="cf_sql_varchar" maxlength="13"> 
    <cfprocparam type="in" value="#C#" cfsqltype="cf_sql_text"> 
    <cfprocparam type="in" value="#D#" cfsqltype="cf_sql_char" maxlength="4"> 
    <!--- 7 results (3 min/3 max/temp table, I need to get the 7th resultset ---> 
    <cfprocresult name="min_max_struct" resultSet=7> 
</cfstoredproc> 

因此,可以輸出從MySQL一個結構!你只需要知道它在哪裏...

+0

實際上,程序返回結果集(即查詢對象),* not * structs。請參閱下面的回覆。 – Leigh