2010-01-15 26 views
2

客戶端與OCI編譯:10.2.0.4.0
服務器:Oracle9i企業版發行9.2.0.4.0甲骨文OCI:與日期字段查詢

有問題的查詢是:

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'這樣的字面值也不起作用。我曾嘗試以下內容:

  • 我試過基本知識:從客戶端查詢數據庫確實有效。這是這一個,讓我的麻煩
  • 下不工作:

    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()和 「改變會話設置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」

所以問題是,爲什麼是OCI應用給予不同的結果,如果兩者都訪問同一個數據庫服務器?

此外,澄清OCI應用的目的:它必須由用戶來配置的查詢。這個想法是,根據需要以適合存在於目標DB日期字段的用戶會適應的查詢,這就是爲什麼我不應該包括「改變會話集NLS_DATE_FORMAT」語句在我的代碼,因爲我不知道的日期格式。這樣我想爲用戶提供靈活性,而不依賴於特定的日期格式。這有意義嗎?有什麼建議麼?

回答

2

你列DATE_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',因爲此格式將按原始日期排序。

+0

嗨Vincent, 查詢的第一個版本是使用TO_DATE()函數。這就是問題的開始。 我的代碼中沒有字母,但我不知道日期的具體格式。關於OCI應用程序的工作原理,我在問題中增加了更多信息。 – AntonioHerraizS 2010-01-15 15:03:04

0

如何插入記錄?

日期字段確實存儲時間信息,因此當使用sysdate插入記錄時,日期字段將包含當天內記錄的不同「值」。當你執行date_proc = '05 -JUL-08'時,你說的是date_proc正好等於2008年7月5日12:01:00。如果您使用sysdate在12:01插入記錄,則不會返回。你有沒有嘗試過使用between或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 
+0

嗨RC,我試過trunc()。我添加了關於如何插入記錄的更多信息。 – AntonioHerraizS 2010-01-15 15:07:06

0

我會說你問的是錯誤的問題。

Oracle依靠共享SQL來提高性能,當你插入一個字符串時,如'20080705',SQL無法共享。詳情here

所以數據值應該是一個佔位符,並且應該是正確的數據類型(DATE)。示例here應該有助於做到這一點。

也就是說,如果這個工程

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

我們只是有這個錯誤(OCI_NO_DATA)獲得由某人在他們的電腦上改變一天中的小時引起的。當他們將日期/時間恢復到正確的時間時,應用程序開始正常工作。