Pergunta

Estou tentando usar a parte da data de um carimbo de data/hora em minha consulta where em um código SQL de passagem do DB2 abaixo.Tentei usar as funções date e datepart, mas não funcionou com este formato.Alguém sabe o nome da função para usar no mesmo código abaixo?

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; 
Foi útil?

Solução

Se você usar uma função no campo data e hora no DB2, o banco de dados não poderá usar seus índices (se esse campo estiver indexado).Isso ocorre porque os índices são (quase sempre) criados no próprio campo, e não no resultado do campo após ele ter sido processado por uma função.Isso vale para a maioria dos bancos de dados, não apenas para o DB2.

Em vez disso, o que você deseja fazer é fornecer valores de data e hora para o início e o final do dia e obter tudo entre eles.Para simplificar esse processo criei um formato chamado mysqldt..Originalmente, esse formato era para um banco de dados MySQL, mas o SQL Server e o DB2 usam os mesmos formatos, portanto também podem ser usados ​​neles:

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

Quando esse formato estiver disponível, costumo usar variáveis ​​macro.No topo do meu programa eu criaria uma variável macro onde especifico a data a ser usada em todo o relatório:

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

Em seguida, eu criaria dois campos de data e hora representando o início e o fim do dia e os salvaria no formato necessário para a instrução 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;

Você então alteraria sua consulta para ficar assim:

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; 

Dessa forma, não apenas seus índices serão usados ​​em sua consulta, mas o SQL parecerá mais limpo e de leitura mais fácil, e você só precisará alterar a data do relatório em um único local (no topo do seu programa) se precisar executar novamente o seu relatório.

Outras dicas

Em geral, é necessário usar a sintaxe correta do DB2.Eu não conheço o DB2, mas este papel cobre isso bastante bem.Especificamente:

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')

Parece que sua consulta seria

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; 

Este artigo da IBM parece sugerir que existem outros formatos além do carimbo de data / hora (que é o que está acima).Portanto, pode ser necessário usar um diferente dependendo do formato exato.

Eu acredito que você deve usar o literal de data SAS.Então:

 where DATEPART(timestamp) > '12Jan2013'd
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top