首页 > 解决方案 > 如何在链接数据库中使用子查询

问题描述

以下查询按预期返回 820240014 的 spriden_id。这将用作下面的子查询。

select spriden_id 
from spriden 
where spriden_pidm = 279355 
and spriden_change_ind is null;

当将 DAP_STU_ID 硬编码为“820240014”时,以下查询从 DAP_AUDIT_DTL 表中返回四行。

select * 
from DWSCHEMA.DAP_AUDIT_DTL@LINKDWTEST 
where DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID = '820240014';

使用与上面相同的查询,除了子查询。即使子查询返回 820240014,此查询也不从 DAP_AUDIT_DTL 表中返回任何行。为什么此查询不返回硬编码查询的值?

select * 
from DWSCHEMA.DAP_AUDIT_DTL@LINKDWTEST 
where DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID = 
(select spriden_id from spriden where spriden_pidm = 279355 
and spriden_change_ind is null);

SPRIDEN.SPRIDEN_ID 的数据类型是 VARCHAR2。DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID 的数据类型是 CHAR(10)。

标签: sqloracle

解决方案


IN在与返回多行的结果集进行比较时,您应该使用:

select *
  from DWSCHEMA.DAP_AUDIT_DTL@LINKDWTEST 
  where DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID IN (select spriden_id
                                                from spriden
                                                where spriden_pidm = 279355 and
                                                      spriden_change_ind is null)

我很惊讶原始版本没有引发异常。

编辑

好吧,看起来我最初的推理是合理的——错误的,但是合理的。:-)

实际问题是您将存储在 CHAR 字段中的值比字段定义长度短一个字符与 VARCHAR2 字段中的值进行比较。CHAR 字段的属性是所有存储在字段中的值都在右侧用空格填充,以便它们与定义的字段长度一样长。在这种情况下,存储的值DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_IDis not '820240014',它是'820240014 '- 换句话说,在“可见”值的末尾添加了一个额外的空格,使其长度为 10 个字符。SPRIDEN.SPRIDEN_ID是一个 VARCHAR2 字段,因此只有指定的字符 - 在本例中为 '820240014' - 被存储和检索。但是,当您将九个字符的值“820240014”与十个字符的值“820240014”进行比较时,它们就会不相等​​。

现在,有趣的SPRIDEN.SPRIDEN_ID是,如果定义为CHAR(20)并包含 value '820240014 ',它将比较为等于CHAR(10) value '820240014 '

我真的希望这是一个大学练习,因为如果你必须在生产环境中处理这个问题 - 好吧,Cthulhu 可以帮助你。:-)

令人高兴的是,有一种(相当简单的)方法来处理这个问题。如果您将 SPIDEN_ID 中的值的特定转换包含到 CHAR(10) 您的初始查询应该可以工作:

select *
  from DWSCHEMA.DAP_AUDIT_DTL@LINKDWTEST 
  where DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID IN (select CAST(spriden_id AS CHAR(10))
                                                from spriden
                                                where spriden_pidm = 279355 and
                                                      spriden_change_ind is null)

我想如果你愿意,你也可以选择转换DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID为 VARCHAR2(10)。试试看,看看你喜欢什么。

dbfiddle在这里


推荐阅读