0

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

当 SAS 尝试比较日期时,我收到以下错误:错误: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。

任何帮助或建议将不胜感激。

4

3 回答 3

1

SAS 存储和使用数据作为数值变量。如果您在将数据库迁移到 SQL Server 时没有将 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");`

请注意双引号“”需要围绕宏变量,因为此比较是数字的。

于 2013-05-24T00:11:36.870 回答
0

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

也就是说,使用传递 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 宏变量(即传递当前日期),只要您不将它们或查询用单引号括起来。

于 2013-05-24T14:06:36.093 回答
0

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

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

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

于 2013-05-23T23:42:03.423 回答