Несогласованные сообщения об ошибках при запросе связанного SQL Server - PullRequest
2 голосов
/ 07 мая 2011

Я создаю хранилище данных, которое запрашивает базы данных, которые иногда расположены на связанных серверах.

При выполнении некоторых запросов я иногда встречал следующее сообщение об ошибке

Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.

К сожалению, в моем случае у меня нет подзапросов в моем операторе 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. Похоже, что они работают одинаково (хотя и не всегда согласованно).

Единственным непротиворечивым элементом этой проблемы является то, что она возникает только при запросах через связанный сервер.

Кто-нибудь знает какие-либо ограничения запросов связанных серверов, о которых я не знаю?

Или, если что-то не так с моим запросом, который я не вижу?

1 Ответ

0 голосов
/ 07 мая 2011

Создает подзапрос, потому что создает подзапрос (или запросы) для выполнения на связанном сервере.

Будьте очень осторожны с запросами к связанным серверам ... поскольку SQL-сервер может выбирать чрезвычайно неэффективные планы запросов. Например, в этом сценарии SQL-сервер может выполнить шесть различных операций выбора для шести удаленных таблиц, а затем выполнить объединение локально (так же как при отправке большого количества данных между серверами вы потеряете все преимущества индексов в ваших удаленных таблицах).

На вашем месте я бы реорганизовал запрос на две части:

  • создайте запрос для необходимых вам данных связанных таблиц и выполните его в операторе OPENQUERY, т.е.

    OPENQUERY ('Связанный сервер', 'SELECT .... FROM DatabaseName.dbo.CL INNER JOIN ...')

Это обеспечит соединение для удаленных таблиц на удаленном сервере.

  • присоединить результат этого запроса к вашему запросу в локальных таблицах:

1021 * т.е. *

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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...