FirebirdSQL logo

Параметризованные операторы

В DSQL операторе можно использовать параметры.Параметры могут быть именованными и позиционными (безымянные). Значение должно быть присвоено каждому параметру.

Особенности использования параметризованных операторов
  1. Одновременное использование именованных и позиционных параметров в одном запросе запрещено;

  2. Если у оператора есть параметры, они должны быть помещены в круглые скобки при вызове EXECUTE STATEMENT, независимо от вида их представления: непосредственно в виде строки, как имя переменной или как выражение;

  3. Именованным параметрам должно предшествовать двоеточие (‘:’) в самом операторе, но не при присвоении значения параметру;

  4. Передача значений безымянным параметрам должна происходить в том же порядке, в каком они встречаются в тексте запроса;

  5. Присвоение значений параметров должно осуществляться при помощи специального оператора “:=”, аналогичного оператору присваивания языка Pascal;

  6. Каждый именованный параметр может использоваться в операторе несколько раз, но только один раз при присвоении значения;

  7. Для позиционных параметров число подставляемых значений должно точно равняться числу параметров (вопросительных знаков) в операторе;

  8. Необязательное ключевое слово EXCESS обозначает, что данный именованный параметр необязательно должен упоминаться в тексте запроса. Обратите внимание, что все не EXCESS параметры должны присутствовать в запросе.

Примеры EXECUTE STATEMENT с параметрами
Example 1. Использование EXECUTE STATEMENT с именованными параметрами:
...
DECLARE license_num VARCHAR(15);
DECLARE connect_string VARCHAR (100);
DECLARE stmt VARCHAR (100) =
  'SELECT license
   FROM cars
   WHERE driver = :driver AND location = :loc';
BEGIN
  ...
  SELECT connstr
  FROM databases
  WHERE cust_id = :id
  INTO connect_string;
  ...
  FOR
    SELECT id
    FROM drivers
    INTO current_driver
   DO
   BEGIN
     FOR
       SELECT location
       FROM driver_locations
       WHERE driver_id = :current_driver
       INTO current_location
     DO
     BEGIN
       ...
       EXECUTE STATEMENT (stmt)
       (driver := current_driver,
        loc := current_location)
       ON EXTERNAL connect_string
       INTO license_num;
       ...
Example 2. Использование EXECUTE STATEMENT с позиционными параметрами:
DECLARE license_num VARCHAR (15);
DECLARE connect_string VARCHAR (100);
DECLARE stmt VARCHAR (100) =
  'SELECT license
   FROM cars
   WHERE driver = ? AND location = ?';
BEGIN
  ...
  SELECT connstr
  FROM databases
  WHERE cust_id = :id
  INTO connect_string;
  ...
  FOR SELECT id
      FROM drivers
      INTO current_driver
  DO
  BEGIN
    FOR
      SELECT location
      FROM driver_locations
      WHERE driver_id = :current_driver
      INTO current_location
    DO
    BEGIN
      ...
      EXECUTE STATEMENT (stmt)
      (current_driver, current_location)
      ON EXTERNAL connect_string
      INTO license_num;
      ...
Example 3. Использование EXECUTE STATEMENT с избыточными (EXCESS) параметрами:
CREATE PROCEDURE P_EXCESS (A_ID INT, A_TRAN INT = NULL, A_CONN INT = NULL)
  RETURNS (ID INT, TRAN INT, CONN INT)
AS
DECLARE S VARCHAR(255);
DECLARE W VARCHAR(255) = '';
BEGIN
  S = 'SELECT * FROM TTT WHERE ID = :ID';

  IF (A_TRAN IS NOT NULL)
  THEN W = W || ' AND TRAN = :a';

  IF (A_CONN IS NOT NULL)
  THEN W = W || ' AND CONN = :b';

  IF (W <> '')
  THEN S = S || W;

  -- could raise error if TRAN or CONN is null
  -- FOR EXECUTE STATEMENT (:S) (a := :A_TRAN, b := A_CONN, id := A_ID)

  -- OK in all cases
  FOR EXECUTE STATEMENT (:S) (EXCESS a := :A_TRAN, EXCESS b := A_CONN, id := A_ID)
      INTO :ID, :TRAN, :CONN
      DO SUSPEND;
END

WITH {AUTONOMOUS | COMMON} TRANSACTION

По умолчанию оператор выполняется в контексте текущей транзакции.При использовании предложения WITH AUTONOMOUS TRANSACTION запускается новая транзакция с такими же параметрами, как и текущая.Она будет подтверждена, если оператор выполнился без ошибок и отменена (откачена) в противном случае.С предложением WITH COMMON TRANSACTION по возможности используется текущая транзакция.

Если оператор должен работать в отдельном соединении, то используется уже запущенная в этом соединении транзакция (если таковая транзакция имеется). В противном случае стартует новая транзакция с параметрами текущей транзакции.Любые новые транзакции, запущенные в режиме “COMMON”, подтверждаются или откатываются вместе с текущей транзакцией.