Почему этот SQL не запускается? Firebird хранимая процедура - PullRequest
2 голосов
/ 25 февраля 2012

Я выполняю следующий простой запрос в IBExpert , и он отлично работает:

SELECT
   pd.NOME_PRODUTO,
   es.QTDE_MINIMA
FROM
   TBL_ESTOQUE es,
   TBL_PRODUTO pd
WHERE
   es.qtde_estoque = 0
   AND es.produto = pd.id
ORDER BY
   pd.NOME_PRODUTO

Но если я создаю хранимую процедуру с двумя выходными параметрами (смниже)

begin
SELECT
  pd.NOME_PRODUTO,
  es.QTDE_MINIMA
FROM
  TBL_ESTOQUE es,
  TBL_PRODUTO pd
WHERE
  es.qtde_estoque = 0
  AND es.produto = pd.id
ORDER BY
  pd.NOME_PRODUTO
into :nome_produto, :qtde_minima;
suspend;
end

Я получаю сообщение, подобное этому:

несколько строк в одиночном выборе.несколько строк в одиночном выборе.В процедуре 'SPD_SALDO_PROD_ZERADO_ESTOQUE' строка: 7, столбец: 3 "

Что это? Я не понимаю, что происходит ...

Ответы [ 2 ]

3 голосов
/ 10 марта 2012

Ответ rstrelba показывает, как решить проблему. Если вы хотите понять это, вот что происходит.

suspend внутри хранимой процедуры Firebird возвращает строку вызывающей стороне. Он может использоваться по-разному и может рассматриваться как аналог оператора yield в Python: приостановить операцию и отправить обратно одно значение (или строку, в данном случае), а затем продолжить, когда вызывающая сторона запросит дополнительные данные. (Это должно быть сделано по техническим причинам, потому что драйверы баз данных не всегда извлекают весь набор результатов сразу.)

У вас есть запрос select, который может вернуть произвольное количество значений, за которым следует один suspend. Firebird выдает ошибку, говоря вам, что это, вероятно, неправильно. То, что вы хотите сделать, это поместить select в цикл for, который зацикливает набор результатов и приостанавливает один раз для каждой строки, как демонстрирует ответ rstrelba. Это гарантирует, что вызывающая сторона получит все результаты обратно.

3 голосов
/ 04 марта 2012
FOR SELECT ...
INTO ...
DO SUSPEND;
...