Co to jest „identyfikator wieloczęściowy” i dlaczego nie można go powiązać?

137

Ciągle otrzymuję te błędy, gdy próbuję zaktualizować tabele na podstawie innej tabeli. W końcu przepisuję zapytanie, zmieniam kolejność złączeń, zmieniam niektóre grupy i ostatecznie to działa, ale po prostu nie do końca rozumiem.

Co to jest „identyfikator wieloczęściowy”?
Kiedy nie można powiązać „identyfikatora wieloczęściowego”?
Z czym to się wiąże?
W jakich przypadkach wystąpi ten błąd?
Jakie są najlepsze sposoby, aby temu zapobiec?

Konkretny błąd z SQL Server 2005 to:

Nie można powiązać wieloczęściowego identyfikatora „...”.

Oto przykład:

UPDATE  [test].[dbo].[CompanyDetail]

SET Mnemonic = [dbBWKMigration].[dbo].[Company].[MNEMONIC], 
               [Company Code] = [dbBWKMigration].[dbo].[Company].[COMPANYCODE]

WHERE [Company Name] = **[dbBWKMigration].[dbo].[Company].[COMPANYNAME]**

Rzeczywisty błąd:

Msg 4104, poziom 16, stan 1, wiersz 3 Nie można powiązać wieloczęściowego identyfikatora „dbBWKMigration.dbo.Company.COMPANYNAME”.

Nawet Mien
źródło

Odpowiedzi:

101

Identyfikator wieloczęściowy to dowolny opis pola lub tabeli, który zawiera wiele części - na przykład MyTable.SomeRow - jeśli nie można go powiązać, oznacza to, że jest z nim coś nie tak - albo masz prostą literówkę, albo pomyłkę tabela i kolumna. Może to być również spowodowane użyciem słów zastrzeżonych w nazwach tabeli lub pól i nie otaczaniem ich znakiem []. Może to być również spowodowane brakiem wszystkich wymaganych kolumn w tabeli docelowej.

Coś w rodzaju zachęty redgate sql jest genialne, aby uniknąć konieczności ręcznego wpisywania tych znaków (nawet automatycznie uzupełnia łączenia na podstawie kluczy obcych), ale nie jest darmowe. SQL Server 2008 obsługuje technologię Intellisense po wyjęciu z pudełka, chociaż nie jest tak kompletna, jak wersja redgate.

Śmigać
źródło
6
Wciąż aktualne: Twoja podpowiedź dotycząca literówki uratowała mi dzień.
Stefan,
Komentarz do oszczędzania dnia dla nowicjuszy: po prostu sprawdź swoją literówkę, czasami pojawia się, gdy brakuje ci małego elementu. W moim wydaniu był to OBJECT_ID (Schema.Table) bez żadnych cudzysłowów w zapytaniu zawierającym ponad 50 wierszy.
Abdullah Ilgaz
57

Właściwie czasami, gdy aktualizujesz jedną tabelę z danych innej tabeli, myślę, że jednym z typowych problemów, które powodują ten błąd, jest nieprawidłowe użycie skrótów tabeli lub gdy nie są one potrzebne . Prawidłowe stwierdzenie znajduje się poniżej:

Update Table1
Set SomeField = t2.SomeFieldValue 
From Table1 t1 
Inner Join Table2 as t2
    On t1.ID = t2.ID

Zwróć uwagę, że SomeFieldkolumna z tabeli Table1 nie ma t1kwalifikatora jako, t1.SomeFieldale jest po prostu SomeField.

Jeśli ktoś spróbuje go zaktualizować, podając t1.SomeFieldinstrukcję, zwróci wieloczęściowy błąd, który zauważyłeś.

amadelle
źródło
3
Dodanie aliasu tabeli przed polem Set powoduje ten problem w moim przypadku.
Malhaar Punjabi
1
To też był mój problem. Miałem SET ABBREVIATION.My_Field, kiedy tylko potrzebowałem SET.My_Field;
VSO
Pobiegłem do tego błędu podczas korzystania z OPENJSON. `FROM cust c OUTER APPLY OPENJSON (cust.Adreses)` zwrócił błąd. `FROM cust c OUTER APPLY OPENJSON (c.Adresies)` zwrócił
zestaw wyników
Pomocne
17

To prawdopodobnie literówka. Poszukaj miejsc w swoim kodzie, w których wywołujesz [schema]. [TableName] (w zasadzie wszędzie tam, gdzie odwołujesz się do pola) i upewnij się, że wszystko jest poprawnie napisane.

Osobiście staram się tego uniknąć, używając aliasów dla wszystkich moich tabel. Ogromnie pomaga, gdy można skrócić długą nazwę tabeli do akronimu jej opisu (np. WorkOrderParts -> WOP), a także sprawia, że ​​zapytanie jest bardziej czytelne.

Edycja: jako dodatkowy bonus zaoszczędzisz TONY naciśnięć klawiszy, gdy wszystko, co musisz wpisać, to trzy- lub czteroliterowy alias w porównaniu ze schematem, tabelą i nazwami pól razem.

Porucznik Frost
źródło
6

