SAS Date Formats Incompatible with SQL Server Date

前端 未结 3 1094
清酒与你
清酒与你 2021-01-27 14:13

I\'m fairly new to SAS and recently we migrated some of our SAS datasets to a SQL Server table but we are still using SAS to do our analysis. I have run into a problem when SAS

相关标签:
3条回答
  • 2021-01-27 14:42

    SAS stores and uses dats as numeric variables. If you had not identified the column srv_edt as a date column when you migrated the database to SQL server everything would now process correctly.

    I assume that currently and into the future you will just store the tables in SQL server and all the processing will be in SAS.

    You have a few options.

    1/ re-migrate the SAS tables but identify all the date, time and datetime columns as just numeric. They all can be stored as 8 byte floating point. The date variables may also be stored (in SQL Server) is long integers. The code would need a slight change so that the macro variables would be numeric.

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

    2/ keep the date, time, and datetime variables in SQL Server format and change the data type of the column when using the data. (Note the reverse will be necessary on output). SQL Server will present the date variables as strings (character) so that your expression above will need to be -

    %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;
    

    That to make sure when using SAS processing the type is numeric which is what the input function will do.

    3/ keep the date, time, and datetime variables in SQL Server format and change your working to accommodate that fact. That is comparisions will be using character data and output will need to produce characters. SQL Server will present the date variables as strings (character) so that your expression above will need to be -

    %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");`
    

    Note double quotes " " required surrounding macro variables as this comparison is numeric.

    0 讨论(0)
  • 2021-01-27 14:53

    SQL Server introduced new date and datetime types in SQL Server 2008 (prior, there was only one type for all date/datetime variables). This usage note suggests that you need to install a new set of SQL Server ODBC drivers for SAS to read the date variables correctly. It suggests this would be installed normally if you have SQL Server 2008 Tools (like SQL Server Management Studio) on the machine that is doing the ODBC connection, but you might have multiple drivers installed and need to ensure you are using the right one.

    That said, it is not a bad idea to use pass-through SQL to pull the data across, as that might make it easier to do the pull (as you don't have to worry as much about the ODBC driver). The generalized pass through connection string is

    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;
    

    From your question it sounds like you're more of a SQL person and can then construct the query yourself; if you are not, either edit the question to include that request (and then either a SQL Server person or myself will answer). You can use SAS macro variables in that query (ie, to pass the current date) as long as you do not enclose them or the query in single quotes.

    0 讨论(0)
  • 2021-01-27 15:02

    If the column srv_edt is showing up in your SAS data set as a character variable, that means it is really a character variable or it's been converted to character by the ODBC driver you are using (possibly because the native data type is not supported by ODBC).

    You'd be better off changing this to a PROC SQL pass-thru query if possible. You would need to figure out the native syntax that corresponds to the SAS intnx function (and I cannot help you there). As written, the entire table must be read (because you are using a SAS function). If you use a pass-thru query, SAS will only receive the rows that match the whee clause.

    There might be setting in the ODBC driver that control this behavior. I'll add the ODBC and SQL Server tags to your question; you may get more "hits".

    0 讨论(0)
提交回复
热议问题