我有一个每天运行的查询,需要StartDate
和EndDate
值。 StartDate
和EndDate
曾经是手动输入,但我试图摆脱这种情况并计算要在查询中使用的StartDate
和EndDate
。我已经开发了代码来捕获变量中的StartDate
和EndDate
:
DECLARE
c_DateMask VARCHAR2(20) := 'DD-Mon-YYYY';
c_TimeMask VARCHAR2(20) := 'HH24:MI';
v_Month char(4) := 'Prev';
v_StartDate date;
v_EndDate date;
v_Environment char(7) := 'Prod';
BEGIN
if v_MONTH = 'Prev'
THEN
select TO_DATE ('01-' || TO_CHAR (ADD_MONTHS (SYSDATE, -1),'mon-yyyy')) into v_StartDate from dual;
select Last_day(TO_DATE('01-' || TO_CHAR (ADD_MONTHS (SYSDATE, -1),'mon-yyyy'))) into v_EndDate from dual;
ELSE
select TO_DATE ('01-' || TO_CHAR (ADD_MONTHS (SYSDATE, 0),'mon-yyyy')) into v_StartDate from dual;
CASE
WHEN v_Environment = 'Prod'
THEN
-- Production Environment --
select
to_char(sysdate, 'dd-Mon-yyyy ') ||
case
when to_char(sysdate, 'mi') between 00 and 20
then to_char(sysdate, 'hh24')-1||':58'||':00'
when to_char(sysdate, 'mi') between 21 and 40
then to_char(sysdate, ' hh24')||':18'||':00'
when to_char(sysdate, 'mi') between 41 and 60
then to_char(sysdate, ' hh24')||':38'||':00'
END
into v_EndDate from dual;
WHEN v_Environment = 'OldTest'
THEN
-- Test Environment --
select
to_char(sysdate, 'dd-Mon-yyyy ') ||
case
when to_char(sysdate, 'mi') between 10 and 30
then to_char(sysdate, 'hh24')||':08'||':00'
when to_char(sysdate, 'mi') between 31 and 50
then to_char(sysdate, ' hh24')||':28'||':00'
when to_char(sysdate, 'mi') between 51 and 60
then to_char(sysdate, ' hh24')||':48'||':00'
END
into v_EndDate from dual;
end case;
end if;
然后我想在下面的select语句中使用变量:
-----------------
/* KPI Figures */
-----------------
SELECT
SysDate as RunTime
, v_StartDate
, v_EndDate
, TTM_OFF_CONTRIBUTOR
, SUM(NVL(TTM_PER_OFF_FEE,0)) Fees
FROM [Table]
Where
TTM_PROCESSED_DATE >= v_StartDate
AND TTM_PROCESSED_DATE <= v_EndDate
group by SysDate, v_StartDate, v_EndDate, TTM_OFF_CONTRIBUTOR
END;
直到我尝试在KPI数据查询中使用变量值时,一切正常。我错过了什么?
更新
关于Phil's answer:我试过但它没有用,我收到以下错误:
PLS-00428: an INTO clause is expected in this SELECT statement.
我确信我昨天看到了另一个回复,现在已经消失了,可以为变量或其他东西分配多个值。
这就是我需要的,我该怎么做?
答案 0 :(得分:1)
变量v_StartDate和v_EndDate仅在声明它们的PL / SQL块中的范围内。看起来您正在尝试在单独的查询中使用它们。为此,您需要在PL / SQL块之外创建SQL Developer绑定变量,如下所示:
var v_start_date varchar2(11)
var v_end_date varchar2(11)
然后在PL / SQL块和SQL查询中将它们作为绑定变量引用:
declare
...
begin
....
:v_start_date := '01-' || TO_CHAR (ADD_MONTHS (SYSDATE, -1), 'mon-yyyy');
:v_end_date := TO_CHAR(Last_day(TO_DATE('01-'
|| TO_CHAR (ADD_MONTHS (SYSDATE, -1),'mon-yyyy'))));
-- (NB No need to select from dual)
...
end;
SQL:
...
Where
TTM_PROCESSED_DATE >= TO_DATE(:v_StartDate)
AND TTM_PROCESSED_DATE <= TO_DATE(:v_EndDate)
请注意,这些变量不能使用DATE类型声明,因此需要将它们转换回查询中的日期(使用正确的格式掩码)。
答案 1 :(得分:1)
我建议你将startdate / enddate包装在两个函数(存储过程)中
create or replace function get_startdate(p_month in varchar2, p_env in varchar2)
return date
is
l_return date;
begin
... logic goes here ...
return l_return;
end;
类似于enddate。
然后在查询中使用这些函数:
SELECT
SysDate as RunTime
, get_startdate('Prev', 'Prod')
, get_enddate('Prev', 'Prod')
, TTM_OFF_CONTRIBUTOR
, SUM(NVL(TTM_PER_OFF_FEE,0)) Fees
FROM [Table]
Where
TTM_PROCESSED_DATE >= get_startdate('Prev', 'Prod')
AND TTM_PROCESSED_DATE <= get_enddate('Prev', 'Prod')
group by SysDate, get_startdate('Prev', 'Prod'), get_enddate('Prev', 'Prod'), TTM_OFF_CONTRIBUTOR
旁注:请考虑更简洁的版本来确定一个月的第一天和最后一天。您也可以在不使用SELECT INTO的情况下为变量赋值,例如
startdate := trunc(sysdate, 'MM'); -- first day of current month
enddate := last_day(trunc(sysdate, 'MM')); -- last day of current month
要计算小时数,您可以添加/减去几分钟,这比您执行的所有to_date / to_char转换更具可读性,例如
enddate := trunc(sysdate, 'HH24');
case
when to_char(sysdate, 'mi') between 00 and 20 then enddate := enddate - 2/(24*60);
when to_char(sysdate, 'mi') between 21 and 40 then enddate := enddate + 18/(24*60);
when to_char(sysdate, 'mi') between 41 and 60 then enddate := enddate + 38/(24*60);
end;
祝你好运,马丁
答案 2 :(得分:0)
我认为问题出在您的查询和别名上。尝试
SELECT
SysDate as RunTime
, v_StartDate AS StartDate
, v_EndDate AS EndDate
, TTM_OFF_CONTRIBUTOR
, SUM(NVL(TTM_PER_OFF_FEE,0)) Fees
FROM [Table]
Where
TTM_PROCESSED_DATE >= v_StartDate
AND TTM_PROCESSED_DATE <= v_EndDate
group by RunTime, StartDate, EndDate, TTM_OFF_CONTRIBUTOR