Binding = twoja tekstowa reprezentacja określonej kolumny jest odwzorowywana na fizyczną kolumnę w jakiejś tabeli, w jakiejś bazie danych, na jakimś serwerze.

Identyfikatorem wieloczęściowym może być: MyDatabase.dbo.MyTable. Jeśli którykolwiek z tych identyfikatorów jest nieprawidłowy, oznacza to, że masz identyfikator wieloczęściowy, którego nie można zmapować.

Najlepszym sposobem uniknięcia tego jest prawidłowe napisanie zapytania za pierwszym razem lub użycie wtyczki do studia zarządzania, która zapewnia inteligencję, a tym samym pomaga uniknąć literówek.

Mark S. Rasmussen
źródło
5

Prawdopodobnie masz literówkę. Na przykład, jeśli masz tabelę o nazwie Customer w bazie danych o nazwie Sales, możesz odnieść się do niej jako Sales..Customer (chociaż lepiej jest odwołać się do niej z nazwą właściciela (domyślnym właścicielem jest dbo), na przykład Sales.dbo .Klient.

Jeśli wpiszesz Sales ... Customer, być może otrzymałeś wiadomość.

HLGEM
źródło
4

Jeśli jesteś pewien, że nie jest to literówka pod względem pisowni, być może jest to literówka uwzględniająca wielkość liter.

Jakiego sortowania używasz? Sprawdź to.

DBA w Pittsburghu
źródło
4

Podczas aktualizowania tabel upewnij się, że nie odwołujesz się do pola podczas aktualizacji za pośrednictwem aliasu.

Właśnie wystąpił błąd z następującym kodem

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

Musiałem usunąć odwołanie do aliasu w instrukcji set, więc wygląda to tak

update [page] 
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
Upio
źródło
4

Zauważyłem, że często je dostaję, kiedy próbuję skrócić, na przykład:

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

Zmiana na:

Table1, Table2 
where Table1.ID = Table2.ID

Sprawia, że ​​zapytanie działa i nie zgłasza błędu.

jo-mso
źródło
3

Kod błędu

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 

Kod rozwiązania

 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 

jak widać w kodzie błędu dbo.SubModulejest już zdefiniowany jako SM ale ja używam dbo.SubModulew następnej linii stąd wystąpił błąd. użyj zadeklarowanej nazwy zamiast rzeczywistej nazwy. Problem rozwiązany.

Onkar Vidhate
źródło
2

Miałem ten problem i okazało się, że jest to nieprawidłowy alias tabeli. Rozwiązanie tego problemu rozwiązało problem.

Matt Setter
źródło
2

Mój przez pomyłkę umieszczał schemat na stole Alias:

SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1  -- oops!
nieznane
źródło
2

Dodanie aliasu tabeli przed polem Set powoduje ten problem w moim przypadku.

Prawa tabela aktualizacji 1 Ustaw SomeField = t2.SomeFieldValue From Table1 t1 Inner Join Table2 as t2 On t1.ID = t2.ID

Nieprawidłowa aktualizacja tabeli1 Ustaw t1.SomeField = t2.SomeFieldValue z tabeli1 t1 Inner Join Table2 as t2 On t1.ID = t2.ID

Malhaar Punjabi
źródło
1

Miałem P.PayeeName AS 'Payer' --, i dwie linie komentarza zwróciły ten błąd

Andrew Day
źródło
1

Właściwie zapomniałem dołączyć do stołu do innych, dlatego dostałem błąd

Miało tak być:

  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)

A nie w ten sposób:

  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)
MT_Shikomba
źródło
1

Moją najlepszą radą w przypadku błędu jest użycie [] braquets do otaczających nazw tabel, skrót tabel powoduje czasami błędy (czasami skróty tabel po prostu działają dobrze ... dziwne)

ramnz
źródło
1

Otrzymałem ten błąd i po prostu nie mogłem zobaczyć, gdzie jest problem. Dokładnie sprawdziłem wszystkie moje aliasy i składnię i nic nie wyglądało na niewłaściwe. Pytanie było podobne do tego, które piszę cały czas.

Postanowiłem po prostu ponownie napisać zapytanie (pierwotnie skopiowałem je z pliku raportu .rdl) poniżej, jeszcze raz i działało dobrze. Patrząc teraz na zapytania, wyglądają one tak samo, ale moje przepisane pytanie działa.

Chciałem tylko powiedzieć, że może warto spróbować, jeśli nic innego nie działa.

clamum
źródło
1

Po wpisaniu tabeli FROM te błędy znikną. Wpisz FROM poniżej tego, co wpisujesz, a następnie Intellisense będzie działać i będzie działać identyfikator wieloczęściowy.

David Morrow
źródło
0

Zmierzyłem się z tym problemem i rozwiązałem go, ale jest różnica między Twoim a moim kodem. Mimo to myślę, że możesz zrozumieć, co to jest „nie można powiązać wieloczęściowego identyfikatora”

Kiedy użyłem tego kodu

 select * from tbTest where email = sakira@gmail.com

Napotkałem problem z identyfikatorem wieloczęściowym

ale kiedy używam pojedynczego cudzysłowu dla adresu e-mail To rozwiązane

 select * from tbTest where email = '[email protected]'
Neloy Sarothi
źródło