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



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



что такое "многосоставный идентификатор"?

Когда является составной идентификатор не может быть привязан?

Что это все равно неизбежно?

В каких случаях произойдет эта ошибка?

Каковы наилучшие способы предотвратить это?



конкретная ошибка от 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 " не может быть связан.


825   14  

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!

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

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

Comments

    Ничего не найдено.