MySQL使用触发器中的select语句调用过程 - “不允许从触发器返回结果集”

时间:2012-11-01 14:22:08

标签: mysql stored-procedures triggers procedures

这是SQL向导的一个。之前已经提出了类似的问题,我知道问题是什么,但是我在编写程序中的select语句时遇到了麻烦,以避免返回结果集,并返回我的触发器想要的全局变量。

对于一些背景知识,我在这里要完成的是使用一组触发器调用过程,这些过程将使用相同的gene_id计算相对于表中其他行的值的百分位数,插入或更新行。

(使用PMA分隔符设置为|)

计算百分位数值的过程正常

DROP PROCEDURE IF EXISTS gecg_relative_expr_compendium |

CREATE PROCEDURE gecg_relative_expr_compendium( IN in_gene_id varchar(24), IN in_fpkm double, OUT percentile float(4,2) ) 
BEGIN 
    SET @row := 0;
    SELECT fpkm, ( (rank / @row) *100 ) AS percentile
    FROM (
        SELECT fpkm, @row := @row +1 AS rank, gene_id
        FROM gene_expression_cufflinks_gene
        WHERE gene_id = in_gene_id
        ORDER BY fpkm ASC
    ) AS p
    WHERE fpkm = in_fpkm;
END |

我可以这样称呼它:

CALL gecg_relative_expr_compendium('ENSG00000251948', 19367800, @percentile)

返回:

fpkm    percentile
19367800    100.0000

我的触发器:

DROP TRIGGER IF EXISTS insert_gecg_relative_expr |

CREATE TRIGGER insert_gecg_relative_expr

 BEFORE INSERT ON `gene_expression_cufflinks_gene` FOR EACH ROW  
 BEGIN  
    CALL gecg_relative_expr_compendium(NEW.gene_id, NEW.fpkm, NEW.fpkm_percentile_compendium) ;
 END  |

当我插入触发触发器的行时,它会失败(为了清晰起见,不相关的列被修剪)

 INSERT INTO `mctp`.`gene_expression_cufflinks_gene` (
`gene_id` ,
`fpkm`,
`fpkm_percentile_compendium` ,
`fpkm_percentile_origin_tissue` ,
`fpkm_percentile_collection_tissue` ,
`fpkm_percentile_sample_cancer`
)
VALUES ('ENSG00000239906','555', NULL , NULL , NULL , NULL , NULL , NULL)

最终我希望我的触发器将计算出的新百分位值插入到正在插入的行中,例如NEW.fkpm_percentile_compendium。出于性能原因,预先计算这些百分位值是必要的,因为该表将是> 500米行,最终其他百分位数值必须根据关系计算,导致连接过多。

我有一个模糊的想法,解决方案应该涉及SELECT INTO变量而不是普通的select语句,但这会破坏我的程序。

DROP PROCEDURE IF EXISTS gecg_relative_expr_compendium |

CREATE PROCEDURE gecg_relative_expr_compendium( IN in_gene_id varchar(24), IN in_fpkm double, OUT percentile float(4,2) ) 
BEGIN 
    SET @row := 0;
    SELECT fpkm, ( (rank / @row) *100 ) AS percentile INTO fpkm, percentile
    FROM (
        SELECT fpkm, @row := @row +1 AS rank, gene_id
        FROM gene_expression_cufflinks_gene
        WHERE gene_id = in_gene_id
        ORDER BY fpkm ASC
    ) AS p
    WHERE fpkm = in_fpkm;
END |

给了我:

#1327 - Undeclared variable: fpkm 

所以我的问题是

1>如何从同一程序中访问我选择INTO的新变量?

2 - ;我怎么能这样做,以便在不返回结果集的情况下将变量返回到触发器?

非常感谢你的帮助。


更新>>以下是工作程序和触发器:

DROP PROCEDURE IF EXISTS gecg_relative_expr_compendium |
CREATE PROCEDURE gecg_relative_expr_compendium( IN in_gene_id varchar(24), IN in_fpkm double, OUT out_fpkm double, OUT out_percentile float(5,2)  ) 
BEGIN 
    SET @row := 0;
    SELECT fpkm, ( (rank / @row) *100 ) AS percentile
    FROM (
        SELECT fpkm, @row := @row +1 AS rank, gene_id
        FROM gene_expression_cufflinks_gene
        WHERE gene_id = in_gene_id
        ORDER BY fpkm ASC
    ) AS p
    WHERE fpkm = in_fpkm
    LIMIT 1 
    INTO out_fpkm, out_percentile;
END |



DROP TRIGGER IF EXISTS insert_gecg_relative_expr |

CREATE TRIGGER insert_gecg_relative_expr

 BEFORE INSERT ON `gene_expression_cufflinks_gene` FOR EACH ROW  
 BEGIN  
    CALL gecg_relative_expr_compendium(NEW.gene_id, NEW.fpkm, @f, @p);
    SET NEW.fpkm_percentile_compendium = @p;
 END  
|

触发器在插入时在行上运行百分位数计算。现在进行下一个任务,在与该gene_id匹配的所有其他行上运行该过程。 guhhh。

xoxoxox

2 个答案:

答案 0 :(得分:1)

我想到了两件事:

1)这是一种奇怪的语法:

SELECT fpkm, ( (rank / @row) *100 ) AS percentile INTO fpkm, percentile  

在此select语句之后才能使用'fpkm'。

2)它有点笨拙,但是从程序中“返回”值的一种方法是将它们放入临时表中。然后从调用过程中选择它们。

答案 1 :(得分:1)

SELECT fpkm, ( (rank / @row) *100 ) AS percentile INTO fpkm, percentile
                                                       ^^^^

你的未申报的var。可能应该是in_fpkm或其他名称。