SAS ODBC с таблицей в локальной библиотеке - PullRequest
1 голос
/ 10 января 2012

Что делать, если я запускаю таблицу создания с использованием ODBC в SAS.Эта таблица теперь сохраняется в моей постоянной библиотеке в SAS.Теперь я хочу взять эту таблицу, потому что она искала миллионы строк данных, и после того, как я закончу, я отфильтровал элементы, и в этой таблице 664 различных строки sys_id.и теперь мне нужно вытащить все sys_id в ODBC, которые совпадают.Я ищу, чтобы соответствовать любой sys_id, который имеет медицинские претензии в течение определенного периода времени.Я знаю, как выполнить часть запроса, но не уверен, как соединить таблицу в моей локальной библиотеке и ODBC одновременно.Я пытался сделать кучу разных вещей, как libname test.sys_id пропущено присоединиться к galaxy.sys_id, но ничего не работает.Я также попытался прочитать, если это вообще возможно.Я думаю, что это может быть невозможно.Странно то, что я могу сделать это в Access, взяв созданную мной таблицу и соединив ее с таблицей на сервере, поэтому я думаю, что это возможно с помощью SAS.Я не могу запустить эту программу в Access.Недостаточно памяти.Любой совет?

Ниже приведен код, который я пробовал до сих пор:

 /***the table is successfully created and saved to my libname readm*****/
proc sql; 
 connect to odbc (dsn=server user=user password=password); 
 create table readm.test as 
 select * from connection to odbc 
  (select distinct server.sys_id, server.clm_aud_nbr, 
                   server.fst_srvc_dt, server.proc_cd 
   from server.table 
   where server.proc_cd in ('27130', '27132', '27447') 
         and server.fst_srvc_dt between (&startdt) and (&enddt))
 order by server.sys_id, server.fst_srvc_dt; 
 disconnect from odbc; 
quit; 

proc sql; 
 connect to odbc (dsn=server user=user password=password); 
 create table readm.test2 as 
 select * from connection to odbc 
  (select libname readm.test, 
      server.mem_sys_id, server.clm_aud_nbr, server.fst_srvc_dt, 
      server.proc_cd 
   from libname readm.test 
   left outer join server.table on 
    readm.test_sys_id = server.table_sys_id 
   where server.fst_srvc_dt 
    between (&startdt) ad (&enddt)) 
  disconnect from odbc; 
  quit; 

Ответы [ 2 ]

1 голос
/ 11 января 2012

Отличный вопрос ... У нас есть макрос, который мы используем здесь, чтобы обойти эту проблему, поскольку у нас нет возможности загружать файлы на сервер ODBC или создавать временные таблицы и т. Д. ... Простой пример использования макрос это:

proc sql noprint;
  create table xx as
  select * 
  from sashelp.class
  where name in (  %ds2list(iDs=sashelp.class, iField=name, iQuote=1, iDelimiter=%str(,))  )
  ;
quit;

Хотя в приведенном выше примере не используется проход ODBC, с ним все будет в порядке. И если OPTION MPRINT включен, то журнал покажет что-то вроде следующего:

121  proc sql noprint;
122    create table xx as
123    select *
124    from sashelp.class
125    where name in (%ds2list(iDs=sashelp.class,iField=name,iQuote=1, iDelimiter=%str(,)))
MPRINT(DS2LIST):  'Alfred'
MPRINT(DS2LIST):  ,'Alice'
MPRINT(DS2LIST):  ,'Barbara'
MPRINT(DS2LIST):  ,'Carol'
MPRINT(DS2LIST):  ,'Henry'
MPRINT(DS2LIST):  ,'James'
MPRINT(DS2LIST):  ,'Jane'
MPRINT(DS2LIST):  ,'Janet'
MPRINT(DS2LIST):  ,'Jeffrey'
MPRINT(DS2LIST):  ,'John'
MPRINT(DS2LIST):  ,'Joyce'
MPRINT(DS2LIST):  ,'Judy'
MPRINT(DS2LIST):  ,'Louise'
MPRINT(DS2LIST):  ,'Mary'
MPRINT(DS2LIST):  ,'Philip'
MPRINT(DS2LIST):  ,'Robert'
MPRINT(DS2LIST):  ,'Ronald'
MPRINT(DS2LIST):  ,'Thomas'
MPRINT(DS2LIST):  ,'William'
126    ;
127  quit;
NOTE: Table WORK.XX created, with 19 rows and 5 columns.
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.15 seconds
      cpu time            0.06 seconds

