> 文章列表 > 认知幻像:如果有这样一道面试题,可以如何作答?

认知幻像:如果有这样一道面试题,可以如何作答?

认知幻像:如果有这样一道面试题,可以如何作答?

书接上回,虽然我们知道,SQL有着强大的标准体系,但是在实践中,不同数据库却有不同的实现方式

除此之外,有时候用常规的思维逻辑而不是计算逻辑去推理SQL执行方式,也有可能出现不同于现实的判定。

以下这个问题,也是来自“云和恩墨大讲堂”朋友提出的。

最后这个查询,在 enmotest 表中,根本不存在 name 字段,查询的结果会是怎样呢?

大家想象一下,如果这是一道面试题,你如何判断结果,如何解释背后的逻辑?

create table enmotech (id number,name varchar2(20));
     insert into enmotech values(1,'Eygle');

create table enmotest (id number);
     insert into enmotest values(1);

select * from enmotech where name in (select name from enmotest);

思考一分钟。

插播:2023 数据技术嘉年华大会,将会在4.7 ~ 4.8 北京开幕,大会特设数据迁移专场,欢迎接受我的赠票邀请(扫码),共享数据库技术盛会,免费报名链接:

        https://modb.pro/event/804/395289

继续采用墨天轮的 SQLRUN 环境

    https://www.modb.pro/sqlrun/mysql

在Oracle数据库的执行结果如下:

认知幻像:如果有这样一道面试题,可以如何作答?

在 云和恩墨 的 MogDB 执行结果如下:

认知幻像:如果有这样一道面试题,可以如何作答?

网友提出的问题是:明明在 enmotest 表中不存在 name 字段,为什么不抛出不存在的异常,反而反回了外表的记录?

我们针对Oracle的查询,执行一个 10053 的跟踪事件(获得SQL解析过程),执行步骤如下:

SQL> alter session set events '10053 trace name context forever,level 1';

Session altered.

SQL> select * from enmotech where name in (select name from enmotest);

在跟踪文件中,可以清晰地看到执行计划的解析过程。以下解析步骤,说明了结果产生的原因。

对于子查询来说,父查询的所有字典信息可见,所以解析转换中,子查询的 NAME 自然就被解析为 ENMOTECH.NAME ,这样比较结果恒为真,就返还了父查询中所有的记录(此时如果父查询表中也不存在这个字段则会抛出异常):

SELECT "ENMOTECH"."ID" "ID","ENMOTECH"."NAME" "NAME" FROM "MOGDB"."ENMOTECH" "ENMOTECH" WHERE "ENMOTECH"."NAME"=ANY (SELECT "ENMOTECH"."NAME" "NAME" FROM "MOGDB"."ENMOTEST" "ENMOTEST")

Objects referenced in the statement

  ENMOTECH[ENMOTECH] 76095, type = 1

  ENMOTEST[ENMOTEST] 76096, type = 1

Objects in the hash table

  Hash table Object 76095, type = 1, ownerid = 3808176908773422935:

    No Dynamic Sampling Directives for the object

  Hash table Object 76096, type = 1, ownerid = 14982774484177512411:

    No Dynamic Sampling Directives for the object

这个题目的真正警示在于,如果开发人员凑巧写错了条件,而这个SQL的执行不会出现异常,只是结果不符合预期,我们需要提前识别这个误操作。


云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看” 

你的喜欢会被看到❤