【问题标题】:MySQL calling a procedure with select statements from a trigger - "Not allowed to return a result set from a trigger"MySQL 从触发器调用带有 select 语句的过程 - “不允许从触发器返回结果集”
【发布时间】:2012-10-22 03:48:21
【问题描述】:

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

对于一些背景知识,我在这里尝试完成的是使用一组触发器来调用程序,该程序将在插入或行的更新。

(使用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 百分位值插入要插入的行中,例如 NEW.fkpm_percentile_compendium。出于性能原因,需要预先计算这些百分位值,因为该表将有超过 500m 行,并且最终必须根据关系计算其他百分位值,从而导致过多的连接。

我有一个模糊的想法,即解决方案应该涉及 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> 如何在不返回结果集的情况下将变量返回到触发器?

非常感谢您的帮助。


UPDATE >> 下面是工作流程和触发器:

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 匹配的所有其他行上运行该过程。呵呵。

xoxoxox

【问题讨论】:

    标签: mysql stored-procedures triggers procedures


    【解决方案1】:

    想到两件事:

    1) 这是奇怪的语法:

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

    在此 select 语句之后,您才能使用“fpkm”。

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

    【讨论】:

      【解决方案2】:
      SELECT fpkm, ( (rank / @row) *100 ) AS percentile INTO fpkm, percentile
                                                             ^^^^
      

      这是你未声明的变量。可能应该是in_fpkm 或其他名称。

      【讨论】:

      • 嗨-这是真的,我确实最终使用了 out_fpkm 来解决这个问题,但是 ethrbunny 的回答对解决整体问题更有帮助,因为我必须在整个选择之后移动 INTO 语句并且子查询让它工作。为所有人点赞。谢谢:)
      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多