Как вы можете видеть, он создал список имен через запятую и процитировал имена. Вы можете изменить разделитель, а также кавычки, которые используются. Количество элементов в списке не ограничено (мы использовали его в списках с количеством элементов более 100 тыс.), Поскольку список «потоковый» с помощью макроса, а не хранится в макропеременной. Единственное ограничение по размеру - это ограничение, определяемое размером запроса ODBC-сервера. Код к макросу немного страшен, но поместите его в папку автоматического вызова макросов и забудьте об этом.

Код макроса ниже:

/***************************************************************************
**  PROGRAM: MACRO.DS2LIST.SAS
**
**  UTILITY PROGRAM THAT DETECTS RETURNS A LIST OF FIELD VALUES FROM A 
**  DATASET IN DELIMITED FORMAT.
**
**  PARAMETERS:
**  iDs       : THE LIBNAME.DATASET NAME THAT YOU WANT TO CHECK.
**  iField    : THE FIELD THAT CONTAINS THE VALUES YOU WANT RETURNED IN A 
**              DELIMITED FORMAT.
**  iDelimiter: DEFAULT IS A COMMA. THE DELIMITER TO USE FOR THE RETURNED LIST.
**  iDsOptions: ANY STANDARD DATASET OPTIONS THAT YOU WOULD LIKE TO APPLY SUCH 
**              AS A WHERE STATEMENT.
**  iQuote    : (0=NO,1=YES). DEFAULT=0/NO. DETERMINES WHETHER THE RETURNED 
**              LIST IS QUOTED OR NOT.
**  iQuoteChar: (SINGLE,DOUBLE) DEFAULT=SINGLE. SPECIFIES WHETHER SINGLE0.
**              OR DOUBLE QUOTES ARE USED WHEN QUOTING THE RETURNED LIST
**
*****************************************************************************
** VERSION:
**
**  1.0 ON: 05-FEB-2007  BY: ROBERT PENRIDGE
**      CREATED.
**  1.1 ON: 29-APR-2008  BY: ROBERT PENRIDGE
**      PUT IN ERROR CHECKING.
**      ADDED AUTOMATIC TYPE DETECTION
**      FIXED OUTPUT.
**  1.2 ON: 23-APR-2010  BY: ROBERT PENRIDGE
**      CHANGED SO THAT OUTPUT SPOOLED. ALLOWS MACRO TO RETURN OUTPUT > 64KB.
**  1.3 ON: 12-MAY-2010  BY: ROBERT PENRIDGE
**      ADDED PARAMETER CHECK AFTER I SPENT 10 MINUTES TRYING TO FIGURE OUT
**      WHY MY CODE WAS RETURNING AN ERROR. DUH!
**  1.4 ON: 26-MAY-2010  BY: KN
**      ADDED IQUOTE.
**  1.5 ON: 08-JUN-2010  BY: RP
**      FIXED DCLOSE SO DATASET WOULD CLOSE PROPERLY AND RELEASE LOCK.
**  1.6 ON: 16-JUN-2010  BY: RP
**      ADDED IQUOTECHAR PARAMETER
**  1.7 ON: 20-JUL-2010  BY: RP
**      UNQUOTED RETURNED VALUES  
**  1.8 ON: 11-OCT-2010  BY: KN
**      MODIFIED TO ALLOW BLANK CHARACTER VALUES AND ALSO REMOVED TRAILING
**      MODIFIED TO ALLOW PARENTHESES IN CHARACTER VALUES
*****************************************************************************/

