процедурный запрос firebird выдавал ошибку «token unknown» в «SET TERM #;»

0

Я запрашиваю базу данных Firebird 2.5, используя php (ibase). Простые запросы работают нормально, но когда я пытаюсь использовать следующий процедурный запрос, я получаю ошибку "токен неизвестности" в строке 1, столбец 5 - т.е. когда встречается "TERM". Я чувствую, что мне не хватает чего-то очень элементарного здесь!

$query = <<<X
SET TERM #;
EXECUTE BLOCK 
   RETURNS (product INT, minPrice FLOAT, maxPrice FLOAT)
AS
DECLARE transID INT = 8733;

BEGIN
  FOR
    SELECT "Product", MIN("CurrencyRate" * "UnitPrice"), MAX("CurrencyRate" * "UnitPrice")
    FROM "CustomerStockInDetail"
    HAVING "Product" = :transID
    INTO :product, :minPrice, :maxPrice
  DO
     SUSPEND;
END#
SET TERM ;#
X;
Теги:
firebird2.5

1 ответ

2
Лучший ответ

Оператор SET TERM не является частью синтаксиса самой Firebird. Он является частью синтаксиса ISQL, а другие инструменты запросов Firebird (например, FlameRobin) следуют его примеру.

SET TERM инструктирует инструмент запроса, когда заканчивается оператор (по умолчанию они используют точку с запятой (;)). Когда инструмент запроса считывает терминатор оператора, инструмент запроса знает, что оператор завершен, и его можно отправить на сервер. Однако хранимые процедуры (и исполняемый блок) также используют полуколонны для завершения операторов. В этом случае инструменту запроса нужен другой терминатор, поэтому SET TERM.

Однако при общении с Firebird через API вы можете отправлять только отдельные полные заявления. Таким образом, нет необходимости в терминаторах операторов, и поэтому Firebird сам по себе не имеет понятия терминаторов операторов, кроме PSQL (процедурный язык).

Короче говоря, удалите SET TERM и измените свой код на:

$query = <<<X
EXECUTE BLOCK 
   RETURNS (product INT, minPrice FLOAT, maxPrice FLOAT)
AS
DECLARE transID INT = 8733;

BEGIN
  FOR
    SELECT "Product", MIN("CurrencyRate" * "UnitPrice"), MAX("CurrencyRate" * "UnitPrice")
    FROM "CustomerStockInDetail"
    HAVING "Product" = :transID
    INTO :product, :minPrice, :maxPrice
  DO
     SUSPEND;
END
X;

Также обратите внимание на отсутствие терминатора после последнего END.

  • 0
    Спасибо @MMarkRotteveel - еще один отличный ответ от вас. Подход EXECUTE BLOCK отлично подходит для помещения PSQL в DSQL, но не может понять, как заставить его работать через API!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню