2011-05-06 3 views
2

때때로 연결된 서버에있는 데이터베이스를 쿼리하는 데이터웨어 하우스를 구축하고 있습니다. 일부 쿼리를 실행할 때 연결된 SQL Server 쿼리시 일관성없는 오류 메시지

, 나는 가끔 내 경우, 내 SELECT 문 내의 서브 쿼리가없는,

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

불행하게도 다음과 같은 오류 메시지가 발생했습니다.

Select CL.ClientID as CompanyID, CL.Client, CL.Name, CT.Description, CS.Label, 
    CCF.PrimaryDiscipline, CCF.DisciplineDescription, CL.WebSite, CL.Memo, 
    CCS.CurrentStatus, CLA.Address, CLA.Address1, CLA.Address2, CLA.Address3, 
    CLA.Address4, CLA.City, CLA.State, CLA.ZIP, CO.Country, CLA.Phone, CLA.Fax, 
    CLA.EMail, CL.PriorWork, CL.Recommend, CL.DisadvBusiness, CL.SmallBusiness, CL.MinorityBusiness, 
    CL.HBCU, CL.WomanOwned, CL.VetOwnedSmallBusiness, CL.DisabledVetOwnedSmallBusiness, 
    CASE WHEN CL.LinkedVendor is not null THEN 'Vendor' ELSE null END as LinkedCompanyType, 
    CL.LinkedVendor as LinkedCompanyID, VE.Name as LinkedCompanyName, 
    'Client' as LOB_EntityCategory, Replace(URL.URL,'{0}',RTRIM(CL.ClientID)) as LOB_CompanyRecord, 
    CCF.LOB_CV_CustVar01, CCF.LOB_CV_CustVar02, CCF.LOB_CV_CustVar03, CCF.LOB_CV_CustVar04, 
    CCF.LOB_CV_CustVar05, CCF.LOB_CV_CustVar06, CCF.LOB_CV_CustVar07, CCF.LOB_CV_CustVar08, 
    CCF.LOB_CV_CustVar09, CCF.LOB_CV_CustVar10, CCF.LOB_CV_CustVar11, CCF.LOB_CV_CustVar12, 
    CCF.LOB_CV_CustVar13, CCF.LOB_CV_CustVar14, CCF.LOB_CV_CustVar15, CCF.LOB_CV_CustTxt01, 
    CCF.LOB_CV_CustTxt02, CCF.LOB_CV_CustTxt03, CCF.LOB_CV_CustTxt04, CCF.LOB_CV_CustTxt05, 
    CCF.LOB_CV_CustNum01, CCF.LOB_CV_CustNum02, CCF.LOB_CV_CustNum03, CCF.LOB_CV_CustNum04, 
    CCF.LOB_CV_CustNum05, CCF.LOB_CV_CustDat01, CCF.LOB_CV_CustDat02, CCF.LOB_CV_CustDat03, 
    CCF.LOB_CV_CustDat04, CCF.LOB_CV_CustDat05, CCF.ShowInClientDirectory 
FROM [LinkedServer].DatabaseName.dbo.CL 
INNER JOIN dbo.KA_LOB_Clients_CustomFields as CCF 
    ON CL.ClientID=CCF.ClientID 
INNER JOIN [LinkedServer].DatabaseName.dbo.CFGClientStatus as CS 
    ON CL.Status=CS.Status 
LEFT OUTER JOIN [LinkedServer].DatabaseName.dbo.CFGClientCurrentStatus as CCS 
    ON CL.CurrentStatus=CCS.CurrentStatus 
LEFT OUTER JOIN [LinkedServer].DatabaseName.dbo.CFGClientType as CT 
    ON CL.Type=CT.Code 
LEFT OUTER JOIN [LinkedServer].DatabaseName.dbo.CLAddress as CLA 
    ON CL.ClientID=CLA.ClientID and CLA.PrimaryInd='Y' 
LEFT OUTER JOIN [LinkedServer].DatabaseName.dbo.VE 
    ON CL.LinkedVendor=VE.Vendor 
LEFT OUTER JOIN [LinkedServer].DatabaseName.dbo.CFGCountry AS CO 
    ON CLA.Country=CO.ISOCountryCode 
LEFT OUTER JOIN dbo.KA_LOB_Config_URLs as URL 
    ON URL.URLType='LOB_ClientRecord' 

당신은 이러한 쿼리의 많은 연결된 서버 건너있는 것을 알 수 있습니다 : 다음

