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”.

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.


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ś.


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


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.


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.


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ść.


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.


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

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.


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.


2

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


2

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

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

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


1

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


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)

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)


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.


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.


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 = 'sakira@gmail.com'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.