2017-08-14 1 views
0

Je ne suis pas encore familiarisé avec SAS et DB2. J'ai une table DB2 avec une colonne qui stocke les valeurs codées en tant que timestamps. J'essaie de charger des données sur cette colonne à partir d'un ensemble de données SAS dans mon répertoire de travail. Cependant, certains de ces horodatages correspondent à des dates antérieures au 01-01-1582 et ne peuvent pas être stockés en tant que valeurs de date et heure dans SAS. Ils sont plutôt stockés en tant que chaînes. Cela signifie que si je veux charger ces valeurs sur la table DB2, je dois d'abord les convertir en horodatage avec la fonction TIMESTAMP() DB2, qui, autant que je sache, nécessite un SQL direct avec une instruction execute (comme opposé à la méthode libname de SAS ACCESS). Par exemple, afin d'écrire une seule valeur que je fais ce qui suit:Insertion dans DB2 d'un ensemble de données SAS avec passthrough SQL

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; 

Comment puis-je obtenir cela pour toutes les valeurs de la source de données définies? Une instruction select ... from dans la commande execute ne fonctionne pas car, autant que je sache, je ne peux pas référencer le répertoire de travail SAS à partir de la connexion DB2. En fin de compte, j'ai pu écrire une macro qui exécute le bloc PROC SQL ci-dessus et l'appeler à partir d'une étape de données pour chaque observation, mais je me demandais s'il y avait un moyen plus facile de le faire. Changer les types de variables n'est pas une option.

Merci d'avance.

Répondre

1

Une façon alambiquée de contourner ce serait d'utiliser 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 est votre ensemble de données SAS contenant les valeurs datetime stockées sous forme de chaînes et dans une variable appelée dt_string. Ce qui se passe ici est que, pour chaque observation dans un ensemble de données, SAS exécutera l'argument de la routine d'appel execute, chaque fois avec la valeur actuelle dt_string.

Une autre méthode en utilisant des macros au lieu d'appel exécuter pour faire essentiellement la même chose:

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

EDIT: Je suppose que vous pouvez également charger la table-est dans DB2 en utilisant SAS/ACCESS puis convertir les chaînes à timestamp avec sql pass-through. Quelque chose comme

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; 
+0

Salut, merci pour la réponse rapide. C'était aussi mon idée quand j'ai parlé d'appeler le proc sql avec une étape de données. Je me demande cependant: Pourquoi utiliser '"dans l'appel TIMESTAMP() –

+1

De rien Je ne sais pas si votre question se rapporte à des guillemets simples ou doubles Si singles, eh bien, dans votre code, la valeur d'horodatage est incluse dans les guillemets simples, donc les guillemets simples sont ici pour que la valeur résolue de 'dt_string' soit aussi entourée de guillemets simples dans la requête appelée Si double, eh bien, je ne les utilise pas dans l'appel' timestamp'. Je ne fais que fermer la chaîne jusqu'à ce moment avant de la concaténer avec la valeur de 'dt_string' – user2877959

+0

Cela ne fonctionnait pas pour moi parce que j'essayais avec TIMESTAMP (& var) et TIMESTAMP (" & var "). J'ai essayé votre TIMESTAMP (% str (% ') & var.% Str (%')) Merci encore une fois pour cela! Je suppose que cela fonctionne parce que le DB2 exige des guillemets simples ... est-ce le cas? Enfin, est-ce alors est-il sûr de conclure que cela ne peut pas être fait avec un "simple" proc sql? –