Что такое "многосоставный идентификатор" и почему он не может быть привязан?
Я постоянно получаю эти ошибки, когда я пытаюсь обновить таблицу на основе другой таблицы. Я в конечном итоге переписываю запрос, изменяю порядок соединений, изменяю некоторые группировки, а затем он в конечном итоге работает, но я просто не совсем понимаю его.
что такое "многосоставный идентификатор"?
Когда является составной идентификатор не может быть привязан?
Что это все равно неизбежно?
В каких случаях произойдет эта ошибка?
Каковы наилучшие способы предотвратить это?
конкретная ошибка от 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.ДБО.Компания.COMPANYNAME " не может быть связан.
14 ответов:
составной идентификатор - это любое описание поля или таблицы, содержащее несколько частей, например MyTable.Так или иначе - если он не может быть связан, это означает, что с ним что-то не так-либо у вас есть простая опечатка, либо путаница между таблицей и столбцом. Это также может быть вызвано использованием зарезервированных слов в именах таблиц или полей и не окружать их [].
что-то вроде redgate SQL prompt гениально для избежания вручную введите их (он даже автоматически завершает соединения на основе внешних ключей), но не является бесплатным. SQL server 2008 поддерживает intellisense из коробки, хотя это не совсем так полно, как версия redgate.
на самом деле иногда, когда вы обновляете одну таблицу из данных другой таблицы, я думаю, что одна из распространенных проблем, вызывающих эту ошибку, заключается в том, что вы неправильно используете аббревиатуры таблиц или когда они не нужны. Правильное утверждение находится ниже:
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оператор вернет многосоставную ошибку, которую вы заметили.
Это, вероятно, опечатка. Найдите места в коде, где вы вызываете [schema].[TableName] (в основном везде, где вы ссылаетесь на поле) и убедитесь, что все написано правильно.
лично я стараюсь избегать этого, используя псевдонимы для всех моих таблиц. Это очень помогает, когда вы можете сократить длинное имя таблицы до аббревиатуры его описания (т. е. WorkOrderParts -> WOP), а также делает ваш запрос более читаемым.
Edit: в качестве дополнительного бонуса вы сохраните Тонны нажатий клавиш, когда все, что вам нужно ввести,-это трех-или четырехбуквенный псевдоним по сравнению со схемой, таблицей и именами полей вместе.
Binding = ваше текстовое представление определенного столбца сопоставляется с физическим столбцом в некоторой таблице, в некоторой базе данных, на некотором сервере.
составной идентификатор может быть: MyDatabase.ДБО.таблица MyTable. Если вы получаете любой из этих идентификаторов неправильно, то у вас есть составной идентификатор, который не может быть сопоставлен.
лучший способ избежать этого-написать запрос правильно в первый раз или использовать плагин для Management studio, который предоставляет intellisense и таким образом помогает вам избегая опечаток.
Если вы уверены, что это не опечатка по орфографии, возможно, это опечатка по регистру.
какие параметры сортировки вы используете? Это проверить.
при обновлении таблиц убедитесь, что вы не ссылаетесь на поле вашего обновления через псевдоним.
у меня просто была ошибка со следующим кодом
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
я обнаружил, что я получаю их много, когда я пытаюсь сократить, например:
Table1 t1, Table2 t2 where t1.ID = t2.IDизменить его на:
Table1, Table2 where Table1.ID = Table2.IDделает запрос работать и не выбрасывать ошибку.
У вас, наверное, опечатка. Например, если у вас есть таблица с именем Customer в базе данных Sales, вы можете ссылаться на нее как на Sales..Клиент (хотя лучше ссылаться на него, включая имя владельца (dbo является владельцем по умолчанию), как продажи.ДБО.Клиент.
Если вы набрали от продаж...Клиент, вы могли бы получить сообщение, которое вы получили.
У меня была эта проблема, и она оказалась неправильным псевдонимом таблицы. Исправление этого решило проблему.
мой ставил схему на псевдоним таблицы по ошибке:
SELECT * FROM schema.CustomerOrders co WHERE schema.co.ID = 1 -- oops!
Я на самом деле забыл присоединиться к таблице с другими, поэтому я получил ошибку
должно быть:
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в следующей строке, поэтому произошла ошибка. используйте объявленное имя вместо фактического имени. Проблема решена.
мой лучший совет при наличии ошибки-использовать [] braquets для сортировки имен таблиц, аббревиатура таблиц иногда вызывает ошибки (иногда аббревиатуры таблиц просто работают нормально...странно)
Comments