Почему SQL Plus побуждает меня ввести значение? - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть query.sql файл, который выглядит следующим образом:

define start_date = '2020-02-01 00:00:00'
define end_date = '2020-02-20 00:00:00'

select * from customers where created_time between '&start_date' and '&end_date';

Когда я выполняю его в SQL Plus, я получаю приглашение ввести значение для start_date и end_date :

SQL> @query
Enter value for start_date: 
Enter value for end_date: 

Почему? Я думал, что я определил их в сценарии?


Редактировать: created_time имеет тип TIMESTAMP. Я попытался изменить запрос на:

define start_date = timestamp'2020-02-01 00:00:00'
define end_date = timestamp'2020-02-20 00:00:00'

select * from customers where created_time between &start_date and &end_date;

Но была обнаружена другая ошибка:

SQL> @query
old   1: select * from customers where created_time between &start_date and &end_date
new   1: select * from customers where created_time between timestamp'2020-02-01 and timestamp'2020-02-20
select * from customers where created_time between timestamp'2020-02-01 and timestamp'2020-02-20
                                                                                *
ERROR at line 1:
ORA-01850: hour must be between 0 and 23

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Во-первых, исправьте форматы литералов:

SQL> define start_date = date'2020-02-01'
SQL> define end_date = date'2020-02-20'

, а затем избавьтесь от лишних кавычек, которые уже ставятся во время инициализации

SQL> select * from customers where created_time between &start_date and &end_date;

Полагаю created_time относится к типу даты, не так ли?

Если тип данных имеет временную метку, как упомянуто в комментарии, то замените ключевые слова date на timestamp для определения переменных

SQL> define start_date = timestamp'2020-02-01 00:00:00'
SQL> define end_date = timestamp'2020-02-20 00:00:00'
0 голосов
/ 21 февраля 2020

Относительно вашего второго выпуска с отметками времени; вы делаете

define start_date = timestamp'2020-02-01 00:00:00'
define end_date = timestamp'2020-02-20 00:00:00'

select * from customers where created_time between &start_date and &end_date;

, но обратите внимание, как это выглядит после замены:

old   1: select * from customers where created_time between &start_date and &end_date
new   1: select * from customers where created_time between timestamp'2020-02-01 and timestamp'2020-02-20

Поскольку значение, которое вы задаете, содержит пробел, его необходимо заключить в двойные кавычки :

define start_date = "timestamp '2020-02-01 00:00:00'"
define end_date = "timestamp '2020-02-20 00:00:00'"

select * from customers where created_time between &start_date and &end_date;

, который теперь заменяется на:

old   1: select * from customers where created_time between &start_date and &end_date
new   1: select * from customers where created_time between timestamp '2020-02-01 00:00:00' and timestamp '2020-02-20 00:00:00'

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

define start_date = 'timestamp ''2020-02-01 00:00:00'''
define end_date = 'timestamp ''2020-02-20 00:00:00'''

, который также работает, но в этом случае двойные кавычки немного проще.


Кстати, between включительно, поэтому ваш запрос (когда это будет работать) подберет любые строки точно с 2020-02-20 00:00:00, что, я думаю, не является вашим намерением. Вы можете сделать:

select * from customers
where created_time >= &start_date
and created_time < &end_date;

Если вы намеревались иметь все строки с 2020-02-20, вам потребуется увеличить дату окончания на один день, чтобы их забрать.


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

...