Могу ли я как-то объявить переменную как результат запроса? - PullRequest
0 голосов
/ 11 мая 2018

У меня есть хранимая процедура, которая должна использовать количество записей в таблице, назовем ее table1. Я знаю, что могу:

select count(*) 
  into variable_name 
  from table1

но я действительно хочу сохранить тело процедуры как можно более чистым и простым. Могу ли я поместить этот запрос в объявление и установить значение моей переменной как результат запроса в разделе объявления?

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Как уже упоминалось в Vivek и Locale по умолчанию, Select внутри pl / sql-блока (например, функции или процедуры) полностью в порядке.

Но есть одно место, где я это делаю: мы храним create-скрипты для автоматических интеграционных тестов в plsql-scripts.

Чтобы сделать их читаемыми, они выглядят так:

DECLARE
    sqlCreateTable   VARCHAR2 (2000) :=
'CREATE TABLE TMyTableName
(
  COL1        VARCHAR2(30 BYTE)             NOT NULL,
  COL2        VARCHAR2(30 BYTE)             NOT NULL
)
TABLESPACE MYTABLESPACE
PCTUSED    0
PCTFREE    0
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          1M
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING 
NOCOMPRESS 
NOCACHE
MONITORING';

    sqlCreateIndex   VARCHAR2 (2000) :=
'CREATE UNIQUE 
    [...]
)';

    sqlCreateView    VARCHAR2 (2000) := 
'CREATE OR REPLACE FORCE VIEW VMyTable
(
    COL1,
    COL2
)
    BEQUEATH DEFINER
AS
    SELECT COL1, COL2 FROM
      FROM MyTableName';
BEGIN
    -- |---------------------------------------------------------------------------|
    -- | CREATE TABLE                                                              |
    -- |---------------------------------------------------------------------------|
    dbms_output.put_line('- - - - - - START - - - - - -'); 
    dbms_output.put_line('CREATE TABLE:' || chr(10) || sqlCreateTable); 
    EXECUTE IMMEDIATE sqlCreateTable;

    dbms_output.put_line('CREATE INDEX:' || chr(10) || sqlCreateIndex); 
    EXECUTE IMMEDIATE sqlCreateIndex;

    dbms_output.put_line('CREATE VIEW:' || chr(10) || sqlCreateView); 
    EXECUTE IMMEDIATE sqlCreateView;

    dbms_output.put_line('- - - - - - DONE - - - - - -'); 
END;

Краткий пример запуска запроса и заполнения локальных переменных:

DECLARE
    myQuery   VARCHAR2 (2000) := 'SELECT 1 from DUAL';
    myVar     NUMBER;
BEGIN
    EXECUTE IMMEDIATE myQuery INTO myVar;

    DBMS_OUTPUT.put_line ('MyVar: ' || myVar);
END;
0 голосов
/ 11 мая 2018

Ответ - нет синтаксиса для встраивания неявного курсора в объявление. Общий синтаксис объявления переменной или константы:

identifier [constant] datatype := expression;

expression может быть функцией, например:

k_somecount constant integer := some_lookup('whatever');

Это может быть аккуратный подход, если функция используется в нескольких местах или имеет несколько шагов и т. Д.

Мне было интересно, есть ли способ использовать выражение XML, например:

k_somecount constant integer := cast(xmlwhatever(mystic xquery incantation) as integer);

но, похоже, нет (а если и было, то я не думаю, что вам это понравится).

Не существует неявного синтаксиса выражения курсора, такого как следующий:

-- Made-up syntax purely to illustrate what you might have been hoping existed:
k_somecount integer := (select count(*) from employees);
0 голосов
/ 11 мая 2018

Вы можете сделать это так,

DECLARE
    CURSOR c 
    IS   SELECT last_name, first_name 
           FROM employee;
    TYPE emp_tab IS TABLE OF c%ROWTYPE INDEX BY BINARY_INTEGER;
    v_emp_tab emp_tab;
    v_variable_count NUMBER;
BEGIN
    OPEN c;
    FETCH c BULK COLLECT INTO v_emp_tab;
    v_variable_count := v_emp_tab.COUNT;
    DBMS_OUTPUT.PUT_LINE(v_variable_count);
    CLOSE c;
END;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...