Что такое «многокомпонентный идентификатор» и почему его нельзя связать? - PullRequest
115 голосов
/ 16 октября 2008

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

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

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

Ответы [ 17 ]

81 голосов
/ 16 октября 2008

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

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

48 голосов
/ 20 июня 2011

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

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

16 голосов
/ 16 октября 2008

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

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

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

5 голосов
/ 16 октября 2008

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

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

5 голосов
/ 16 октября 2008

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

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

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

4 голосов
/ 26 мая 2011

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

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

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

Table1, Table2 
where Table1.ID = Table2.ID

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

4 голосов
/ 16 октября 2008

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

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

4 голосов
/ 20 июня 2012

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

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

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
2 голосов
/ 16 февраля 2013

Шахта кладет схему на таблицу Alias ​​по ошибке:

SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1  -- oops!
2 голосов
/ 15 декабря 2011

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

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