Константы в запросе Oracle SQL

Я новичок в Oracle (хотя и знаком с SQL), и мне приходится писать довольно сложный запрос, в котором значение, полученное из текущей даты, используется много раз. Вместо того, чтобы каждый раз вычислять значение, было бы очевидным объявить константу для этой цели.

Однако, когда я затем пытаюсь использовать мою константу DateIndex в последующем операторе SELECT (который я хочу вернуть значения на основе «DateIndex»), синтаксический анализатор сообщает мне, что он выполняет SELECT INTO.

То, что у меня есть (упрощено до самой низкой формы), это...

 DECLARE DateIndex CONSTANT NUMBER(10,0) := 24;

 BEGIN
      SELECT DateIndex
      FROM DUAL;
END;

Можно ли использовать константы только при выборе таблицы, а не при возврате результатов? Кажется очень странным.

Обратите внимание, что у меня нет прав на запись в базу данных.

Большое спасибо за любую помощь.


person FourOaks    schedule 18.08.2009    source источник
comment
Какой инструмент вы используете? SQL*плюс?   -  person jva    schedule 18.08.2009


Ответы (5)


Ваш код не Oracle SQL, а PL/SQL. В PL/SQL результат запроса должен быть присвоен переменной. Таким образом, вам либо нужно использовать «предложение select into», если вы ожидаете ровно один результат, либо вы используете курсор.

С другой стороны, в SQL вы не можете объявить константу. Иногда вы можете обойти это ограничение, используя встроенное представление, например

select something-complex-here, x.pi 
from sometable, (
    select 3.1415 as pi, 1234 other_constant 
    from dual
)
person Jens Schauder    schedule 18.08.2009
comment
Это, вероятно, вызывает некоторое мое замешательство. Как видно из моего комментария выше, я привык создавать локальные переменные и константы в своем SQL (не говоря уже о временных таблицах!). - person FourOaks; 18.08.2009
comment
Ах! Я улавливаю твой дрейф. Может хорошо работать, я попробую. Спасибо. - person FourOaks; 18.08.2009

Я предпочитаю следующее использование WITH и таблицы DUAL:

WITH 
const AS ( SELECT 
    3.14 AS pi,
    1    AS one 
    FROM DUAL
)
SELECT * FROM sometable t,  const
 WHERE t.value = const.pi;

Это позволяет вам определять константы перед использованием в операторе, а фактический оператор не загроможден подзапросами.

person f3lix    schedule 11.09.2013

Ошибка связана не с вашей константой, а с тем, что вы используете оператор SELECT без INTO. SELECT в анонимном блоке — это не то же самое, как если бы вы запускали оператор SELECT, например, из SQL*Plus. Нет смысла выбирать что-то и ничего с этим не делать, поэтому он предлагает вам войти:

SELECT colA, colB
INTO variable_a, variable_b
WHERE something = DateIndex;

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

РЕДАКТИРОВАТЬ: неважно, я вижу, что не могу создать тип

person Chris Cameron-Mills    schedule 18.08.2009
comment
Да, я пытаюсь вернуть таблицу результатов в VB, выполняющий запрос для отображения на веб-странице. В моем более знакомом домене все слишком просто... DECLARE @DateIndex int SET @DateIndex = MONTH(GETDATE()) + 12 * YEAR(GETDATE()) SELECT * FROM Log WHERE MonthIndex = @DateIndex - person FourOaks; 18.08.2009

Если вы хотите вернуть набор результатов, вам нужен курсор ссылки.

create or replace procedure getlogs(p_sys_refcursor out sys_refcursor)
is
begin
  open p_sys_refcursor for
    select *
    from   log
    where  monthindex = 12 * to_char(sysdate,'yyyy') + to_char(sysdate,'mm');
end;
/

Значение sysdate будет определено только один раз в начале запроса, поэтому нет необходимости объявлять какую-то константу внутри sql или pl/sql.

Изменить1

Если вы не хотите вызывать хранимую процедуру, выполните:

select *
from   log
where  monthindex = 12 * to_char(sysdate,'yyyy') + to_char(sysdate,'mm');
person tuinstoel    schedule 18.08.2009

person    schedule
comment
Привет, спасибо за быстрый ответ, но, возможно, я упростил пример. Что мне нужно сделать, так это вернуть результаты запроса на основе значения DateIndex. Например. (чуть менее простой пример!)... SELECT * FROM SomeTable WHERE SomeColumn = DateIndex; - person FourOaks; 18.08.2009