내가 오류를받은 다음 선택 문 중 하나의 예입니다. 데이터웨어 하우스가 동일한 서버에있을 때 오류 메시지가 표시되지 않습니다.

문제를 더욱 복잡하게 만들려면 오류의 일관성이 없습니다. 명명 된 열을 모두 제거하고 Select * From...으로 바꾼다면 잘 작동합니다.

정확히 동일한 스키마로 다른 데이터베이스를 쿼리하면 정상적으로 작동합니다. 다른 연결된 서버로 데이터베이스를 이동하면 가끔 작동합니다.

두 개의 조인을 제거하면 정상적으로 작동하지만 유사한 성공으로 조인의 다양한 조합을 제거 할 수 있습니다. 즉, 오류를 단일 테이블로 제한하거나 조인 할 수 없습니다.

내 데이터웨어 하우스 또는 쿼리중인 데이터베이스가 SQL Server 2005 또는 2008에 있는지 여부도 중요하지 않은 것처럼 보입니다.

이 문제의 유일한 일관성있는 요소는 연결된 서버를 통해 쿼리 할 때만 발생한다는 것입니다.

내가 아는 링크 된 서버를 쿼리하는 제한 사항을 알고있는 사람이 있습니까?

내 검색어에 문제가있는 경우 볼 수 없습니까?

답변

0

연결된 서버에서 실행할 하위 쿼리 (또는 쿼리)를 만들기 때문에 하위 쿼리가 만들어집니다.

SQL 서버는 매우 비효율적 인 쿼리 계획을 선택할 수 있으므로 연결된 서버에 대한 쿼리에는 매우주의해야합니다. 예를 들어,이 시나리오에서 SQL 서버는 6 개의 원격 테이블에 대해 6 개의 다른 선택을 수행 한 다음 로컬로 조인을 수행 할 수 있습니다 (서버간에 많은 양의 데이터를 보내면 원격 테이블의 인덱스 이점을 잃을 수 있습니다).

내가 당신이라면 나는 두 부분으로 쿼리를 리팩토링 것 :

  • 는 당신이 필요로 연결된 테이블의 데이터에 대한 쿼리를 작성하고

    OPENQUERY 즉 OPENQUERY 문이 실행 ('링크 DatabaseName.dbo.CL 내부 조인 FROM 서버 ','... SELECT ... ')

이것은 원격 서버에서 수행됩니다 원격 테이블에 조인 보장합니다.

  • 로컬 테이블에 쿼리에이 쿼리의 결과를 결합 :

즉 부작용으로

SELECT ... FROM OPENQUERY(..) as REM INNER JOIN dbo.KA_LOB_Clients_CustomFields as CCF 
    ON REM.ClientID=CCF.ClientID LEFT OUTER JOIN dbo.KA_LOB_Config_URLs as URL 
    ON URL.URLType='LOB_ClientRecord' 

, 나는이 작업을 수행 할 경우 문제가 사라집니다 의심 .

나는 당신이 URL 테이블에 대한 조인으로 무엇을하려고하는지 이해하지 못합니다. LEFT OUTER JOIN 대신 CROSS JOIN을 실제로하고 싶습니까?

+0

Gareth. 그것은 매우 도움이됩니다. 먼저, URL 테이블에 대한 조인과 관련하여 URLType = 'LOB_ClientRecord'인 CROSS JOIN이라는 것입니다. CROSS JOIN으로 쿼리가 모든 결과를 반환하고 WHERE 절을 적용해야하기 때문에 LEFT OUTER JOIN으로 처리하는 것이 더 좋을 것처럼 보였습니다. 두 가지 방법으로 테스트 해봤는데 LEFT OUTER JOIN을 사용하면 성능이 더 좋아진 것 같았습니다. –

+0

확실히 OPENQUERY를 사용해 보겠습니다. 유일한 문제는 고객의 환경에 따라 데이터베이스가 동일한 서버에있는 경우가 있다는 것입니다. 나는 한 세트의 SQL 스크립트 만 가지기를 바랬지 만 연결된 서버 전체를 질의하는 특성을 감안할 때 가능하지 않을 수도 있습니다. 다시 한 번 감사드립니다! –

+0

하위 쿼리를 모든 플랫폼에서 구현하는 SP로 만들 수 있습니다. 쿼리를 실행할 때 연결된 서버 또는 로컬 서버에 대해 실행할지 여부를 선택하십시오. – Gareth

관련 문제