在Oracle SQL Developer中使用变量作为日期范围

时间:2017-07-26 14:08:39

标签: sql oracle

如何更改下面的代码以获取日期范围而不是一天?代码1工作,代码2不工作(我正在使用Oracle SQl Developer)

代码1

DEFINE date1 = '01-JUN-17' 
SELECT * 
FROM   op_all_appointments OP 
WHERE  OP.ATTENDANCE_DTTM = '&&date1'

我尝试了以下,但它不起作用?它仅返回2017年6月1日的数据

代码2

DEFINE date1 between '01-JAN-17' and '30-JUN-17'
SELECT * 
FROM   op_all_appointments OP 
WHERE  OP.ATTENDANCE_DTTM = '&&date1'

谢谢

3 个答案:

答案 0 :(得分:1)

如果您仔细查看输出结果,那么对于您的第二个define,您会看到:

SP2-0135: symbol date1 between '01-jan-17' and '30-jun-17' is UNDEFINED

这样命令不会被操作,您的第一个定义仍然有效,因此您仍然可以看到第一个单日期的数据。

你可以一起去:

DEFINE date1 = between '01-JAN-17' and '30-JUN-17'

添加了导致该SP错误的缺失=;你的查询然后改为:

...
WHERE  OP.ATTENDANCE_DTTM = &&date1

没有等号,并且替换变量周围没有引号。

但是因为这依赖于隐式转换和你的NLS设置,所以你真的需要这样做:

DEFINE date1 = between to_date('01-JAN-17', 'DD-MON-RR', 'NLS_DATE_LANGUAGE=''ENGLISH''') and to_date('30-JUN-17', 'DD-MON-RR', 'NLS_DATE_LANGUAGE=''ENGLISH''')

或更简单地使用日期文字:

DEFINE date1 = between date '2017-01-01' and date '2017-06-30'

使用两个变量可能更简洁:

DEFINE date1 = 2017-01-01
DEFINE date2 = 2017-06-30

...
WHERE  OP.ATTENDANCE_DTTM between date '&&date1' and date '&&date2'

值得注意的是,如果您的专栏有午夜以外的时间 - 正如DTTM建议的那样 - 您将错过该范围最后一天的任何数据,即2017-06-30午夜之后的任何数据。一般情况下,这通常更安全:

DEFINE date1 = 2017-01-01
DEFINE date2 = 2017-07-01

...
WHERE  OP.ATTENDANCE_DTTM >= date '&&date1'
AND    OP.ATTENDANCE_DTTM < date '&&date2'

如果您真的想要,可以在单个替换变量中进行相同的范围比较。

您可能还想考虑使用绑定变量而不是替换变量 - 尽管那时您不能使用日期文字,但仍应坚持使用与语言无关的格式并使用带有显式格式掩码的to_date(); e.g:

var date1 varchar2(10);
var date2 varchar2(10);
exec :date1 := '2017-01-01';
exec :date2 := '2017-07-01';

...
WHERE  OP.ATTENDANCE_DTTM >= to_date(:date1, 'YYYY-MM-DD')
AND    OP.ATTENDANCE_DTTM < to_date(:date2, 'YYYY-MM-DD')

...你不能在一个变量中做(无论如何都使用普通的SQL)。

答案 1 :(得分:0)

这就是你应该做的事情

SELECT * 
FROM   op_all_appointments OP 
WHERE  OP.ATTENDANCE_DTTM between date '2017-01-01' and date '2017-06-30'

如果您想使用CTE

WITH data AS
    (SELECT DATE '2017-01-01' date1,
            DATE '2017-06-30' date2
    FROM dual
    )
SELECT *
FROM dual,
    data
WHERE sysdate BETWEEN data.date1 AND data.date2;

答案 2 :(得分:-1)

DEFINE date1 = 'between ''01-JAN-17'' and ''30-JUN-17'''
SELECT * 
FROM   op_all_appointments OP 
WHERE  OP.ATTENDANCE_DTTM  '&&date1'

或(尝试两者)

DEFINE date1 = 'between ''01-JAN-17'' and ''30-JUN-17'''
SELECT * 
FROM   op_all_appointments OP 
WHERE  OP.ATTENDANCE_DTTM  &&date1