Вставка в DB2 из набора данных SAS с сквозным SQL

Я все еще новичок в SAS и DB2. У меня есть таблица DB2 со столбцом, в котором хранятся значения, закодированные в виде временных меток. Я пытаюсь загрузить данные в этот столбец из набора данных SAS в моем рабочем каталоге. Однако некоторые из этих меток времени соответствуют датам до 01-01-1582 и не могут быть сохранены в качестве значений даты и времени в SAS. Вместо этого они хранятся в виде строк.

Это означает, что если я хочу загрузить эти значения в таблицу DB2, я должен сначала преобразовать их в метку времени с помощью функции TIMESTAMP () DB2, которая, насколько мне известно, требует сквозного SQL с оператором выполнения (в отличие от SAS ДОСТУП к методу libname). Например, чтобы написать одно значение, я делаю следующее:

PROC SQL;
    connect to db2 (user = xxxx database = xxxx password = xxxx);
    execute (insert into xxxx.xxxx (var) values (TIMESTAMP('0001-01-01-00.00.00.000000'))) by db2;
    disconnect from db2;
quit;

Как я могу добиться этого для всех значений в исходном наборе данных? Оператор select ... from внутри команды execute не работает, потому что, насколько мне известно, я не могу ссылаться на рабочий каталог SAS из соединения DB2.

В конечном итоге я мог бы написать макрос, который выполняет блок PROC SQL, указанный выше, и вызывать его из шага данных для каждого наблюдения, но мне было интересно, есть ли более простой способ сделать это. Изменение типов переменных невозможно.

Заранее спасибо.


person Marco    schedule 14.08.2017    source источник


Ответы (1)


Сложный способ работы с этим состоял бы в использовании call execute:

data _null_;
set sas_table;
call execute("PROC SQL;
              connect to db2 (user = xxxx database = xxxx password = xxxx);
              execute (
                 insert into xxxx.xxxx (var)
                 values (TIMESTAMP('"||strip(dt_string)||"'))
                ) by db2;
              disconnect from db2;
              quit;");
run;

Где sas_table - это ваш набор данных SAS, содержащий значения даты и времени, хранящиеся в виде строк и в переменной с именем dt_string.

Здесь происходит следующее: для каждого наблюдения в наборе данных SAS будет выполнять аргумент процедуры вызова execute, каждый раз с текущим значением dt_string.

Другой метод, использующий макросы вместо выполнения вызова, делает по сути то же самое:

%macro insert_timestamp;
  %let refid = %sysfunc(open(sas_table));
  %let refrc = %sysfunc(fetch(&refid.));
  %do %while(not &refrc.);
    %let var = %sysfunc(getvarc(&refid.,%sysfunc(varnum(&refid.,dt_string))));

    PROC SQL;
      connect to db2 (user = xxxx database = xxxx password = xxxx);
      execute (insert into xxxx.xxxx (var) values (TIMESTAMP(%str(%')&var.%str(%')))) by db2;
     disconnect from db2;
    quit;

    %let refrc = %sysfunc(fetch(&refid.));
  %end;
  %let refid = %sysfunc(close(&refid.));
%mend;
%insert_timestamp;

РЕДАКТИРОВАТЬ: я думаю, вы также можете загрузить таблицу в DB2 как есть, используя SAS / ACCESS, а затем преобразовать строки в метку времени с помощью sql pass-through. Что-то вроде

libname lib db2 database=xxxx schema=xxxx user=xxxx password=xxxx;
data lib.temp;
set sas_table;
run;
PROC SQL;
    connect to db2 (user = xxxx database = xxxx password = xxxx);
    execute (create table xxxx.xxxx (var TIMESTAMP)) by db2;
    execute (insert into xxxx.xxxx select TIMESTAMP(dt_string) from xxxx.temp) by db2;
    execute (drop table xxxx.temp) by db2;
    disconnect from db2;
quit;
person user2877959    schedule 14.08.2017
comment
Привет, спасибо за быстрый ответ. Это тоже была моя идея, когда я говорил о вызове proc sql с шагом данных. Однако мне интересно: зачем использовать 'в вызове TIMESTAMP ()? - person Marco; 14.08.2017
comment
Пожалуйста. Я не могу сказать, относится ли ваш вопрос к одинарным или двойным кавычкам. Если в вашем коде одиночные числа, то значение метки времени заключено в одинарные кавычки; поэтому одинарные кавычки здесь таковы, что разрешенное значение dt_string также заключено в одинарные кавычки в вызываемом запросе. Если удваивается, я не использую их в вызове timestamp. Я просто закрываю строку до этого момента перед конкатенацией со значением dt_string. - person user2877959; 14.08.2017
comment
Раньше у меня не работало, потому что я пытался использовать TIMESTAMP (& var) и TIMESTAMP (& var). Однако это сработало, когда я попробовал ваш TIMESTAMP (% str (% ') & var.% Str (%')). Еще раз спасибо за это! Я предполагаю, что это работает, потому что DB2 требует одинарных кавычек ... это так? Наконец, можно ли сделать вывод, что это невозможно сделать с помощью простого proc sql? - person Marco; 14.08.2017
comment
@MarcoLeal Да, DB2 (и большинство других реализаций SQL) требует одинарных кавычек для строковых литералов. Двойные кавычки определяют такие элементы, как имена переменных, имена таблиц и т. Д. Я отредактировал свой ответ, чтобы добавить еще один вариант, который идет другим путем. - person user2877959; 14.08.2017