Pergunta

Cliente compilado com OCI: 10.2.0.4.0
Servidor: Oracle9i Enterprise Edition Release 9.2.0.4.0

A consulta problemática é:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = '05-JUL-08'

Descrição da tabela:

SQL>describe LOG;

TEL NOT NULL VARCHAR2(15)
CODIGO NOT NULL VARCHAR2(20)
DATE_PROC NOT NULL DATE

Por mais simples que pareça, quando executado diretamente no servidor com sqlplus, ele retorna um resultado, mas quando executado do aplicativo que usa OCI, essa consulta retorna OCI_NO_DATA sempre. No começo, o valor da data também era um espaço reservado, mas descobri que mesmo dando a um literal como '05-JUL-08' não funcionou. Eu tentei o seguinte:

  • Eu tentei o básico: consultar o banco de dados do cliente funciona. É esse que me dá problemas
  • O seguinte funciona:

    SELECT CODIGO FROM LOG WHERE TEL = :telnumber
    
  • Executando ALTER SESSION SET NLS_DATE_FORMAT="DD-MM-YYYY"; antes da consulta no servidor e no cliente. Mesmo resultado: o servidor retorna dados, cliente OCI_NO_DATA

  • Tentei mudar DATE_PROC formato, combinando isso com o uso de TO_DATE(). Mesmo resultado.
  • Pesquisado, pesquisado, pesquisado. Sem resposta

Estou um pouco desesperado para encontrar uma resposta, apreciaria qualquer ajuda e pode fornecer tantos detalhes mais necessários. Obrigado.

--- Mais informações ---

update log set DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS') where CODIGO='BancoOne';

Eu tentei combinações diferentes usando trunc () e "alter session Set NLS_DATE_FORMAT" ... e é isso que recebo:

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

No servidor: Retornos: "Bancoone" (bom valor)
No aplicativo OCI: Retorna OCI_NO_DATA

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

No servidor: Retornos: "Bancoone"
No aplicativo OCI: retorna "Bancoone"

Portanto, o ponto é: por que o aplicativo OCI está fornecendo resultados diferentes se ambos estão acessando o mesmo servidor de banco de dados?

Além disso, para esclarecer o objetivo do aplicativo OCI: ele tem uma consulta a ser configurada pelo usuário. A idéia é que o usuário adapte a consulta conforme desejado para se encaixar no campo Data presente no banco de dados de destino, é por isso que não devo incluir as instruções "Alter Session Set NLS_DATE_FORMAT" no meu código, pois não vou saber o formato da data. Dessa forma, quero fornecer flexibilidade ao usuário e não confie em formatos de data específica. Isso faz sentido? Alguma sugestão?

Foi útil?

Solução

Sua coluna date_proc é uma data, você deve sempre Compare com uma data e Nunca confie na conversão implícita de dados.

Experimente isso:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = DATE '2008-07-05'

ou isto:

SELECT CODIGO 
  FROM LOG 
 WHERE TEL = :telnumber 
   AND DATE_PROC = to_date('05-JUL-08', 'DD-MON-RR')

Se puder, evite usar um formato de data em seu código que usa letras por meses (porque o código vai falhar Quando você muda a linguagem padrão) e apenas dois chars por anos (ambiguidade do século). Eu gosto de usar 'YYYY/MM/RR' Porque esse formato será classificado como a data original.

Outras dicas

Como os registros foram inseridos?

Os campos de data armazenam informações de tempo e, portanto, ao inserir registros usando o SysDate, o campo de data conterá diferentes "valores" para registros nesse dia. Quando você executa Date_proc = '05 -Jul-08 ', você está dizendo onde Date_proc é igual exatamente em 5 de julho de 2008 às 12:01:00. Se você inseriu o registro às 12:01 com o Sysdate, ele não será devolvido. Você já tentou usar um entre ou trunc?

Aqui está um exemplo:

drop table test_date;
create table test_date (id number, ud date);

insert into test_date values (1, '15-jan-10');
insert into test_date values (2, '15-jan-10');
insert into test_date values (3, '15-jan-10');
insert into test_date values (6, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (7, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (8, '16-jan-10');
commit;

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where ud = '15-jan-10';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00      

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where trunc(ud) = '15-jan-2010';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
6                      15-JAN-10                 15-JAN-2010 08:01:55                                                        
7                      15-JAN-10                 15-JAN-2010 08:01:55

Eu diria que você está fazendo a pergunta errada.

O Oracle conta com o compartilhamento de SQL para desempenho e quando você coloca uma string, como '20080705', o SQL não pode ser compartilhado. Detalhes aqui.

Portanto, o valor dos dados deve ser um espaço reservado e deve ser do tipo de dados correto (data). O exemplo aqui deve ajudar a fazer isso.

Dito isto, se isso funcionar

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

Mas isso não

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 
AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

Eu estaria tentando

SELECT TO_CHAR(DATE_PROC,'DD-MM-YYYY HH24:MI:SS') FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

Acabamos de receber esse erro (OCI_NO_DATA) ser causado por alguém que muda a hora do dia no PC. Quando eles colocam a data/hora de volta à hora certa, o aplicativo começou a funcionar bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top