2010-01-21 3 views
9

나는이 쿼리하위 쿼리에서 "잘못된 열 이름 XYZ"오류가 발생하지 않습니다. 열 이름이 하위 쿼리 테이블에 없더라도?

SELECT CustomerId FROM Stocks.dbo.Suppliers 

그것은 나를이 오류를 제공을 실행합니다. 열 이름 'CustomerId'가 잘못되었습니다. 이 오류는 Suppliers 테이블에 CustomerId 열이 없으므로 유효합니다. 하지만 하위 쿼리에서 동일한 쿼리를 사용하면 오류가 발생하지 않습니다. 예 :

SELECT * 
    FROM SomeOtherDb.dbo.Customer 
WHERE CustomerId In(SELECT CustomerId 
         FROM Stocks.dbo.Suppliers) 

"잘못된 열 이름"과 같은 오류가 발생하지만 쿼리가 오류없이 실행됩니다.

정규화 된 이름은 모두 동일한 서버에있는 규칙입니다.

CustomerId는 SomeOtherDb.dbo.Customer 테이블에는 있지만 서브 쿼리에는 존재하지 않습니다.

왜이 동작입니까? 하위 쿼리가있는 것입니까?

감사합니다.

+0

어느 상황에서 나에 대한 잘못된 열 오류가 발생합니다 (말했다, 나는 많은 사람들이 내가 :) 코드를 응축/단순화하기 위해 위의 사용 앨리어싱에 대한 십자군에 알고). 정규화 된 이름은 관습에 따라 또는 연결된 서버를 통해 제공됩니까? – Andrew

+0

완전한 이름은 규칙 일뿐입니다. 두 DB 모두 동일한 서버에 있습니다. – Kashif

답변

13

하위 쿼리는 외부 쿼리의 열을 상속합니다.

SomeOtherDb.dbo.Customer에는 CustomerId 열이 있습니다 (이 이름은 이름에서 유추 된 것으로 보입니다).

하위 쿼리의 테이블에 CustomerId 열이없는 경우 하위 쿼리를 사용하여 수행하지 않을 것임을 의미합니다 (하위 테이블의 테이블에 CustomerId 열이 없으면 그렇지 않을 수도 있습니다. 그렇지 않으면 다음과 같은 오류가 발생하지 않습니다. 하위 쿼리 자체를 실행하는 경우) 하위 쿼리는 외부 CustomerId를 선택하여 반환하며 하위 쿼리의 유일한 열이므로 하위 쿼리는 쓸모가 없습니다.

+0

네, 맞습니다 SomeOtherDb.dbo.Customer는 CustomerId 컬럼을 가지고 있습니다. – Kashif

+6

필자는이 문제에 대해 몇 번 생각해 보았습니다. 대답이 맞지만 SQL Server의 디자인이 완벽하지 않다고 생각합니다 (ISO SQL 표준을 완전히 구현하는지 여부는 관계 없음). 상위 쿼리의 열을 참조 할 때 하위 쿼리가 별칭을 사용하도록하는 것이 훨씬 안전하다고 생각합니다. 동료는 위와 같은 하위 쿼리의 입력 오류로 인해 프로덕션 테이블의 모든 행을 실수로 업데이트했을 때 관련 비극을 경험했습니다. Hilarity (및 백업에서 복원)가 발생했습니다. –

+0

각 열에 대해 테이블 ​​(또는 테이블 별칭)을 명시 적으로 정의하는 것이 좋습니다. 즉, 부질의가 잘못된 테이블에서 열을 가져 오는 것을 피할 수 있으며,) 누군가가 새로운 열을 생성하는 경우 이름 충돌을 피할 수 있습니다. – drizin

1

귀하의 질문에 대한 답변 ("왜 오류가 없음")은 위와 같지만 나중에이 문제 유형을 피하는 방법에 조금 도움이됩니다. 하위 쿼리를 사용하는 대신 왼쪽 가입을 사용하십시오 :

SELECT C.* 
FROM SomeOtherDb.dbo.Customer AS C 
LEFT JOIN Stocks.dbo.Suppliers AS S ON C.CustomerId = S.CustomerId 
WHERE S.CustomerID Is Null 

이 쿼리는 물론 가능한 조인으로 구성 될 때 원본 쿼리와 동일하게 항상 성능이 향상됩니다. 위의 문제를 피할 수있는 추가 이점이 있습니다. 이 구조에서는 자연스럽게 테이블 이름을 사용할 것이기 때문에 등호 양쪽에 같은 테이블 이름과 같은 문제가있을 때 더 분명합니다. 서브 쿼리가 빨려, 나는 그들을 상대로 영구적 인 성전에 서있다.