【问题标题】:Convert date type in do loop?在do循环中转换日期类型?
【发布时间】:2021-06-20 18:18:28
【问题描述】:

我正在尝试编写一个 SAS 宏,我需要在其中循环一个日期范围并在 PROC SQL 步骤的 where 条件中使用日期。同时,我必须在 PROC SQL 步骤中使用路径。

table1 中的 start_date 字段为日期时间格式,即 '15mar2021:00:00:00'。

我尝试将 where 子句中 &i 的日期格式转换为与 table1 中 start_date 字段的格式匹配。我尝试了以下查询,但收到此错误:错误:CLI 描述错误:[Oracle][ODBC][Ora]ORA-00923:FROM 关键字未在预期位置找到

%macro date_delq(start,end);
%let start=%sysfunc(inputn(&start,anydtdte9.));
%let end=%sysfunc(inputn(&end,anydtdte9.));
%do i= &start %to &end;
  proc sql;
     connect using admin as server;
          create table delq_&i as
                select * from connection to server(
     select *
     from table1
     where start_date= CONVERT(datetime,&i,106)
);
run;
%end;
%mend date_delq;
%date_delq(01mar2021,02mar2021);

感谢您的帮助!

【问题讨论】:

  • CONVERT(datetime,&i,106) 在我看来就像 SQL Server 语法。如果 startdate 应该是 DATE 列(DATE 是 Oracle 对日期时间的不恰当名称),那么它应该足以满足 select * from table1 where start_date = &i。如果尽管它的名字 start_date 有一个你想去掉的时间部分,你可以通过应用 TRUNC: where trunc(start_date) = &i 将它截断到日期。
  • 如果您的变量 &i 是字符串而不是日期或日期时间,则将其转换为 TO_DATE。确保指定 &i 中使用的格式,例如to_date(&i, 'yyyy-mm-dd') 如果 &i 是包含四位数年份、破折号、两位数月份、破折号和两位数日期的字符串。

标签: oracle sas oracle-sqldeveloper sas-macro


【解决方案1】:

我不使用 SAS。

但是,看起来您使用的是 Oracle 数据库,我假设 start_date 列的数据类型是 date(应该是这样;如果是 varchar2,表设计者犯了一个巨大的错误)。

在 Oracle 中,日期以 内部格式 存储,我们人类无法读取。这就是为什么我们使用函数(如TO_CHAR)或更改会话来设置NLS_DATE_FORMAT 或在我们的前端应用程序中应用所需的格式掩码以根据需要显示那些date 数据类型值。

因此,从例如“转换”列内容没有用处。 15Mar2021 00:00:0021mar2021 因为您不会实现任何目标,数据仍将以相同的内部格式存储,并且 - 除非您对呈现这些值采取措施,你不会看到任何区别。

您可以/应该做的是使用所需的格式掩码,例如

SQL> with test (start_date) as
  2    (select to_date('24.03.2021 08:14:23', 'dd.mm.yyyy hh24:mi:ss') from dual)
  3  select to_char(start_date, 'fmdd Month yyyy, hh24:mi') example_1,
  4         to_char(start_date, 'Mon dd, yyyy') example_2,
  5         to_char(start_date, 'hh24:mi:ss') example_3
  6  from test;

EXAMPLE_1           EXAMPLE_2    EXAMPLE_
------------------- ------------ --------
24 March 2021, 8:14 Mar 24, 2021 08:14:23

SQL>

SQL> alter session set nls_date_format = 'dd Mon yyyy, hh24:mi';

Session altered.

SQL> select sysdate from dual;

SYSDATE
------------------
24 Mar 2021, 08:16

SQL>

等等。

【讨论】:

  • 实际上,Oracle 确实使 内部日期结构 可供我们人类使用和阅读。除了解决一点好奇心之外,这并不是说它对任何事情都非常有用。要查看它,请使用转储功能;所以例如" select sysdate, dump(sysdate) "internal structure" from dual;
猜你喜欢
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
相关资源
最近更新 更多