MySQL хранимая процедура повторное использование? - PullRequest
0 голосов
/ 26 апреля 2011

У меня довольно сложная хранимая процедура 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    !  
!----------!    ! ...         !  
                +-------------+  

Таблицы panel и assembly имеют отношение один ко многим. sp_assembly_breakdown объединяет другие таблицы (не показаны), связанные со сборкой, такие как assembly_part и assembly_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 голосов
/ 04 мая 2011

Для дальнейшего использования, если кто-то может найти это полезным, вот суть решения, которое я придумал:

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 был преобразован из хранимой процедуры в хранимую функцию. Это позволяет вызывать его для каждой строки в запросе SELECT в родительской процедуре sp_panel_breakdown.

2) sp_assembly_breakdown, вместо того, чтобы возвращать набор результатов из одной строки, теперь вставляет одну строку во временную таблицу. Таким образом, результаты могут быть собраны для каждого последующего вызова функции. Кроме того, функция возвращает пустое значение, потому что она должна что-то возвращать.

3) Родительская процедура sp_panel_breakdown должна создать временную таблицу breakdown для использования в sf_assembly_breakdown.

4) Первый запрос выбора внутри sp_panel_breakdown вызывает функцию sf_assembly_breakdown FOR EACH ROW. Это возвращает 1-й «фиктивный» набор результатов.

5) Наконец, процедура sp_panel_breakdown возвращает все содержимое временной таблицы breakdown в качестве 2-го набора записей.

6) При вызове sp_panel_breakdown возвращаются 2 набора результатов. 1-й набор результатов содержит фиктивные нулевые значения, 2-й набор результатов содержит содержимое временной таблицы breakdown.

0 голосов
/ 26 апреля 2011

Если panel_id относится к assembly_id через таблицу, тогда вы можете определить представление , которое я назову sp_panel_breakdown, которое инкапсулирует присоединение к таблице, и затем выбрать из sp_panel_breakdown where panel_id = ? в вашем приложении. Я думаю , что может сработать. Я не гуру MySQL (далеко не так).

Если у вас еще нет сопоставления panel_id с его компонентом assembly_id s в базе данных, то создайте временную таблицу «на лету» для целей запроса, а затем присоединитесь к ней , Это немного уродливо, но все равно будет быстро; то есть быстрее, чем повторные вызовы sp_assembly_breakdown, и, вероятно, меньше безобразно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...