how to return an object (from a MySQL temporary table) into a Coldfusion stored procedure?

孤人 提交于 2019-12-11 08:58:56

问题


I'm calling stored procedure in Coldfusion8/MySQL which gets 3 types of min and max prices from products table.

I'm having problems returning the temp table back to MySQL. The below code only returns the first foundMin value and not the temp table itself.

If I run this inside MySQL the results are

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

So I'm returning all individual table entries plus the table, when I only want the table.

Here is my code:

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

The values are calculated correctly and also inserted in the temp table where they should be. The only problem is the above returns both the table entries AND the table.

Question:
How do I return just the temp table as a resultset/struct, which I can then work with in Coldfusion?


回答1:


IMO the real problem is your mySQL procedure returns multiple resultsets (not structs). While that can be useful in some cases, your procedure is doing it unintentionally. Since you are not using those results in your CF code, the better solution is to eliminate them and only return a single result. ie There is no point wasting resources to return data you do not need.

The reason your procedure returns multiple results is because of the SELECT statements inside your loop. Each SELECT generates a separate resultset (ie query object). You can eliminate those by removing the two SELECT statements and insert the MIN/MAX values directly into your temp table instead:

    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

Then the procedure should generate a single resultset ie SELECT * FROM MinMax;.




回答2:


I believe there is no mechanism to have a procedure/function return a whole table (TABLE is not a type AFAIK). On the other hand, you could SELECT * FROM MinMax from your application immediately after your procedure completes, as long as you do it within the same session (~ on the same DB connection).




回答3:


Got it. I need to use the resultset attribute in Coldfusion like so:

<!--- 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>

So it is possible to output a struct from MySQL! You just have to know where it is...



来源:https://stackoverflow.com/questions/11062812/how-to-return-an-object-from-a-mysql-temporary-table-into-a-coldfusion-stored

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!