2016-08-25 35 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) 

...这让价值为日期不是字符串并且不需要任何隐式转换。

我不知道为什么要将所有内容都转换为时间戳来比较它们,但是您并未显示是否有任何列实际上是时间戳而不是日期。无论如何,你似乎并不一致。