%macro ds2list(iDs=, iField=, iDsOptions=, iDelimiter=%str(,), iQuote=0, iQuoteChar=single);
  %local dsid pos rc result cnt quotechar;

  %let result=;
  %let cnt=0;

  %if &iQuote %then %do;
    %if "%upcase(&iQuoteChar)" eq "DOUBLE" %then %do;
      %let quotechar = %nrstr(%");
    %end;
    %else %if "%upcase(&iQuoteChar)" eq "SINGLE" %then %do;
      %let quotechar = %nrstr(%');
    %end;
    %else %do;
      %let quotechar = %nrstr(%");
      %put WARNING: MACRO.DS2LIST.SAS: PARAMETER IQUOTECHAR INCORRECT. DEFAULTED TO DOUBLE;
    %end;
  %end;
  %else %do;
    %let quotechar = ;
  %end;

  /*
  ** ENSURE ALL THE REQUIRED PARAMETERS WERE PASSED IN.
  */
  %if "&iDs" ne "" and "&iField" ne "" %then %do;

    %let dsid=%sysfunc(open(&iDs(&iDsOptions),i));
    %if &dsid %then %do;

      %let pos=%sysfunc(varnum(&dsid,&iField));
      %if &pos %then %do;

        %let rc=%sysfunc(fetch(&dsid));
        %do %while (&rc eq 0);

          %if "%sysfunc(vartype(&dsid,&pos))" = "C" %then %do;
            %let value = %qsysfunc(getvarc(&dsid,&pos));
            %if "%trim(&value)" ne "" %then %do;
              %let value = %qsysfunc(cats(%nrstr(&value)));
            %end;
          %end;
          %else %do;
            %let value = %sysfunc(getvarn(&dsid,&pos));
          %end;

          /* WHITESPACE/CARRIAGE RETURNS REMOVED IN THE BELOW LINE */
          /* TO ENSURE NO WHITESPACE IS RETURNED IN THE OUTPUT.    */
          %if &cnt ne 0 %then %do;%unquote(&iDelimiter)%end;%unquote(&quotechar&value&quotechar.)

          %let cnt = %eval(&cnt + 1);
          %let rc  = %sysfunc(fetch(&dsid));
        %end;

        %if &rc ne -1 %then %do;
          %put WARNING: MACRO.DS2LIST.SAS: %sysfunc(sysmsg());
        %end;

      %end;
      %else %do;
        %put ERROR: MACRO.DS2LIST.SAS: FIELD &iField NOT FOUND IN DATASET %upcase(&iDs).;
      %end;
    %end;
    %else %do;
      %put ERROR: MACRO.DS2LIST.SAS: DATASET %upcase(&iDs) COULD NOT BE OPENED.;
    %end;

    %let rc=%sysfunc(close(&dsid));

  %end;
  %else %do;
    %put ERROR: MACRO.DS2LIST.SAS: YOU MUST SPECIFY BOTH THE IDS AND IFIELD PARAMETERS TO CALL THIS MACRO.;
  %end;

%mend;
0 голосов
/ 10 января 2012

Поскольку вы можете делать все, что хотите, КРОМЕ присоединиться к таблице на локальном компьютере с данными ODBC, может показаться, что подзапрос сработает.

Как только ваш подзапрос получает 664 sys_ids, это небольшое подмножество объединяется с данными ODBC, чтобы возвращать только нужные записи ... что не должно быть неизмеримо большим количеством записей

Ссылки на подзапрос Proc SQL Здесь и Здесь

Если вы знакомы с объектом HASH в SAS ... это аналогично. Или ранее, используя Proc SQL для создания макропеременной со всеми sys_ids, разделенными запятыми и используемыми с оператором IN на шаге Data (как то, что @Rob Penridge использует в своем макросе).

...