我正在构建一个数据仓库,用于查询有时位于链接服务器上的数据库。
执行某些查询时,我偶尔会遇到以下错误消息
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
不幸的是,就我而言,我的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 :(得分:0)
它正在创建一个子查询,因为它创建了一个在链接服务器上执行的子查询(或查询)。
对链接服务器的查询要非常小心......因为SQL服务器可能会选择效率极低的查询计划。例如,在这种情况下,SQL服务器可以为六个远程表执行六种不同的选择,然后在本地进行连接(以及在服务器之间发送大量数据,您将失去远程表上索引的任何好处)。
如果我是你,我会将查询重构为两部分:
为您需要的链接表格数据创建一个查询,并在OPENQUERY语句中运行它,即
OPENQUERY('Linked Server','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吗?