如何提取SAS PROC SQL passthru中按日期过滤的记录,但日期是字符串格式?
我试图从日期范围中提取数据(由null步骤中定义的start_date和end_date变量设置) 通常,我会使用passthru PROC SQL执行此操作,如下所示:如何提取SAS PROC SQL passthru中按日期过滤的记录,但日期是字符串格式?,sql,oracle,datetime,sas,type-conversion,Sql,Oracle,Datetime,Sas,Type Conversion,我试图从日期范围中提取数据(由null步骤中定义的start_date和end_date变量设置) 通常,我会使用passthru PROC SQL执行此操作,如下所示: PROC SQL; CONNECT TO ORACLE AS xxxxx (AUTHDOMAIN="xxxxx" PATH=xxxxx preserve_comments); CREATE TABLE work.new_data AS SELECT * FR
PROC SQL;
CONNECT TO ORACLE AS xxxxx (AUTHDOMAIN="xxxxx" PATH=xxxxx preserve_comments);
CREATE TABLE
work.new_data AS
SELECT
*
FROM
CONNECTION TO xxxxx (SELECT /*+parallel(16)*/ var1, var2, var3
FROM
oracle_data
WHERE date >= &start_date. AND date <= &end_date.);
DISCONNECT FROM xxxxx;
QUIT;
是否可以在passthru阶段将字符串解释为datetime并将其用于过滤?或者有没有其他方法比将所有内容或直接执行数据步骤拉入oracle数据更有效?当您将日期条件传递给oracle时,服务器端日期文本的一个构造实际上是
DATE 'yyyy-mm-dd'
对于使用日期文字的Oracle源代码填充宏变量的任务,您需要解释SAS datetime字符串,检索日期部分并将该值呈现为Oracle日期文字
例如:
options nosource;
data have;
length task start_date_string end_date_string $19;
input task start_date_string& end_date_string&;
datalines;
task1 31/01/2020 08:09:10 02/02/2020 11:00:00
task2 15/03/2019 02:00:00 19/03/2019 23:00:00
;
proc sql noprint;
select start_date_string, end_date_string into :start_date, :end_date
from have where task='task1';
%put &=start_date;
%put &=end_date;
%let s_datepart_val = %sysfunc(inputn(&start_date,ddmmyy10.));
%let e_datepart_val = %sysfunc(inputn(&end_date,ddmmyy10.));
%put &=s_datepart_val;
%put &=e_datepart_val;
%let ora_start_literal = DATE %str(%')%sysfunc(putn(&s_datepart_val,yymmdd10.))%str(%');
%let ora_end_literal = DATE %str(%')%sysfunc(putn(&e_datepart_val,yymmdd10.))%str(%');
%put &=ora_start_literal;
%put &=ora_end_literal;
---------- LOG ----------
START_DATE=31/01/2020 08:09:10
END_DATE=02/02/2020 11:00:00
S_DATEPART_VAL=21945
E_DATEPART_VAL=21947
ORA_START_LITERAL=DATE '2020-01-31'
ORA_END_LITERAL=DATE '2020-02-02'
以及填充包含日期文字的宏变量的替代方法
proc sql noprint;
select
'DATE ' || quote(put(input(start_date_string,ddmmyy10.),yymmdd10.),"'")
, 'DATE ' || quote(put(input( end_date_string,ddmmyy10.),yymmdd10.),"'")
into
:ora_start_literal
, :ora_end_literal
from
have
where
task = 'task2'
;
%put &=ora_start_literal;
%put &=ora_end_literal;
---------- LOG ----------
ORA_START_LITERAL=DATE '2019-03-15'
ORA_END_LITERAL=DATE '2019-03-19'
传递将利用“文本”宏变量
WHERE date >= &ora_start_literal. AND date <= &ora_end_literal;
WHERE date>=&ora\u start\u literal。日期我们使用格式来简化流程
创建一个名为oracledt.
的格式,该格式接受日期时间值并将其转换为'mm/dd/yy hh:mm:ss'
(包括引号)格式
创建一个名为my_datetime
的宏变量,该变量包含使用上述自定义格式格式化的当前日期时间:
%let my_datetime = %sysfunc(datetime(), oracledt.);
%put &=my_datetime;
输出:
MY_DATETIME='02/28/20 09:13:17'
本白皮书介绍了构建自定义格式时可以使用的各种值:
如果您所使用的格式是'yyyy-mm-dd hh:mm:ss'
,那么您的格式定义将如下所示:''%Y-%0m-%0d%0H:%0m:%0S'
正如Richard所演示的,将日期/日期时间存储为SAS dates/datetime值是一种很好的做法,这样您就可以使用它们,然后创建用于passthrough语句的附加变量 您是否尝试过OracleTO_DATE()
函数?我过去曾尝试过使用该函数,但无法使其正常工作。我收到了这个错误消息。。。错误:ORACLE执行错误:ORA-12801:并行查询服务器P006中发出错误信号,实例XXXXXXXXXXXXX(1)ORA-01843:不是有效月份。此时,我将代码行更改为:WHERE to_DATE(DATE,'DD-MON-YYYY')>=&start_DATE.);您希望传递的&start\u date
和&end\u date
是完整的日期时间还是日期时间的日期部分?@Richard我只希望它是日期。我希望在传递过程中完全忽略时间部分,但将其保留为单独的时间变量。但我现在不太担心这个问题,只是为了得到一些可以在传递过程中将字符串解释为日期的东西。我认为我没有清楚地解释我的问题。日期字符串存储在oracle数据集本身中(在我的示例中,变量名为“date”)。因此,我有数百万条记录,其中日期存储为字符串,我有一个开始和结束日期变量,我已经将其转换为oracle格式,并与之进行比较。我使用SQLPassthru提取数据的速度要比使用数据步骤快得多,如果日期是实际的日期格式,这将非常简单。但不幸的是,我无法控制这个数据集,也无法修改它。
%let my_datetime = %sysfunc(datetime(), oracledt.);
%put &=my_datetime;
MY_DATETIME='02/28/20 09:13:17'