Что такое "идентификатор нескольких частей" и почему он не может быть связан?

Я постоянно получаю эти ошибки при попытке обновить таблицы на основе другой таблицы. Я в конечном итоге переписываю запрос, меняю порядок объединений, меняю некоторые группы, а затем в конечном итоге работает, но я просто не совсем понимаю.

Что такое "многочастный идентификатор"?
Когда "многочастный идентификатор" не может быть связан?
В чем же все это связано?
В каких случаях эта ошибка произойдет?
Каковы наилучшие способы предотвратить это?

Конкретная ошибка SQL Server 2005:

Идентификатор многочастности "..." не может быть привязан.

Вот пример:

UPDATE  [test].[dbo].[CompanyDetail]

SET Mnemonic = [dbBWKMigration].[dbo].[Company].[MNEMONIC], 
               [Company Code] = [dbBWKMigration].[dbo].[Company].[COMPANYCODE]

WHERE [Company Name] = **[dbBWKMigration].[dbo].[Company].[COMPANYNAME]**

Фактическая ошибка:

Msg 4104, уровень 16, состояние 1, строка 3 Идентификатор с несколькими частями "dbBWKMigration.dbo.Company.COMPANYNAME" не может быть привязан.

Ответ 1

Многопользовательский идентификатор - это любое описание поля или таблицы, которое содержит несколько частей - например, MyTable.SomeRow - если оно не может быть связано, что означает, что с ним что-то не так - либо у вас есть простая опечатка, либо путаница между таблицей и столбцом. Это также может быть вызвано использованием зарезервированных слов в вашей таблице или именах полей, а не их окружающих с помощью [].

Что-то вроде redgate sql prompt отлично подходит для того, чтобы избежать необходимости вручную вводить их (он даже автоматически завершает объединение на основе внешних ключей), но не является бесплатным. SQL Server 2008 поддерживает intellisense из коробки, хотя он не так полно, как версия redgate.

Ответ 2

Собственно, иногда, когда вы обновляете одну таблицу из других табличных данных, я думаю, что одна из распространенных проблем, вызывающих эту ошибку, - это когда вы неправильно используете свои сокращения таблиц или когда они не нужны. Правильная инструкция приведена ниже:

Update Table1
Set SomeField = t2.SomeFieldValue 
From Table1 t1 
Inner Join Table2 as t2
    On t1.ID = t2.ID

Обратите внимание, что столбец SomeField из Таблица1 не имеет t1 классификатора t1.SomeField, а просто SomeField.

Если вы попытаетесь обновить его, указав t1.SomeField, оператор вернет многочастную ошибку, которую вы заметили.

Ответ 3

Это, наверное, опечатка. Найдите места в коде, где вы вызываете [schema]. [TableName] (в основном, где бы вы ни ссылались на поле) и убедитесь, что все написано правильно.

Лично я стараюсь избегать этого, используя псевдонимы для всех моих таблиц. Это очень помогает, когда вы можете сократить длинное имя таблицы до аббревиатуры описания (т.е. WorkOrderParts → WOP), а также сделать ваш запрос более удобочитаемым.

Изменить: в качестве дополнительного бонуса вы будете сохранять TONS нажатий клавиш, когда все, что вам нужно набрать, это трех или четырехбуквенный псевдоним вместе с именами схемы, таблицы и поля.

Ответ 4

Binding = ваше текстовое представление определенного столбца сопоставляется с физическим столбцом в некоторой таблице в некоторой базе данных на каком-то сервере.

Многостраничный идентификатор может быть: MyDatabase.dbo.MyTable. Если вы ошиблись в любом из этих идентификаторов, у вас есть идентификатор multipart, который нельзя сопоставить.

Лучший способ избежать этого - правильно написать запрос в первый раз или использовать плагин для студии управления, который обеспечивает intellisense и, таким образом, поможет вам избежать опечаток.

Ответ 5

