답변:
열 table_b
이없는 경우에도 쿼리는 구문 상 올바른 SQL name
입니다. 그 이유는 범위 확인입니다.
쿼리를 구문 분석 할 때 먼저 열 table_b
이 있는지 확인합니다 name
. 그렇지 않기 때문에 table_a
확인됩니다. 테이블에 name
열 이없는 경우에만 오류가 발생합니다 .
마지막으로 쿼리는 다음과 같이 실행됩니다.
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
결과에 대해 쿼리의 모든 행에 table_a
대해 하위 쿼리 는 (select name from table_b)
또는 값 (select a.name from table_b b)
이 같고 a.name
행이 많은 단일 열이있는 테이블입니다 table_b
. 따라서 table_b
하나 이상의 행이 있으면 쿼리는 다음과 같이 실행됩니다.
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
또는:
select a.*
from table_a a
where a.name = a.name ;
또는:
select a.*
from table_a a
where a.name is not null ;
table_b
비어 있으면 쿼리는 행을 반환하지 않습니다 (thnx에서 @ughai로 해당 가능성을 나타냄).
그것은 (오류가 발생하지 않는다는 사실) 아마 모든 열 참조에 테이블 이름 / 별칭이 접두사를 붙여야하는 가장 좋은 이유 일 것입니다. 쿼리가 다음과 같은 경우
select a.* from table_a where a.name in (select b.name from table_b);
오류가 바로 발생했을 것입니다. 테이블 접두사가 생략되면, 특히 더 복잡한 쿼리에서 이러한 실수가 발생하는 것이 어렵지 않으며 더욱 중요한 것은 눈에 띄지 않습니다.
또한 Oracle Docs : 정적 SQL 문에서 이름 확인 내부 캡처 의 유사한 예제 B-6 및 SELECT 및 DML 문에서 내부 캡처 방지의 단락에 있는 권장 사항을 참조하십시오 .
명령문의 각 열 참조를 적절한 테이블 별명으로 규정하십시오.
때문에
중첩 된 하위 쿼리가 하위 쿼리보다 한 수준 위의 부모 문을 참조하는 테이블의 열을 참조하면 Oracle은 상관 된 하위 쿼리를 수행합니다. http://docs.oracle.com/cd/E11882_01/server.112/e41084/queries007.htm#SQLRF52357
하위 쿼리가 상호 관련되어 있는지 여부를 확인 하려면 Oracle 은 외부 문 컨텍스트를 포함하여 하위 쿼리에서 이름을 확인 해야합니다 . 그리고 접두사가없는 name
경우 가능한 유일한 해결책입니다.
더 없다 name
필드 table_b
오라클에서 일을합니다 그래서는 table_a
. 나는 시도 EXPLAIN PLAN
했지만 이것은 나에게만 있다고 말했다 TABLE ACCESS
FULL
. 나는 이것이 두 테이블 사이에 어떤 종류의 카티 전 곱을 생성한다고 가정하고 모든 이름의 목록 table_a
이 하위 쿼리에 의해 반환 된다고 가정 합니다.
from table_a where ...
있습니다. 널인 행을 table_a
제외한 모든 행을 리턴합니다 name
.
TABLE ACCESS FULL
순차 스캔을 수행하고 있음을 알리는 오라클의 방법입니다.