将SAS日期写入SQL Server数据库

时间:2018-12-14 14:02:57

标签: sql database sas

如何将SAS日期写入数据库中的Microsoft SQL Server 2016 Date数据类型?

我获得了SAS日期为DataEndDay的SAS数据,我想将其写入数据库。使用以下位(缓冲区只是为了加快测试失败的速度):

libname valu oledb provider=sqloledb schema="dbo" INSERTBUFF=100
        properties=("User ID"="&username." Password="&pw."
                    "data source" = &database. 
                    "initial catalog"=&catalog.);

proc sql noprint;
 insert into valu.Data_upload_from_me
(   <some_columns...>, 
   <more-columns...>
,DataEndDay
)

select 
<some_columns_source...>,
<more-columns_source...>
,DataEndDay 
from work.SAS_data_to_publish 
;quit;

当然,因为SAS日期是数字,所以直接写入将失败。有效的方法是将其硬编码为:

select 
<some_columns_source...>,
<more-columns_source...>
,'2018-12-12' 
from work.SAS_data_to_publish 
;quit;

但是如果我将SAS日期转换为SAS数据步骤中的字符串:

data SAS_data_to_publish ; 
    set SAS_data_to_publish ;
     dataEndday0 = put(DataEndDay, yymmddd10.);
     DataEndDay1 = quote(dataEndday0, "'") ;
run;

并尝试编写其中任何一个,都会出现转换错误:

  

错误:ICommand :: Execute失败。 :从字符串转换日期和/或时间时,转换失败。

当我选择字符串时,它看起来还不错:

proc sql; select DataEndDay1 from SAS_data_to_publish; quit;
  

'2018-12-12'

以前,我已经设法使用类似的技巧来编写dateTimes,该方法有效:

proc format;
    picture sjm
    . = .
    other='%Y-%0m-%0d %0H:%0M:%0S:000' (datatype=datetime)
;run;

data to_be_written; 
    set save.raw_data_to_be_written;
    DataEndDay0 = put(dhms(DataEndDay,0,0,0), sjm. -L);
run;

有人遇到类似的问题吗?如何写日期? 我可能会要求他们将列更改为dateTime……

先谢谢您。

编辑:

我设法开发了一种变通方法,该方法可以工作,但很难看,而且-坦率地说-我不喜欢它。碰巧我的日期在所有行中都是相同的,因此我可以将其关联到宏变量,然后在数据库编写中使用它。

data _NULL_; 
  set SAS_data_to_publish; 
  call symput('foobar', quote( put (DataEndDay , yymmddd10. -L), "'") ) ; 
run;

....
select 
  <some_columns_source...>,
  <more-columns_source...>
 ,&foobar.
from work.SAS_data_to_publish 
;quit;

当然,如果DataEndDay有所不同,这将立即失败,但可能表明Proc SQL的select子句中出现了问题。...

编辑编辑将该问题粘贴到SAS forums

3 个答案:

答案 0 :(得分:1)

通常我只使用PROC APPEND将观察值插入到远程数据库中。

proc append base=valu.Data_upload_from_me force
   data=work.SAS_data_to_publish 
;
run;

确保SAS数据集中的日期变量使用与目标数据库表中相应变量名称相同的数据类型。因此,如果您的MS SQL数据库使用TIMESTAMP字段作为日期值,请确保SAS数据集使用DATETIME值。

如果要使用常量,请确保在SAS代码中使用SAS语法,在任何传递代码中使用MS SQL语法。

data test;
   date = '01JAN2017'd ;
   datetime = '01JAN2017:00:00'dt ;
run;

proc sql ;
  connect to oledb .... ;
  execute (  ... date = '2017-01-01' .... datetime='2017-01-01 00:00' ...)
  by oledb;
quit;

答案 1 :(得分:1)

SAS不能真正正确地支持SQL Server DATE数据类型。我想这是由于它是较新的事实,但是无论出于何种原因,您都必须将数据作为字符串传递。

对于缺少值,重要的是要有一个空白字符串,而不是.字符。此处最简单的解决方法是设置:

options missing=' ';

这将允许您正确插入数据。然后,您可以根据需要将其返回到.。在可能被其他人使用的生产应用程序中,我会考虑暂时保留选项值,然后将其重置为该值,以免造成损害。

答案 2 :(得分:0)

我终于设法解决了这个问题。问题是缺少值。当我将值作为字符串传递到数据库时,解析器将缺少的值解释为实点而不是空字符串。以下作品:

data upload; 
  set upload; 
  CreatedReportdate2 = PUT(CreatedReportdate , yymmddn8.);
run;

libname uplad_db odbc  noprompt = 
        "DRIVER=SQL Server;  server=&server.; Uid=&user.;Pwd=&pw.; DATABASE=&db.;" 
        INSERTBUFF=32767;

proc sql; 
  insert into uplad_db.upload_table 
  (.... ) 
 select 
  case when CreatedReportdate2 ='.'  then '' else CreatedReportdate2 end, 
  ... 
 from upload; 
quit;