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

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

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

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

The multi-part identifier "..." could not be bound.

Вот пример:

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, Level 16, State 1, Line 3 The multi-part identifier "dbBWKMigration.dbo.Company.COMPANYNAME" could not be bound.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
145
0
438 928
18
Перейти к ответу Данный вопрос помечен как решенный

Ответы 18

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

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

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

Ответ принят как подходящий

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

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

Все еще актуально: ваша опечатка спасла мне день.

Stefan 05.02.2018 19:08

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

Abdullah Ilgaz 17.05.2020 19:51

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

Если вы набрали Продажи ... Клиент, возможно, вы получили то же сообщение.

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

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

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

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

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

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

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

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

Table1, Table2 
where Table1.ID = Table2.ID

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

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

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

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

Malhaar Punjabi 23.11.2018 01:55

Это тоже была моя проблема. У меня был НАБОР ABBREVIATION.My_Field, когда мне просто понадобился SET.My_Field;

VSO 28.01.2019 23:49

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

Shaakir 19.09.2019 13:05

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

CAtoOH 01.04.2020 16:09

Амадель, у тебя сильное кунг-фу. Это исправило это для меня !!

S.H.Bouwhuis 17.08.2020 15:33

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

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

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

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

Мой по ошибке помещал схему в таблицу Alias:

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

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

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

Предположительно так:

  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)

Код ошибки

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

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

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

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

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

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

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

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

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

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

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

 select * from tbTest where email = [email protected]

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

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

 select * from tbTest where email = '[email protected]'

Другие вопросы по теме