Что такое «составной идентификатор» и почему его нельзя связать?


137

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

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

Конкретная ошибка в 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]**

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

Сообщение 4104, уровень 16, состояние 1, строка 3 Не удалось связать идентификатор из нескольких частей "dbBWKMigration.dbo.Company.COMPANYNAME".

Ответы:


101

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

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


6
Все еще актуально: ваша подсказка опечатки спасла мой день.
Стефан

Дневной комментарий для новичков: просто проверьте свою опечатку, иногда это происходит, когда вы пропускаете маленький кусочек. В моем выпуске это был OBJECT_ID (Schema.Table) без кавычек в запросе из 50+ строк.
Абдулла Ильгаз

57

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

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

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

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


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

1
Это была и моя проблема. У меня был SET ABBREVIATION.My_Field, когда я просто нуждался SET.My_Field;
VSO

Я столкнулся с этой ошибкой при использовании OPENJSON. `ОТ cust c OUTER APPLY OPENJSON (cust.Addresses)` выдает ошибку. `ОТ Cust C OUTER APPLY OPENJSON (c.Addresses)` дал
набор результатов

Вы можете найти объяснение из sqlservertutorial.net/sql-server-basics/sql-server-update-join полезным:
CAtoOH

17

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

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

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


6

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

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

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


5

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

Если вы ввели Sales ... Customer, возможно, вы получили сообщение.


4

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

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


4

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

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

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

Мне пришлось удалить ссылку на псевдоним в операторе 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

4

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

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

Меняя это на:

Table1, Table2 
where Table1.ID = Table2.ID

Заставляет запрос работать и не выдает ошибку.


3

Код ошибки

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следующую строку, поэтому произошла ошибка. используйте объявленное имя вместо фактического имени. Задача решена.


2

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


2

Моя по ошибке выкладывала схему Alias ​​на стол:

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

2

Добавление псевдонима таблицы перед полем 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



1

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

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

  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)

1

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


1

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

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

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


1

При вводе таблицы FROM эти ошибки исчезнут. Введите FROM ниже того, что вы наберете, тогда Intellisense будет работать, и будет работать многокомпонентный идентификатор.


0

Я столкнулся с этой проблемой и решил ее, но есть разница между вашим и моим кодом. Несмотря на то, что я думаю, вы можете понять, что такое «не состоящий из нескольких частей идентификатор»

Когда я использовал этот код

 select * from tbTest where email = sakira@gmail.com

Я столкнулся с проблемой многокомпонентного идентификатора

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

 select * from tbTest where email = 'sakira@gmail.com'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.