Oracle OCI : 날짜 필드가있는 쿼리
문제
OCI로 컴파일 된 클라이언트 : 10.2.0.4.0
서버 : Oracle9i Enterprise Edition 릴리스 9.2.0.4.0
문제가있는 쿼리는 다음과 같습니다.
SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = '05-JUL-08'
테이블 설명 :
SQL>describe LOG;
TEL NOT NULL VARCHAR2(15)
CODIGO NOT NULL VARCHAR2(20)
DATE_PROC NOT NULL DATE
SQLPLUS를 사용하여 서버에서 직접 실행하면 결과를 반환하지만 OCI를 사용하는 앱에서 실행되면이 쿼리가 반환됩니다. OCI_NO_DATA
언제나. 처음에는 날짜 값도 자리 표시 자 였지만 문자 그대로와 같은 문자를주는 것을 알았습니다. '05-JUL-08'
작동하지 않았습니다. 다음을 시도했습니다.
- 기본 사항을 시도했습니다. 클라이언트에서 DB를 쿼리하면 작동합니다. 이 사람은 나에게 문제를주는 것입니다
다음은 작동합니다.
SELECT CODIGO FROM LOG WHERE TEL = :telnumber
실행
ALTER SESSION SET NLS_DATE_FORMAT="DD-MM-YYYY";
서버와 클라이언트 모두에서 쿼리 전에 동일한 결과 : 서버는 데이터, 클라이언트를 반환합니다OCI_NO_DATA
- 변경을 시도했습니다
DATE_PROC
형식, 이것을 사용과 결합합니다TO_DATE()
. 동일한 결과. - 검색, 검색, 검색. 대답이 없습니다
나는 답을 찾기 위해 약간 필사적이며, 어떤 도움을 주셔서 감사하며, 필요한만큼 자세한 내용을 제공 할 수 있습니다. 감사.
--- 추가 정보 ---
update log set DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS') where CODIGO='BancoOne';
Trunc () 및 "Alter Session Set NLS_DATE_FORMAT"를 사용하여 다른 조합을 시도했습니다 ... 그리고 이것이 내가 얻는 것입니다.
SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');
서버 : 반환 : "Bancoone"(좋은 가치)
OCI 앱에서 : OCI_NO_DATA를 반환합니다
SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');
서버 : 반환 : "Bancoone"
OCI 앱에서 : "Bancoone"을 반환합니다.
요점은, 둘 다 동일한 DB 서버에 액세스하는 경우 OCI 앱이 다른 결과를 제공하는 이유는 무엇입니까?
또한 OCI 앱의 목적을 명확히하기 위해 : 사용자가 구성 할 쿼리가 있습니다. 아이디어는 사용자가 대상 DB에있는 날짜 필드에 맞게 원하는대로 쿼리를 조정한다는 것입니다. 그래서 날짜 형식을 알지 못하므로 코드에 "Alter Session Set NLS_DATE_FORMAT"문을 포함해서는 안됩니다. 이렇게하면 사용자에게 유연성을 제공하고 특정 날짜 형식에 의존하지 않습니다. 이게 말이 되요? 제안이 있습니까?
해결책
열 날짜 _proc은 날짜입니다 언제나 날짜와 비교하십시오 절대 암시 적 데이터 변환에 의존하십시오.
이 시도:
SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = DATE '2008-07-05'
아니면 이거:
SELECT CODIGO
FROM LOG
WHERE TEL = :telnumber
AND DATE_PROC = to_date('05-JUL-08', 'DD-MON-RR')
가능하다면 날짜 형식 사용을 자제하십시오. 코드에서 몇 달 동안 문자를 사용합니다 (코드 때문에 실패합니다 기본 언어를 변경할 때)와 몇 년 동안 두 숯 만 (세기의 모호함). 나는 사용하는 것을 좋아한다 'YYYY/MM/RR'
이 형식은 원래 날짜로 정렬되기 때문입니다.
다른 팁
기록은 어떻게 삽입 되었습니까?
날짜 필드는 시간 정보를 저장하므로 SysDate를 사용하여 레코드를 삽입 할 때 날짜 필드에는 해당 날 내에 다른 "값"이 포함됩니다. date_proc = '05 -jul-08 '을 실행할 때 Date_proc이 2008 년 7 월 5 일과 정확히 12:01:00과 같은 곳을 말합니다. Sysdate와 함께 12:01에 레코드를 삽입 한 경우 반환되지 않습니다. 사이 또는 Trunc을 사용해 보셨습니까?
예는 다음과 같습니다.
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
나는 당신이 잘못된 질문을하고 있다고 말하고 싶습니다.
Oracle은 성능을 위해 SQL을 공유하는 데 의존하며 '20080705'와 같은 문자열을 고수 할 때 SQL을 공유 할 수 없습니다. 세부 여기.
따라서 데이터 값은 자리 표시자가되어야하며 올바른 데이터 유형 (날짜)이어야합니다. 예 여기 그렇게하는 데 도움이 될 것입니다.
이것이 효과가 있다면
SELECT CODIGO FROM LOG
WHERE TEL = 11223344 AND
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');
그러나 이것은 그렇지 않습니다
SELECT CODIGO FROM LOG
WHERE TEL = 11223344
AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');
나는 노력할 것이다
SELECT TO_CHAR(DATE_PROC,'DD-MM-YYYY HH24:MI:SS') FROM LOG
WHERE TEL = 11223344 AND
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');
우리는 방금이 오류 (OCI_NO_DATA)가 PC에서 하루의 시간을 변경하여 발생했습니다. 날짜/시간을 적절한 시간으로 되돌릴 때 응용 프로그램이 작동하기 시작했습니다.