2011-05-06 95 views
2

我正在构建一个数据仓库,用于查询有时位于链接服务器上的数据库。查询链接SQL Server时出现不一致的错误消息

当执行一些疑问,我偶尔会遇到以下错误消息

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

不幸的是,在我的情况,我没有我的SELECT语句中的任意子查询。

下面是我收到的错误,这些select语句的一个示例:

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服务器可能会为六个远程表执行六个不同的选择,然后在本地执行联接(以及在服务器之间发送大量数据,您将失去远程表上索引的任何好处)。

如果我是你,我会重构查询分为两个部分:

  • 创建您需要的链接表数据的查询,并在OPENQUERY语句即

    OPENQUERY运行这个('链接服务器','SELECT .... FROM DatabaseName.dbo.CL INNER JOIN ...')

这将确保远程表的连接将在远程服务器上完成。

  • 加入这个查询的结果到您的查询在本地表:

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表加入。你真的想做一个CROSS JOIN而不是一个LEFT OUTER JOIN吗?

+0

谢谢Gareth。这非常有帮助。首先,关于到URL表的连接你是对的,它基本上是一个CROSS JOIN,其中的URLType ='LOB_ClientRecord'。看起来最好是将它作为LEFT OUTER JOIN来执行,因为作为CROSS JOIN,查询将不得不返回所有结果,然后应用WHERE子句。我对它进行了两种测试,使用LEFT OUTER JOIN的表现看起来更好。 – 2011-05-08 04:32:27

+0

我一定会尝试使用OPENQUERY。唯一的问题是数据库有时在同一台服务器上,这取决于我们客户的环境。我希望只有一组sql sql sript,但考虑到跨链接服务器查询的性质,这可能是不可能的。再次感谢! – 2011-05-08 04:42:57

+0

您可以使子查询成为您在所有平台上实施的SP。在运行查询时,您选择了是否针对链接或本地服务器运行 – Gareth 2011-05-08 18:58:46