Запустите скрипт Oracle SQL дважды с разными параметрами

У меня есть оператор SQL в разработчике Oracle SQL, который имеет некоторые переменные:

DEFINE custom_date = "'22-JUL-2016'" --run1
DEFINE custom_date = "'25-JUL-2016'" --run2

SELECT * FROM TABLE WHERE date=&custom_date

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


person Nickpick    schedule 26.09.2016    source источник
comment
stackoverflow.com/questions/18620893/   -  person OldProgrammer    schedule 26.09.2016
comment
Это единственный способ запустить скрипт более одного раза? Мне действительно нужно вызывать его извне несколько раз?   -  person Nickpick    schedule 26.09.2016


Ответы (2)


В Oracle &variable является «подстановочной переменной» и не является частью SQL; это часть языка сценариев SQL * Plus (понимаемый SQL Developer, Toad и т. д.)

Лучший вариант, и то, о чем вы спрашиваете, это BIND VARIABLES. Обозначается :variable (с двоеточием: вместо &), например :custom_date.

Разница в том, что переменная подстановки заменяется ее значением во внешнем приложении (в вашем случае SQL Developer) до того, как запрос будет отправлен в механизм Oracle. Переменная связывания заменяется во время выполнения. Это имеет несколько преимуществ; их обсуждение выходит за рамки вашего вопроса.

Когда вы выполняете запрос с переменными связывания в SQL Developer, программа откроет окно, в котором вы вводите нужные значения для переменных связывания. Вам придется немного поэкспериментировать с этим, пока вы не сможете заставить его работать (например, я никогда не помню, нужно ли вводить дату с одинарными кавычками или без). Удачи!

person mathguy    schedule 26.09.2016
comment
Сценарию на самом деле нужно будет запустить несколько сотен параметров, поэтому всплывающее окно не является решением. Также некоторые параметры являются списками (где в &var.). Не уверен, как это можно было бы обработать в переменных связывания - person Nickpick; 26.09.2016
comment
?? Как вы сейчас вводите значения для нескольких сотен параметров, используя подстановочные переменные? Похоже, параметры вообще не должны быть параметрами, они должны храниться в таблице (или генерироваться вашим приложением) и использоваться таким образом. - person mathguy; 26.09.2016
comment
Если вам нужно выполнить запрос более одного раза, вам нужно написать процедуру на PL/SQL (или, возможно, на предпочтительном для вашей организации языке, таком как Java или C#) — это совсем другая тема. В запросе по-прежнему должны использоваться переменные связывания, а значения должны откуда-то поступать (таблица, сгенерированная приложением и т. д.). - person mathguy; 26.09.2016
comment
К сожалению, для этого мне не разрешено использовать что-либо еще, кроме SQL, иначе я мог бы легко решить это на python. - person Nickpick; 26.09.2016
comment
@nickpick - тогда что ты имеешь в виду под сценарием? Вы имеете в виду SQL-запрос? (Запрос НЕ является сценарием!) В Oracle SQL вы можете выполнять только один запрос за раз; все остальное запускает скрипт в чем-то другом, кроме простого SQL. - person mathguy; 26.09.2016

Define используется в TRANSACT SQL. Чтобы сделать это способом Oracle, вы можете создать анонимный блок PL/SQL, подобный этому:

DECLARE
    p_param1 DATE;
    p_param2 NUMBER;
    CURSOR c_cur1(cp_param1 DATE,cp_param2 NUMBER)
    IS
        SELECT * FROM table WHERE date = cp_param1
    ;
BEGIN
    -- Execute it first time
    p_param1 := TO_DATE('2016-09-01','YYYY-MM-DD');
    FOR r IN c_cur1(p_param1)
    LOOP
        NULL;
    END LOOP;
    -- Execute it second time
    p_param1 := TO_DATE('2015-10-11','YYYY-MM-DD');
    FOR r IN c_cur1(p_param1)
    LOOP
        NULL;
    END LOOP;
END;

И в нем вы создаете курсор с параметрами и дважды выполняете его с разными параметрами. Я не знаю, почему Вы хотите выполнить этот запрос дважды, поэтому приведенный выше скрипт ничего не делает с результатами, но он, безусловно, должен выполнить Ваш запрос дважды с разными параметрами.

person T.Z.    schedule 26.09.2016
comment
Хорошо, я попробую это. Я хочу выполнить его дважды, потому что мой фактический запрос создает новые таблицы в зависимости от параметров. Я буду создавать новую таблицу каждый раз, когда она выполняется, и имя таблицы также является переменной. - person Nickpick; 26.09.2016
comment
Звучит нехорошо... ;) Но я тоже недостаточно знаю, помогите или прокомментируйте Ваш подход. Укажите код, который вы пытаетесь выполнить. - person T.Z.; 26.09.2016
comment
Я получаю эту ошибку при запуске вашего примера: PLS-00103: Обнаружен символ ; при ожидании одного из следующих: loop Символ loop был заменен на ; продолжить. - person Nickpick; 26.09.2016
comment
Я забыл про END LOOP. Я исправил ответ выше. - person T.Z.; 26.09.2016
comment
по-прежнему возникают ошибки: ORA-06550: строка 6, столбец 60: PL/SQL: ORA-00936: отсутствует выражение ORA-06550: строка 6, столбец 9: PL/SQL: оператор SQL игнорируется 06550. 00000 - строка %s, столбец %s:\n%s *Причина: Обычно ошибка компиляции PL/SQL. - person Nickpick; 26.09.2016
comment
Как я уже говорил, предоставьте код, который вы пытаетесь выполнить. - person T.Z.; 26.09.2016