2016-08-25 47 views
-1

我遇到了一個非常奇怪的情況。 我有兩個Oracle XE安裝。使用多重連接時,SQLPLUS不返回數據

一個安裝在西班牙語Windows機器中的另一個英文windows機器。

我有一個SQL查詢在西班牙語系統上運行。這個SQL有許多連接。當我使用SQLPLUS執行該SQL時,我沒有收到整數或長整型數據。

我很害怕,因爲我可以想象,表中有數據必須出現在查詢結果中。因此,我將模式導出到我的英文系統中。並使用SQLPLUS運行相同的SQL查詢。我用很多數據得到了預期的結果。

我的SQL沒有問題。這個SQL在我的項目中使用了很長時間。

查詢看起來like--

SELECT 
      device_id, 
      SUM(COALESCE(total_page_volume, 
      0)) AS total_page_volume, 
      SUM(COALESCE(total_page_volume, 
      0)-COALESCE(color_page_volume, 
      0)) AS mono_page_volume, 
      SUM(COALESCE(color_page_volume, 
      0)) AS color_page_volume, 
      SUM(COALESCE(total_page_volume, 
      0)) as totalvolume, 
      SUM(COALESCE(color_page_volume, 
      0)) as colorvolume, 
      SUM(COALESCE(total_page_volume, 
      0)-COALESCE(color_page_volume, 
      0)) as monovolume, 
      SUM(COALESCE(print_volume, 
      0)) AS print_volume, 
      SUM(COALESCE(copy_volume, 
      0)) AS copy_volume, 
      SUM(COALESCE(fax_volume, 
      0)) AS fax_volume, 
      SUM(COALESCE(total_oversize_volume, 
      0)) AS total_oversize_volume, 
      SUM(COALESCE(total_duplex_volume, 
      0)) AS total_duplex_volume, 
      SUM(COALESCE(num_detected_error_states, 
      0)) AS num_detected_error_states, 
      SUM(COALESCE(num_device_status, 
      0)) AS num_device_status, 
      SUM(COALESCE(num_printer_status, 
      0)) AS num_printer_status, 
      MIN(start_time) as minday, 
      MAX(end_time) as maxday 
     FROM 
      device_data_summary, 
      group_membership g_m , 
      group_closure g_c 
     WHERE 
      g_m.entity_id=device_id 
      AND g_c.child_id=g_m.group_id 
      AND g_c.parent_id = 95 
      AND CAST(start_time AS TIMESTAMP) >= CAST(TO_CHAR(g_m.start_date,'DD-MON-YYYY') AS TIMESTAMP) 
      AND (
       (
       g_m.end_date is NULL 
      ) 
       or (
       CAST(end_time AS TIMESTAMP) <= CAST(g_m.end_date AS TIMESTAMP) 
      ) 
      ) 
      AND start_time>=to_timestamp('2016-07-25 00:00:00','YYYY-MM-DD HH24:MI:SS') 
      AND end_time<=to_timestamp('2016-08-24 23:59:59','YYYY-MM-DD HH24:MI:SS') 
      AND period=1 
     GROUP BY 
      device_id; 
+2

沒有看到代碼,我猜想你有一些隱式的數據類型轉換,其行爲有所不同,具體取決於會話的NLS設置。無論代碼是否重現了這個問題,我都會期待這個問題被關閉。 –

+0

任何想法哪種數據類型可以有這樣的問題。 ? – Sirsendu

+1

字符串,日期和數字都將潛在地轉換爲不同的對象。假設問題不在於你在兩個系統中有不同字符集中的數據(即,當您使用US7ASCII導入到英語系統時,西班牙語系統將字符串「León」轉換爲「Leon」字符集)。 –

回答

1

您在至少這個查詢的一部分依靠隱式轉換:

... >= CAST(TO_CHAR(g_m.start_date,'DD-MON-YYYY') AS TIMESTAMP) 

你正在轉換的start_date爲一個字符串,然後將該字符串轉換爲時間戳,該時間戳必須依賴於會話的NLS_TIMSTAMP_FORMAT設置。不同的值可能會產生正確的結果,錯誤或不正確的結果。例如,這兩種格式可以滿足您的期望:

alter session set nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS'; 
select CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP) from dual; 

25-AUG-2016 00:00:00       

alter session set nls_timestamp_format = 'DD/MM/RRRR HH24:MI:SS'; 
select CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP) from dual; 

25/08/2016 00:00:00        

但是,這些都會給出錯誤的結果;在今年0025的第一個結束了(所以你不要有,否則所有您的數據將匹配條件):

alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'; 
select CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP) from dual; 

0025-08-20 16:00:00        

這兩個使2020年:

alter session set nls_timestamp_format = 'DD-MON-RR HH24:MI:SS'; 
select CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP) as nls, 
    to_char(CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP), 'YYYY-MM-DD HH24:MI:SS') as formatted 
from dual; 

NLS    FORMATTED   
------------------ ------------------- 
25-AUG-20 16:00:00 2020-08-25 16:00:00 

alter session set nls_timestamp_format = 'DD/MM/RR HH24:MI:SS'; 
select CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP) as nls, 
    to_char(CAST(TO_CHAR(sysdate,'DD-MON-YYYY') AS TIMESTAMP), 'YYYY-MM-DD HH24:MI:SS') as formatted 
from dual; 

NLS    FORMATTED   
----------------- ------------------- 
25/08/20 16:00:00 2020-08-25 16:00:00 

假設您沒有得到任何結果的會話是使用生成2020年日期的格式模型,而且您將來沒有任何事情發生。您可以更改西班牙語設置中的NLS設置,以顯示不同的值會生成您期望的結果。

您不應該依賴隱式轉換或NLS設置。你可能真的不想在這裏轉換成一個字符串,因爲你不會在其他地方那麼做;也許start_date有你想通過無時間部分的格式彈跳忽略時間分量,但在這種情況下,你可以這樣做:

CAST(TRUNC(g_m.start_date) AS TIMESTAMP) 

...這讓價值爲日期不是字符串並且不需要任何隱式轉換。

我不知道爲什麼要將所有內容都轉換爲時間戳來比較它們,但是您並未顯示是否有任何列實際上是時間戳而不是日期。無論如何,你似乎並不一致。