2012-06-16 43 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