查询链接的SQL Server时出现不一致的错误消息

查询链接的SQL Server时出现不一致的错误消息,sql,tsql,linked-server,Sql,Tsql,Linked Server,我正在构建一个数据仓库,用于查询有时位于链接服务器上的数据库 在执行一些查询时,我偶尔会遇到以下错误消息 子查询返回了多个值。当子查询在=、!=、=或者当子查询用作表达式时 不幸的是,在我的示例中,select语句中没有任何子查询 以下是我收到错误的其中一条select语句的示例: Select CL.ClientID as CompanyID, CL.Client, CL.Name, CT.Description, CS.Label, CCF.PrimaryDiscipline,

我正在构建一个数据仓库,用于查询有时位于链接服务器上的数据库

在执行一些查询时,我偶尔会遇到以下错误消息

子查询返回了多个值。当子查询在=、!=、=或者当子查询用作表达式时

不幸的是,在我的示例中,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。。。它很好用

如果我使用完全相同的模式查询不同的数据库,它就可以正常工作。如果我将数据库移动到另一个链接的服务器,它偶尔会工作

如果我删除了几个连接,效果很好,但我可以删除不同的连接组合以获得类似的成功,这意味着我不能将错误缩小到单个表或连接

我的数据仓库或我正在查询的数据库位于SQLServer2005还是2008上似乎也无关紧要。它们似乎同样失败,但未必始终如一

此问题唯一一致的因素是,它仅在跨链接服务器查询帐户时发生

有人知道我不知道的查询链接服务器的任何限制吗


或者,如果我的查询有什么问题,我看不到?

它正在进行子查询,因为它创建了一个或多个要在链接服务器上执行的查询

对链接服务器的查询要非常小心……因为SQL server可能会选择效率极低的查询计划。例如,在这种情况下,SQL server可能会对六个远程表执行六种不同的选择,然后在本地执行联接,并在服务器之间发送大量数据,这将失去远程表索引的任何好处

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

为所需的链接表数据创建查询,并在OPENQUERY语句中运行该查询,即

OPENQUERY“链接服务器”、“选择…”。。。。从DatabaseName.dbo.CL内部联接…'

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

将此查询的结果连接到本地表上的查询: i、 e

作为一个副作用,我怀疑如果你这样做,你的问题就会消失


顺便说一句,我不明白你想对URL表的连接做什么。您真的想进行交叉连接而不是左外连接吗?

它正在进行子查询,因为它创建了一个或多个要在链接服务器上执行的查询

对链接服务器的查询要非常小心……因为SQL server可能会选择效率极低的查询计划。例如,在这种情况下,SQL server可能会对六个远程表执行六种不同的选择,然后在本地执行联接,并在服务器之间发送大量数据,这将失去远程表索引的任何好处

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

为所需的链接表数据创建查询,并在OPENQUERY语句中运行该查询,即

OPENQUERY“链接服务器”、“选择…”。。。。从DatabaseName.dbo.CL内部联接…'

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

将此查询的结果连接到本地表上的查询: i、 e

作为一个副作用,我怀疑如果你这样做,你的问题就会消失


顺便说一句,我不明白你想对URL表的连接做什么。你真的想做交叉连接而不是左外连接吗?

谢谢Gareth。这非常有帮助。首先,关于URL表的连接,您是对的,它本质上是一个交叉连接,其中URLType='LOB_ClientRecord'。不过,似乎最好将其作为左外部联接,因为作为交叉联接,查询必须返回所有结果,然后应用WHERE子句。我用两种方法对它进行了测试,使用左外部连接的性能似乎更好。我一定会尝试使用OPENQUERY。唯一的问题是数据库有时位于同一台服务器上,这取决于我们客户机的环境。我希望只有一组sql脚本,但考虑到查询跨链接服务器的性质,这可能是不可能的。再次感谢!您可以使子查询成为在所有平台上实现的SP。运行查询时,您选择了是针对左侧外部联接/交叉联接问题上的链接服务器还是本地服务器运行。我将检查关联的查询计划t
看看有什么不同。SQL Server应该生成相同的查询计划有时对查询的微小更改可能会导致SQL Server生成完全不同的查询计划。我会尽量避免使用左外连接,如果这不是您正在做的事情,那么它会让下一个必须支持您的代码的人感到困惑。如果您需要强制执行特定的查询计划,请使用提示。。。从…起交叉连接选择。。。从dbo.KA_LOB_Config_URL,其中URLType='LOB_ClientRecord'作为URL,指示SQL server首先在'LOB_ClientRecord'上进行筛选。如果性能仍然不如预期,请检查查询计划。谢谢Gareth。这非常有帮助。首先,关于URL表的连接,您是对的,它本质上是一个交叉连接,其中URLType='LOB_ClientRecord'。不过,似乎最好将其作为左外部联接,因为作为交叉联接,查询必须返回所有结果,然后应用WHERE子句。我用两种方法对它进行了测试,使用左外部连接的性能似乎更好。我一定会尝试使用OPENQUERY。唯一的问题是数据库有时位于同一台服务器上,这取决于我们客户机的环境。我希望只有一组sql脚本,但考虑到查询跨链接服务器的性质,这可能是不可能的。再次感谢!您可以使子查询成为在所有平台上实现的SP。当您运行查询时,您选择了是针对左侧外部联接/交叉联接问题上的链接服务器还是本地服务器运行。我将检查关联的查询计划,以查看不同之处。SQL Server应该生成相同的查询计划有时对查询的微小更改可能会导致SQL Server生成完全不同的查询计划。我会尽量避免使用左外连接,如果这不是您正在做的事情,那么它会让下一个必须支持您的代码的人感到困惑。如果您需要强制执行特定的查询计划,请使用提示。。。从…起交叉连接选择。。。从dbo.KA_LOB_Config_URL,其中URLType='LOB_ClientRecord'作为URL,指示SQL server首先在'LOB_ClientRecord'上进行筛选。如果性能仍然不如预期,请检查查询计划。
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'