Що таке "ідентифікатор з декількома частинами" і чому його не можна зв'язати?


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]**

Фактична помилка:

Msg 4104, рівень 16, стан 1, рядок 3 Ідентифікатор багаточастин "dbBWKMigration.dbo.Company.COMPANYNAME" не вдалося зв'язати.

Відповіді:


101

Багаточастинний ідентифікатор - це будь-який опис поля чи таблиці, що містить кілька частин - наприклад, MyTable.SomeRow - якщо його не можна пов'язати, це означає, що з ним щось не так - або у вас проста помилка друку, або плутанина між таблиця та стовпчик. Також це може бути викликано використанням зарезервованих слів у назвах таблиці чи полів, а не оточенні їх []. Це також може бути спричинене не включенням усіх необхідних стовпців у цільову таблицю.

Щось на зразок Redgate sql підказки є геніальним для того, щоб уникнути необхідності вводити їх вручну (він навіть автоматично завершує приєднання на основі іноземних ключів), але не є безкоштовним. SQL-сервер 2008 підтримує інтеліссенс поза коробкою, хоча він не настільки повний, як версія 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
Додавання псевдоніму таблиці перед полем Встановити викликає цю проблему в моєму випадку.
Малхаар Пенджабі

1
Це була і моя проблема. У мене було SET ABBREVIATION.My_Field, коли мені просто було потрібно SET.My_Field;
VSO

Я зіткнувся з цією помилкою під час використання OPENJSON. `З КОРОЗУ ЗОВНІШНЬОГО ЗАСТОСУВАННЯ OPENJSON (cust.Addresses)` видав помилку `ВІД КРАСУ ЗОВ'ЯЗКОВОЇ ЗАЯВКИ OPENJSON (c.Adresses)` дав результат
набору

Ви можете знайти пояснення з sqlservertutorial.net/sql-server-basics/sql-server-update- приєднатися до корисного:
CAtoOH

17

Це, мабуть, помилка друку. Шукайте місця у вашому коді, де ви викликаєте [схему]. [Таблиця] (в основному будь-де ви посилаєтесь на поле) і переконайтеся, що все написано правильно.

Особисто я намагаюся уникати цього, використовуючи псевдоніми для всіх своїх таблиць. Це надзвичайно допомагає, коли ви можете скоротити довге ім’я таблиці до абревіатури його опису (тобто WorkOrderParts -> WOP), а також зробить ваш запит більш читабельним.

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


6

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

Багатопоточним ідентифікатором може бути: MyDatabase.dbo.MyTable. Якщо ви неправильно визначили будь-який з цих ідентифікаторів, у вас є багаточастинний ідентифікатор, який неможливо відобразити.

Найкращий спосіб уникнути цього - написати запит правильно з першого разу або використовувати плагін для студії управління, яка забезпечує інтелігенцію і тим самим допоможе вам, уникаючи помилок.


5

У вас, певно, є помилка друку. Наприклад, якщо у базі даних з назвою Продаж є таблиця з назвою Клієнт, ви можете посилатися на неї як Продаж. Замовник (хоча краще посилатися на неї, включаючи ім'я власника (dbo - власник за замовчуванням), наприклад Sales.dbo .Замовник.

Якщо ви набрали Sales ... Клієнт, можливо, ви отримали повідомлення, яке ви отримали.


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

Мені довелося видалити посилання на псевдонім у встановленому операторі, щоб воно було таким чином

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

Шахта помилково ставила схему на стіл Псевдонім:

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

2

Додавання псевдоніму таблиці перед полем Встановити викликає цю проблему в моєму випадку.

Права таблиця оновлення1 Встановіть SomeField = t2.SomeFieldValue з таблиці1 t1 Внутрішня приєднана таблиця2 як t2 В t1.ID = t2.ID

Неправильне оновлення Table1 Set t1.SomeField = t2.SomeFieldValue Від Table1 t1 INNER JOIN Table2 як 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

Коли ви введете таблицю ВІД, ці помилки зникнуть. Введіть ВІД нижче того, що буде введено, а 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.