Это невозможно. Firebird должен знать во время компиляции, какую переменную он собирается использовать. Динамическая ссылка на выходной параметр невозможна.
В качестве промежуточного решения вы можете присвоить результат временной переменной, а затем выполнить присваивание только нужной переменной в длинной цепочке if-else
. Это все еще дублирование кода, но меньше, чем повторение запроса снова и снова.
Вы также можете выполнить один запрос, который выдаст результаты сразу за все месяцы. Это приведет к небольшому раздуванию кода, но, вероятно, будет более эффективным:
select
(SELECT count(*) from MY_TABLE where MONTH_ID = 1),
(SELECT count(*) from MY_TABLE where MONTH_ID = 2),
(SELECT count(*) from MY_TABLE where MONTH_ID = 3),
-- ...and so on
into :O_PARAM_1, :O_PARAM_2, :O_PARAM_3;
Если вы использовали более позднюю версию Firebird, такую как Firebird 2.5, вы могли бы использовать CTE (хотя для этого простого запроса это не сильно упрощает его):
WITH counts AS (SELECT MONTH_ID, count(*) AS MONTH_COUNT from MY_TABLE M GROUP BY MONTH_ID)
select
(SELECT MONTH_COUNT from counts where MONTH_ID = 1),
(SELECT MONTH_COUNT from counts where MONTH_ID = 2),
(SELECT MONTH_COUNT from counts where MONTH_ID = 3),
-- ...and so on
into :O_PARAM_1, :O_PARAM_2, :O_PARAM_3;
Совершенно другим решением было бы отказаться от идеи исполняемой хранимой процедуры (хотя при наличии SUSPEND
в вашем текущем решении она фактически выбирается всегда с одной строкой) и вместо этого использовать выбираемую процедуру, которая возвращает результат в виде строк. Если это решение, зависит от ваших реальных потребностей в данных.
CREATE PROCEDURE MY_PROC (
I_PARAM INTEGER)
RETURNS (
MONTH_ID INTEGER, MONTH_COUNT INTEGER)
AS
BEGIN
FOR
select MONTH_ID, count(*)
from MY_TABLE M
GROUP BY MONTH_ID
into :MONTH_ID, :MONTH_COUNT
BEGIN
SUSPEND;
END
END
person
Mark Rotteveel
schedule
04.05.2015