Доступные версии документации

Выполнение запроса

Назначение

   

Оператор запроса предназначен для организации непосредственной работы с СУБД.

В хранимых процедурах допустимы два вида запросов: претранслируемые, которые разбираются на этапе трансляции процедуры, и динамические, которые формируются, транслируются на этапе выполнения процедуры и сразу же выполняются. Приоритет обоих типов запросов наследуется от родительского канала. Претранслируемые и динамические запросы делятся на запросы возвращающие выборку данных и не возвращающие выборку данных. Запросы, возвращающие выборку данных, могут быть использованы в курсорах (см. пункт Открытие курсора). Текст запроса должен оканчиваться знаком (;) и быть заключенным в двойные апострофы (").

В качестве претранслируемых запросов обычно используются запросы с параметрами. Запрос транслируется и сохраняется в БД. На этапе выполнения к претранслированному запросу привязываются вычисленные параметры, если они есть.

В качестве динамических запросов используются запросы, текст которых на момент трансляции процедуры неизвестен (он формируется в виде символьного выражения хранимой процедурой в процессе её выполнения, поэтому синтаксический и семантический контроль такого запроса производится при выполнении процедуры).

Если при выполнении запроса обнаруживается ошибка, происходит исключение с соответствующим кодом завершения.

Синтаксис

           
<выполнение претранслируемого запроса>::=
    EXECUTE <запрос> [{,|USING} <параметр> [, …]] [INTO <переменная> [, …]];

<выполнение динамического запроса>::=
    EXECUTE DIRECT <выражение символьного типа> [{,|USING} <параметр> [, …]] [INTO <переменная> [, …]];

Описание

  1. Оператор EXECUTE позволяет выполнить любой запрос (в том числе и SELECT) по отдельному каналу СУБД ЛИНТЕР, который неявно открывается при обработке этого оператора (его закрытие производится в зависимости от обработки транзакции).

  2. <Запрос> должен быть обрамлен двойными апострофами «"» и оканчиваться «;».

  3. Параметр INTO <переменная> [, …] задает список скалярных переменных, в который должны быть загружены выбираемые по <запросу> значения. Количество и тип данных скалярных переменных должны соответствовать количеству и типу данных выбираемых по <запросу> значений. Запрос выборки должен возвращать только одну запись.

    Для <переменной> допускаются все простые типы данных, кроме BLOB и EXTFILE.

    Примечание

    Если результат <запроса> – пустая выборка, то <переменная> сохранит значение, которое было перед выполнением EXECUTE … INTO …

  4. Если задана опция DIRECT, текст запроса при создании процедуры не проверяется, а передается напрямую ядру СУБД ЛИНТЕР при выполнении процедуры, т.е. синтаксический и семантический контроль запроса выполняется при исполнении процедуры.

    Если опция DIRECT не указана, синтаксический и семантический контроль <запроса> выполняется на этапе создания процедуры.

    Сравните (таблица t1 отсутствует в БД):

    CREATE OR REPLACE PROCEDURE tst_dir()
    RESULT NUMERIC for debug
    DECLARE
      VAR VINST_ID NUMERIC;
    CODE
      EXECUTE "SELECT a from t1;" INTO VINST_ID; //ошибка трансляции
      EXECUTE DIRECT "SELECT a from t1;" INTO VINST_ID; //без ошибки трансляции
      RETURN VINST_ID;
    END;
  5. Если заданы опции DIRECT и <параметры>, то во время выполнения оператора сначала выполняется трансляция <запроса>, затем привязка параметров и выполнение <запроса>.

    Примечание

    Рекомендуется использовать опцию DIRECT только в ситуациях, когда статическая компиляция запроса невозможна – например, при динамическом указании имени таблицы или имен столбцов. Нежелательно использование оператора EXECUTE с опцией DIRECT для подстановки параметров в запрос, поскольку это гораздо эффективнее выполняется при помощи статического EXECUTE.

  6. В результате выполнения оператора EXECUTE может возникнуть исключение, соответствующее коду завершения СУБД ЛИНТЕР (так же, как и при выполнении операторов OPEN, FETCH и CLOSE).

  7. Запрос может транслировать один пользователь, а выполнять другой (в случае, если запрос указан в команде EXECUTE, и процедура выполняется не в режиме AS OWNER). Проверки наличия привилегий при этом проверяются для выполняющего пользователя, а не для транслирующего. От транслирующего пользователя берутся только умолчания (прежде всего его текущая схема).

    Есть различие с действием команды EXECUTE DIRECT при выполнении процедуры не в режиме AS OWNER – там и права проверяются для выполняющего пользователя, и умолчания берутся его же.

    Пользователь CREATOR: создает процедуру с командой
     EXECUTE "SELECT * FROM TBL;"
    Пользователь EXECUTOR: выполняет эту процедуру без AS OWNER
    Результат: запрос от имени EXECUTOR подается к таблице CREATOR.TBL
    
    Пользователь CREATOR: создает процедуру с командой
     EXECUTE DIRECT "SELECT * FROM TBL;"
    Пользователь EXECUTOR: выполняет эту процедуру без AS OWNER
    Результат: запрос от имени EXECUTOR подается к таблице EXECUTOR.TBL

Примеры

  1.  

    execute "update tab1 set s = ? where current of \"CURS\";" using sum;
  2.  

    execute "create table test(i int);";
  3.  

    var cnt int; //
    …
    execute "select count(*) from auto;" into cnt; //
    
  4.  

    create or replace procedure tst() result char(50) for debug
    declare
      var mdl char(20); //
      var sale int; //
    code
      execute "select model, year+1900 from auto where personid=500;" into mdl, sale; //
      return mdl+" дата продажи; "+ itoa(sale); //
    end;
    
  5.  

    create or replace table test(i int, utf nchar(10), v_utf nvarchar(20));
    insert into test (i, utf, v_utf) values(1, n'342f', n'56ffca45');
    insert into test (i, utf, v_utf) values(2, n'cccc', n'56745333fffa');
    
    create or replace procedure prc_test() result nchar(20) for debug
    declare
      var ch nvarchar(50); //
    code
      execute "select v_utf from test where i=2;" into ch; //
      return ch; //
    end;
    execute prc_test();
    Return value = 56745333fffa
    
  6.  

    create table aaa (i int, ch char(3));
    insert into aaa values(1, 'abc');
    insert into aaa values(2, 'def');
    insert into aaa values(3, 'ghi');
    create or replace procedure prc_test(in n int) result char(15) for debug
    declare
      var ch typeof(aaa.ch);//
    code
      execute "select ch from aaa where i=:p1;" using n into ch;//
      return ch;//
    end;
    execute prc_test(2);
    drop table aaa;
    
    Результат работы примера:
    
    Return value = def
    
  7.  

    execute block result typeof( person.fmlystat )
    declare
      var age integer;//
      var stat typeof(person.fmlystat);//
    code
      execute "update person set age=40 where name='kim' and firstnam='eddie'";//
      execute "select age, fmlystat from person where name=? and firstnam=?" using "kim", "eddie" into age, stat;//
      execute "update person set age=? where name=? and firstnam=?" using age + 1, "kim", "eddie";//
      execute "select age from person where name=? and firstnam=?", "kim", "eddie" into age;//
      return stat;//
    end;
    
  8.  

    create or replace procedure report(in Модель char(15); in Цвет char(10))
    result int for debug
    declare
      var Количество int; //
      var Запрос char(100); //
    code
      Запрос:="select count(*) from auto where model='"+ Модель+ "'and color='" + Цвет+"';";//
      execute direct Запрос into Количество; //
      return Количество; //
    end;
    execute report('PANTERA','BLACK');
    return value = 5
    
Заметили ошибку?
Выделите текст и нажмите Ctrl + Enter