sql - 如何在链接数据库中使用子查询
问题描述
以下查询按预期返回 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)。
解决方案
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_ID
is 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)。试试看,看看你喜欢什么。
推荐阅读
- java - 从对象中私有的关键字段中获取 MethodHandle 列表
- amazon-athena - 为 athena 选择特定文件
- flutter - 颤振在底部表顶部显示 Snackbar
- ios - 放置 3D 模型代替坐标
- c - Printf 递归字符串函数奇怪的行为
- angular - 组件中的 Angular 7 选项卡
- c# - 使用安全密钥 System.IdentityModel.Tokens.Jwt 4.0.2 解码 Jwt 令牌
- angular - 加载外部脚本后无法访问组件
- python - 在 AWS 上访问 Luigi 可视化工具
- concourse - 在 AWS 中安装 Concourse 5.0