SAS日期格式与SQL Server日期不兼容

时间:2013-05-23 22:00:56

标签: sql-server-2008-r2 odbc sas

我是SAS的新手,最近我们将一些SAS数据集迁移到SQL Server表,但我们仍在使用SAS进行分析。当SAS尝试从SQL Server表中引入数据并让SAS检查srv_edt日期是否在dos_beg_dt1和dos_end_dt1的SAS日期之间时,我遇到了一个问题。

当SAS尝试比较日期时,我得到一个错误:ERROR:WHERE子句操作符需要兼容的变量。

dos_beg_dt1,dos_end_dt1和srv_edt(SQL日期格式)全部以“yyyy-mm-dd”的格式“显示”。当我将srv_edt带入SAS表时,它将其作为字符日期读取。所以我尝试更改日期的格式然后我会得到一个错误:错误:变量srv_edt已被定义为字符和数字。我似乎无法找到正确的格式或函数来让SAS进行比较,以查看srv_edt(SQL)是否在dos_beg_dt1和dos_end_dt1 SAS日期之间。

我使用的代码如下:

libname sql odbc dsn=test schema=dbo;

%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning),yymmdd10.);
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end),yymmdd10.);

data sample;
set sql.table;
where &dos_beg_dt1 <= srv_edt <= &dos_end_dt1;
run;

作为参考,我使用SAS 9.2通过odbc连接到SQL Server 2008。

非常感谢任何帮助或建议。

3 个答案:

答案 0 :(得分:1)

SAS存储并使用dats作为数字变量。如果在将数据库迁移到SQL服务器时未将列srv_edt标识为日期列,则现在可以正常处理所有内容。

我假设当前和将来您只需将表存储在SQL Server中,所有处理都将在SAS中进行。

您有几个选择。

1 /重新迁移SAS表,但将所有日期,时间和日期时间列标识为仅数字。它们都可以存储为8字节浮点。日期变量也可以存储(在SQL Server中)是长整数。代码需要稍微改变,以便宏变量是数字。

%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning));
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end));

2 /以SQL Server格式保留日期,时间和日期时间变量,并在使用数据时更改列的数据类型。 (注意输出时需要反向)。 SQL Server将日期变量显示为字符串(字符),以便上面的表达式需要 -

%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning));
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end));

data sample;
set sql.table;

where &dos_beg_dt1 <= (input(srv_edt, yymmdd10.0))  <= &dos_end_dt1;

为了确保在使用SAS处理时,类型是数字,这是输入函数将执行的操作。

3 /保留SQL Server格式的日期,时间和日期时间变量,并更改您的工作以适应这一事实。那就是比较将使用字符数据和输出将需要产生的字符。 SQL Server将日期变量显示为字符串(字符),以便上面的表达式需要 -

%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning), yymmdd10.);
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end), yymmdd10.);

data sample;
set sql.table;

where ("&dos_beg_dt1" <= srv_edt) and
   (srv_edt <= "&dos_end_dt1");`

注意双引号“”需要包围宏变量 比较是数字。

答案 1 :(得分:0)

如果列 srv_edt 在您的SAS数据集中显示为字符变量,这意味着它实际上是一个字符变量,或者它已被您正在使用的ODBC驱动程序转换为字符(可能因为ODBC不支持本机数据类型。

如果可能的话,最好将其更改为PROC SQL pass-thru查询。您需要找出与SAS intnx函数对应的本机语法(我无法帮助您)。如上所述,必须读取整个表(因为您使用的是SAS功能)。如果使用pass-thru查询,SAS将只接收与whee子句匹配的行。

ODBC驱动程序中可能存在控制此行为的设置。我将ODBC和SQL Server标记添加到您的问题中;你可能会得到更多“点击”。

答案 2 :(得分:0)

SQL Server在SQL Server 2008中引入了新的日期和日期时间类型(之前,所有日期/日期时间变量只有一种类型)。 This usage note建议您需要为SAS安装一组新的SQL Server ODBC驱动程序才能正确读取日期变量。如果您在执行ODBC连接的计算机上安装了SQL Server 2008工具(如SQL Server Management Studio),则表明这将正常安装,但您可能安装了多个驱动程序,并且需要确保使用正确的驱动程序。 / p>

也就是说,使用传递SQL来提取数据并不是一个坏主意,因为这可能会更容易实现拉动(因为您不必担心ODBC驱动程序) 。广义传递连接字符串是

proc sql;
   connect to odbc (required="driver=sql server native client 10.0;
Server=server;Trusted_Connection=Yes;DATABASE=database;");
  create table X as select * from connection to odbc(... sql server native code here ...);
quit;

从你的问题来看,听起来你更像是一个SQL人,然后可以自己构建查询;如果不是,请编辑问题以包含该请求(然后SQL Server人员或我自己将回答)。您可以在该查询中使用SAS宏变量(即,传递当前日期),只要您不将它们或查询用单引号括起来。