У вас, вероятно, есть опечатка. Например, если у вас есть таблица с именем Customer в базе данных с именем Sales, вы можете ссылаться на нее как на Sales..Customer(хотя лучше обратиться к ней, включая имя владельца (dbo является владельцем по умолчанию), например Sales.dbo.Customer.

Если вы ввели Sales... Customer, вы могли получить сообщение, которое у вас есть.

Ответ 6

Если вы уверены, что это не опечатка, возможно, это опечатка по делу.

Какую сортировку вы используете? Проверьте его.

Ответ 7

Я обнаружил, что получаю это много, когда я пытаюсь сокращать, например:

Table1 t1, Table2 t2 
where t1.ID = t2.ID

Изменение его на:

Table1, Table2 
where Table1.ID = Table2.ID

Делает запрос работой и не выдает ошибку.

Ответ 8

При обновлении таблиц убедитесь, что вы не ссылаетесь на поле вашего обновления через псевдоним.

У меня была ошибка со следующим кодом

update [page] 
set p.pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0

Мне пришлось удалить ссылку alias в инструкции set, чтобы она читалась следующим образом

update [page] 
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0

Ответ 9

У меня была эта проблема, и это оказалось неправильным псевдонимом таблицы. Исправление этого разрешило проблему.

Ответ 10

Шахта ошибочно помещала схему на стол псевдонима:

SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1  -- oops!

Ответ 11

У меня было P.PayeeName AS 'Payer' --, и две строки комментариев сбросили эту ошибку

Ответ 12

Я действительно забыл присоединиться к таблице другим, почему я получил ошибку

Предполагается, что это так:

  CREATE VIEW reserved_passangers AS
  SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
  FROM dbo.Passenger, dbo.Reservation, dbo.Flight
  WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
  (dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum =562)

И не так:

  CREATE VIEW reserved_passangers AS
  SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
  FROM dbo.Passenger, dbo.Reservation
  WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
  (dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum = 562)

Ответ 13

Код ошибки

FROM                
    dbo.Category C LEFT OUTER JOIN           
    dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN          
    dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN          
    dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN 
    dbo.trainer ON dbo.trainer.TopicID =dbo.SubModule.subModuleID 

Код решения

 FROM                
    dbo.Category C LEFT OUTER JOIN           
    dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN          
    dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN          
    dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN 
    dbo.trainer ON dbo.trainer.TopicID = SM.subModuleID 

Как вы можете видеть, в коде ошибки dbo.SubModule уже определен как SM, но я использую dbo.SubModule в следующей строке, поэтому произошла ошибка. используйте объявленное имя вместо фактического имени. Задача решена.

Ответ 14

Мой лучший совет при наличии ошибки - использовать [] скобки для сортировки имен таблиц, сокращение таблиц иногда приводит к ошибкам (иногда сокращения таблиц работают просто отлично... странно)

Ответ 15

Добавление псевдонима таблицы перед полем Set вызывает эту проблему в моем случае.

Справа Обновление таблицы 1 Установите SomeField = t2.SomeFieldValue из таблицы 1 t1 Внутреннее соединение таблицы 2 как t2 на t1.ID = t2.ID

Неправильное обновление таблицы 1 Установите t1.SomeField = t2.SomeFieldValue из таблицы 1 t1 Внутреннее соединение таблицы 2 как t2 на t1.ID = t2.ID

Ответ 16

Я получал эту ошибку и просто не мог видеть, где проблема. Я дважды проверил все свои псевдонимы и синтаксис, и ничто не выглядело неуместным. Запрос был похож на те, которые я пишу все время.

Я решил просто переписать запрос (я изначально скопировал его из файла отчета .rdl) ниже, снова, и он работал нормально. Глядя на запросы сейчас, они выглядят одинаково для меня, но мой переписанный работает.

Просто хотел сказать, что это может стоить того, чтобы ничего не получалось.