Domanda

Sto cercando di utilizzare la data parte di un timbro temporale nella mia query in un codice SQL di DB2 pass-through di DB2.Ho provato a utilizzare le funzioni di data e daprendario ma non funzionerà con questo formato.Qualcuno conosce il nome della funzione da utilizzare nello stesso codice qui sotto?

PROC SQL; 
   connect to db2(ssid=smtng); 
     select *  from connection to db2 
         (select *  
             from ATable 
          where DATEPART(timestamp) > '12/01/2013'
   FOR READ ONLY WITH UR
    );
DISCONNECT FROM DB2;
QUIT; 
.

È stato utile?

Soluzione

Se si utilizza una funzione sul campo DateTime in DB2, quindi il database non sarà in grado di utilizzare gli indici (se tale campo è indicizzato). Questo perché gli indici sono (quasi sempre) creati sul campo stesso, non il risultato del campo dopo che è stato elaborato da una funzione. Ciò vale per la maggior parte dei database non solo DB2.

Invece, ciò che vuoi fare è fornire valori da datetime per l'inizio del giorno e per la fine della giornata e ottenere tutto loro inbetween. Per semplificare questo processo ho creato un formato chiamato mysqldt.. Originariamente questo formato è stato per un database MySQL, ma SQL Server e DB2 utilizzano entrambi gli stessi formati in modo che possa essere utilizzato anche su quelli:

proc format;
  picture mysqldt low-high = '''%Y-%0m-%0d %0H:%0M:%0S''' (datatype = datetime) ;
run ;
.

Una volta disponibile questo formato, tendo a utilizzare le variabili macro. Nella parte superiore del mio programma creerei una variabile macro in cui specifico la data da utilizzare durante il rapporto:

%let rpt_date = %sysfunc(mdy(1,12,2013));
.

Creerei quindi due campi datetime che rappresentano l'inizio del giorno e la fine della giornata, e li salvisse nel formato necessario per l'istruzione SQL:

%let sql_start = %sysfunc(dhms(&rpt_date, 0, 0, 0), mysqldt.);
%let sql_end   = %sysfunc(dhms(&rpt_date,23,59,59), mysqldt.);

%put &rpt_date &sql_start &sql_end;
.

Vuoi quindi cambiare la tua query per assomigliare a questo:

proc sql; 
  connect to db2(ssid=smtng); 
  select *  from connection to db2 
         (select *  
          from atable 
          where timestamp between &sql_start and &sql_end
          for read only with ur
    );
quit; 
.

In questo modo, non solo i tuoi indici ora sono ora utilizzati nella tua query, ma SQL sembra più pulito e si legge più facilmente e devi solo modificare la data del report in un unico posto (nella parte superiore del tuo programma) se hai bisogno per rieseguire il tuo rapporto.

Altri suggerimenti

In generale, è necessario utilizzare la sintassi DB2 corretta.Non conosco DB2, ma Questo documento copreQuesto abbastanza bene.In particolare:

PROC SQL; 
CREATE TABLE ONE AS SELECT * FROM CONNECTION TO DB2 
 (SELECT A.ID, A.NAME, B.AMOUNT, B.POSTDATE 
FROM IDS A 
INNER JOIN BANK B 
ON A.ID = B.ID 
WHERE POSTDATE BETWEEN '2007-01-01-00.00.00.000000' 
 AND '2007-09-30-23.59.59.999999')
.

Quindi sembra che la tua richiesta sia

PROC SQL; 
   connect to db2(ssid=smtng); 
     select *  from connection to db2 
         (select *  
             from ATable 
          where DATEPART(timestamp) > '2013-12-01-00.00.00.00000'
   FOR READ ONLY WITH UR
    );
DISCONNECT FROM DB2;
QUIT; 
.

Questo articolo da IBM sembra suggerirloCi sono altri formati diversi dal timestamp (che è quello che sopra è).Quindi potrebbe essere necessario utilizzarne uno diverso a seconda del formato esatto.

Io credo, dovresti usare SAS-DATE Letterale.Quindi:

 where DATEPART(timestamp) > '12Jan2013'd
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top