Подтвердить что ты не робот

Объявление и установка переменных в инструкции выбора

Я пытаюсь написать простой запрос, в котором я объявляю некоторые переменные, а затем использую их в выражении select в Oracle. Я смог сделать это раньше в SQL Server со следующим:

DECLARE @date1   DATETIME
SET @date1 = '03-AUG-2010'

SELECT U.VisualID
FROM Usage u WITH(NOLOCK)
WHERE U.UseTime > @Date1

В результате поиска, который я сделал, вы не можете объявить и установить такие переменные в операторах Select. Правильно ли это, или я что-то делаю?

4b9b3361

Ответ 1

В результате поиска, который я сделал, вы не можете объявить и установить такие переменные в операторах Select. Это правильно или я что-то упускаю?

В Oracle PL/SQL и SQL есть два отдельных языка с двумя отдельными механизмами. Вы можете встраивать SQL DML в PL/SQL, и это даст вам переменные. Например, следующий анонимный блок PL/SQL. Обратите внимание, что / в конце не является частью PL/SQL, но сообщает SQL * Plus о отправке предыдущего блока.

declare 
    v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
    v_Count number;
begin
    select count(*) into v_Count
    from Usage
    where UseTime > v_Date1;
    dbms_output.put_line(v_Count);
end;
/

Проблема заключается в том, что блок, эквивалентный вашему T-SQL-коду, не будет работать:

SQL> declare 
  2      v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
  3  begin
  4      select VisualId
  5      from Usage
  6      where UseTime > v_Date1;
  7  end;
  8  /
    select VisualId
    *
ERROR at line 4:
ORA-06550: line 4, column 5:
PLS-00428: an INTO clause is expected in this SELECT statement

Чтобы передать результаты запроса из PL/SQL, анонимного блока, хранимой процедуры или сохраненной функции, курсор должен быть объявлен, открыт и затем возвращен вызывающей программе. (Помимо возможностей ответа на этот вопрос. EDIT: см. Получить набор результатов из хранимой процедуры oracle)

Клиентский инструмент, который подключается к базе данных, может иметь собственные переменные связывания. В SQL * Plus:

SQL> -- SQL*Plus does not all date type in this context
SQL> -- So using varchar2 to hold text
SQL> variable v_Date1 varchar2(20)
SQL>
SQL> -- use PL/SQL to set the value of the bind variable
SQL> exec :v_Date1 := '02-Aug-2010';

PL/SQL procedure successfully completed.

SQL> -- Converting to a date, since the variable is not yet a date.
SQL> -- Note the use of colon, this tells SQL*Plus that v_Date1
SQL> -- is a bind variable.
SQL> select VisualId
  2  from Usage
  3  where UseTime > to_char(:v_Date1, 'DD-Mon-YYYY');

no rows selected

Обратите внимание, что выше в SQLPlus, возможно, не работает (возможно, не будет) в разработчике Toad PL/SQL и т.д. Строки, начинающиеся с переменной и exec, являются командами SQLPlus. Они не являются командами SQL или PL/SQL. Строки не выбраны, потому что таблица пуста.

Ответ 2

Я пробовал это, и он работал:

define PROPp_START_DT = TO_DATE('01-SEP-1999')

select * from proposal where prop_start_dt = &PROPp_START_DT

 

Ответ 3

Команда SET специфична для TSQL - здесь эквивалент PLSQL тому, что вы разместили:

v_date1 DATE := TO_DATE('03-AUG-2010', 'DD-MON-YYYY');

SELECT u.visualid
  FROM USAGE u 
 WHERE u.usetime > v_date1;

Также нет необходимости в префиксах переменных с помощью "@"; Я предпочитаю префиксные переменные "v_", чтобы различать переменные и столбцы /etc.

Смотрите этот поток об эквиваленте Oracle NOLOCK...

Ответ 4

Попробуйте to_date.