Oracle查询中SAS宏日期的正确语法

时间:2012-03-22 21:06:34

标签: oracle sas

我试图在一夜之间查询过去一周对Oracle数据库的添加,并且需要使用宏来填充日期。如果我硬编码实际日期,我可以运行下面的查询。我在宏变量&sd&ed上尝试过双引号和单引号。请指教。

data _null_;
sd = dhms(today()-7,00,00,00);
ed = dhms(today()-1,23,59,59);
call symput("sd", put(sd, datetime20.));
call symput("ed", put(ed, datetime20.));
run;
%put &sd &ed;

proc sql;
connect to oracle (user=x password=x path=x);
create table weekly_test as
select * from connection to oracle
(select * from x.Estimates
where state_fips_code = '41' 
and altered_date between 
    to_date('&sd','DDMONYYYY:HH24:MI:SS')
    and to_date('&ed','DDMONYYYY:HH24:MI:SS'));
disconnect from oracle;
quit;

错误

  

ORACLE执行错误:ORA-01858:找到了数字所在的非数字字符。

并使用双引号

and altered_date between 
    to_date("&sd",'DDMONYYYY:HH24:MI:SS')
    and to_date("&ed",'DDMONYYYY:HH24:MI:SS'));

此错误

ERROR: ORACLE prepare error: ORA-00904: "  21MAR2012:23:59:59": invalid identifier. SQL
statement: select * from X.Estimates where state_fips_code = '41' and altered_date
between to_date("  15MAR2012:00:00:00",'DDMONYYYY:HH24:MI:SS') and to_date("
21MAR2012:23:59:59",'DDMONYYYY:HH24:MI:SS').

3 个答案:

答案 0 :(得分:2)

最好的办法是在值周围用单引号定义宏变量。事实上,我认为没有必要将其格式化为日期时间文字;只需构造一个普通的ANSI日期字符串(YYYY-MM-DD),你也可以摆脱TO_DATE函数调用。

例如,尝试以下两个陈述:

%let SD=%str(%')%sysfunc( putn( %sysfunc(intnx(day,%sysfunc(today()) ,-7)),yymmdd10.))%str(%'); 
%let ED=%str(%')%sysfunc( putn( %sysfunc(intnx(day,%sysfunc(today()) ,-1)),yymmdd10.))%str(%');

那些将SD定义为今天() - 7和ED定义为今天() - 1(使用纯宏代码而不是数据步骤)。然后,在您的查询中,引用这些宏变量不加引号:

proc sql;
connect to oracle (user=x password=x path=x);
create table weekly_test as
select * from connection to oracle
(select * from x.Estimates
where state_fips_code = '41' 
and altered_date between &sd and &ed
);
disconnect from oracle;
quit;

答案 1 :(得分:0)

非常感谢鲍勃。我尝试了你发布的代码并获得了ORA-01861:literal与格式字符串不匹配。无论如何,你让我思考正确的道路。我刚刚添加了代码,在数据步骤中将单引号放在我的日期周围,并且它有效。对于有类似问题的人,代码如下。

data _null_;
sd = dhms(today()-7,00,00,00);
ed = dhms(today()-1,23,59,59);
call symput('sd',"'"|| trim(left(put(sd, datetime20.)))||"'");
call symput('ed', "'"||trim(left(put(ed, datetime20.)))||"'");
run;
%put &sd &ed;

proc sql;
connect to oracle (user=x password=x path=x);
create table weekly_test as
select * from connection to oracle
(select * from x.Estimates
where state_fips_code = '41' 
and altered_date between 
    to_date(&sd,'DDMONYYYY:HH24:MI:SS')
    and to_date(&ed,'DDMONYYYY:HH24:MI:SS'));
disconnect from oracle;
quit;

答案 2 :(得分:0)

这有效....

%LET SD = %SYSFUNC(intnx(day,"&SYSDATE9"d,-7,b),date9.) ;
%LET ED = %SYSFUNC(intnx(day,"&SYSDATE9"d,-1,b),date9.) ;
%PUT &SD &ED ;

proc sql ;
  connect to oracle (user=x password=x path=x);
  create table weekly_test as
  select * from connection to oracle
  (select * from x.Estimates
   where state_fips_code = '41'
     and altered_date between %BQUOTE('&SD') and %BQUOTE('&ED')
  );
  disconnect from oracle ;
quit ;