MySQL存储过程重用?

时间:2011-04-26 10:28:16

标签: mysql stored-procedures

我有一个相当复杂的存储过程sp_assembly_breakdown,它接受​​一个参数assembly_id。生成的输出始终是基于该参数的单行,包含大约20个计算字段(成本和小时)。

我还有一个查询会根据另一个参数assembly_id创建panel_id列表。我想以某种方式为该列表中的每个sp_assembly_breakdown调用assembly_id,并将所有结果合并在一起,即每assembly_id行一行,其中每行由sp_assembly_breakdown生成。

我想在服务器端完成所有这些操作。我们的想法是客户端应用程序将单个参数panel_id传递给存储过程,而存储过程又返回sp_assembly_breakdown的多个调用。数据将被复制到客户端的临时表中,并用于生成报告。

编辑:更多信息......

+----------+    +-------------+    
! panel    !    ! assembly    !  
+----------+    +-------------+    
! panel_id !    ! assembly_id !  
! ...      !    ! panel_id    !  
!----------!    ! ...         !  
                +-------------+  

panelassembly表具有一对多的关系。 sp_assembly_breakdown加入与汇编相关的其他表格(未显示),例如assembly_partassembly_labour

所需的输出将是表格(显示示例数据):

+-------------+-------+-------+-------+-------+-------+-------+---
! assembly_id ! cost1 ! cost2 ! cost3 ! cost4 ! cost5 ! cost6 ! ...
+-------------+-------+-------+-------+-------+-------+-------+---
! 1           ! 100   ! 0     ! 20    ! 300   ! 0     ! 0     ! ...
! 3           ! 200   ! 0     ! 40    ! 100   ! 0     ! 0     ! ...
! 6           ! 300   ! 0     ! 600   ! 200   ! 0     ! 0     ! ...
! 12          ! 400   ! 0     ! 700   ! 300   ! 0     ! 0     ! ...

2 个答案:

答案 0 :(得分:0)

如果panel_id通过表格与assembly_id相关联,那么您可以define a view,我称之为sp_panel_breakdown,封装表格连接,然后从您的应用程序中选择sp_panel_breakdown where panel_id = ?。我认为可行。我不是一个MySQL大师(远离它)。

如果您还没有panel_id到数据库中的组件assembly_id的映射,那么为了查询的目的,“动态”创建一个临时表,并且然后加入它。它有点难看,但它仍然很快;比重复调用sp_assembly_breakdown更快,可能更少丑陋。

答案 1 :(得分:0)

为了将来参考,万一有人可能觉得它有用,这就是我提出的解决方案的本质:

CREATE STORED PROCEDURE sp_panel_breakdown(p_panel_id INT)
BEGIN
    -- create temporary table
    DROP TABLE IF EXISTS breakdown;
    CREATE TEMPORARY TABLE breakdown(breakdown_id INT NOT NULL AUTO_INCREMENT, assembly_id INT, cost1 DECIMAL(10,2), cost2 DECIMAL(10,2), ..., cost10 DECIMAL(10,2), PRIMARY KEY (breakdown_id));

    -- insert data into temporary table
    SELECT sf_assembly_breakdown(assembly_id) as dummy
        FROM assembly
        WHERE panel_id=p_panel_id;

    -- return temporary table
    SELECT * FROM breakdown;
END

CREATE STORED FUNCTION sf_assembly_breakdown(p_assembly_id INT) RETURNS INT
BEGIN
    -- do cost calculations
    ...

    -- insert calculated costs as a new row in temporary table
    INSERT INTO breakdown SELECT null, p_assembly_id, cost1, cost2, ..., cost10;

    -- return dummy value
    RETURN null;
END

关键点:

1)sp_assembly_breakdown已从存储过程转换为存储函数。这允许在父过程sp_panel_breakdown中的SELECT查询中为每一行调用它。

2)sp_assembly_breakdown,而不是返回单行结果集,现在将一行插入临时表。这样,可以为函数的每次连续调用累积结果。此外,该函数返回一个'哑'空值,因为它必须返回一些东西。

3)父程序sp_panel_breakdown必须创建要在breakdown中使用的临时表sf_assembly_breakdown

4)sp_panel_breakdown中的第一个选择查询调用函数sf_assembly_breakdown FOR EACH ROW。这将返回第一个'虚拟'结果集。

5)最后,sp_panel_breakdown过程返回临时表breakdown的全部内容作为第二个记录集。

6)调用sp_panel_breakdown时,返回2个结果集。第一个结果集包含虚拟空值,第二个结果集包含临时表breakdown的内容。