O que é um 'identificador de várias partes' e por que não pode ser vinculado?

136

Eu recebo esses erros continuamente quando tento atualizar tabelas com base em outra tabela. Acabo reescrevendo a consulta, altero a ordem das junções, altero alguns agrupamentos e, eventualmente, funciona, mas não entendi direito.

O que é um 'identificador de várias partes'?
Quando um 'identificador de várias partes' não pode ser vinculado?
A que isso está sendo vinculado?
Em que casos esse erro ocorrerá?
Quais são as melhores maneiras de evitá-lo?

O erro específico do SQL Server 2005 é:

O identificador de várias partes "..." não pôde ser vinculado.

Aqui está um exemplo:

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

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

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

O erro real:

Msg 4104, Nível 16, Estado 1, Linha 3 O identificador de várias partes "dbBWKMigration.dbo.Company.COMPANYNAME" não pôde ser vinculado.

Even Mien
fonte

Respostas:

101

Um identificador de várias partes é qualquer descrição de um campo ou tabela que contém várias partes - por exemplo, MyTable.SomeRow - se não puder ser vinculado, significa que há algo errado com ele - você tem um erro de digitação simples ou uma confusão entre tabela e coluna. Também pode ser causado pelo uso de palavras reservadas nos nomes de suas tabelas ou campos e não envolvendo-as com []. Também pode ser causado pela não inclusão de todas as colunas necessárias na tabela de destino.

Algo como o prompt do redgate sql é brilhante para evitar a necessidade de digitar manualmente (até conclui automaticamente as junções com base em chaves estrangeiras), mas não é gratuito. O SQL Server 2008 suporta o intellisense imediatamente, embora não seja tão completo quanto a versão do redgate.

Whisk
fonte
6
Ainda atual: sua dica de erro de digitação salvou meu dia.
Stefan
Comentário de economia de dia para os recém-chegados: basta verificar seu erro de digitação, às vezes ocorre quando falta um pedacinho. No meu problema, era OBJECT_ID (Schema.Table) sem aspas em uma consulta de mais de 50 linhas.
Abdullah Ilgaz
57

Na verdade, às vezes, quando você está atualizando uma tabela a partir dos dados de outra tabela, acho que um dos problemas comuns que causam esse erro é quando você usa as abreviações da tabela incorretamente ou quando não são necessárias . A declaração correta está abaixo:

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

Observe que a SomeFieldcoluna da Tabela1 não possui o t1qualificador, t1.SomeFieldmas é apenasSomeField .

Se alguém tentar atualizá-lo especificando t1.SomeFielda instrução, retornará o erro de várias partes que você notou.

amadelle
fonte
3
Adicionar alias de tabela no campo Set frontal causa esse problema no meu caso.
Malhaar Punjabi
1
Este foi o meu problema também. Eu tinha SET ABBREVIATION.My_Field, quando eu só precisava SET.My_Field;
VSO
Corri para esse erro ao usar o OPENJSON. `FROM cust c OUTER APPLY OPENJSON (cust.Addresses)` gerou o erro. `DE cust c EXTERIOR APLICAR OPENJSON (c.Addresses)` deu conjunto de resultados de volta
Shaakir
Você pode encontrar a explicação de sqlservertutorial.net/sql-server-basics/sql-server-update-join útil:
CAtoOH
17

Provavelmente é um erro de digitação. Procure os locais em seu código onde você chama [schema]. [TableName] (basicamente em qualquer lugar em que você referencie um campo) e verifique se tudo está escrito corretamente.

Pessoalmente, tento evitar isso usando aliases para todas as minhas tabelas. Ajuda tremendamente quando você pode encurtar um nome de tabela longo para um acrônimo de sua descrição (ou seja, WorkOrderParts -> WOP) e também torna sua consulta mais legível.

Editar: como um bônus adicional, você economizará TONELADAS de pressionamentos de tecla quando tudo o que você precisar digitar for um alias de três ou quatro letras versus o esquema, a tabela e os nomes de campos todos juntos.

Tenente Frost
fonte
6

Ligação = sua representação textual de uma coluna específica é mapeada para uma coluna física em alguma tabela, em algum banco de dados, em algum servidor.

O identificador de várias partes pode ser: MyDatabase.dbo.MyTable. Se você errar algum desses identificadores, possui um identificador de várias partes que não pode ser mapeado.

A melhor maneira de evitá-la é escrever a consulta corretamente na primeira vez ou usar um plug-in para o estúdio de gerenciamento que forneça inteligência e, assim, ajude você, evitando erros de digitação.

Mark S. Rasmussen
fonte
5

Você provavelmente tem um erro de digitação. Por exemplo, se você tiver uma tabela chamada Customer em um banco de dados chamado Sales, poderá se referir a ela como Sales..Customer (embora seja melhor fazer referência a ela incluindo o nome do proprietário (dbo é o proprietário padrão) como Sales.dbo .Cliente.

Se você digitou Vendas ... Cliente, pode ter recebido a mensagem que recebeu.

HLGEM
fonte
4

Se você tiver certeza de que não é um erro de ortografia, talvez seja um erro de digitação.

Que agrupamento você está usando? Verifique-o.

Pittsburgh DBA
fonte
4

Ao atualizar tabelas, certifique-se de não referenciar o campo como sua atualização por meio do alias.

Eu apenas tive o erro com o seguinte código

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

Eu tive que remover a referência de alias na instrução set para que fique assim

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
fonte
4

Descobri que recebo muito isso quando tento abreviar, como:

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

Alterando para:

Table1, Table2 
where Table1.ID = Table2.ID

Faz a consulta funcionar e não gera o erro.

jo-mso
fonte
3

Erro de código

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 

Código da solução

 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 

como você pode ver, no código de erro, dbo.SubModulejá está definido como SM, mas estou usando dbo.SubModulena próxima linha; portanto, ocorreu um erro. use o nome declarado em vez do nome real. Problema resolvido.

Onkar Vidhate
fonte
2

Eu tive esse problema e acabou sendo um alias de tabela incorreto. Corrigir isso resolveu o problema.

Matt Setter
fonte
2

O meu estava colocando o esquema na tabela Alias ​​por engano:

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

Adicionar alias de tabela no campo Set frontal causa esse problema no meu caso.

Atualização à direita Tabela1 Defina SomeField = t2.SomeFieldValue Da tabela1 t1 Associação interna Tabela2 como t2 Em t1.ID = t2.ID

Atualização incorreta Tabela1 Defina t1.SomeField = t2.SomeFieldValue Da tabela1 t1 Associação interna a tabela2 como t2 Em t1.ID = t2.ID

Malhaar Punjabi
fonte
1

Eu tinha P.PayeeName AS 'Payer' --, e as duas linhas de comentário lançaram este erro

Andrew Day
fonte
1

Na verdade, eu esqueci de juntar a mesa aos outros, por isso recebi o erro

Deveria ser assim:

  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)

E não desta maneira:

  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
fonte
1

Meu melhor conselho, ao ter o erro, é usar braquetes [] para contornar os nomes das tabelas; a abreviação de tabelas às vezes causa erros (algumas vezes as abreviações da tabela funcionam bem ... esquisitas)

ramnz
fonte
1

Eu estava recebendo esse erro e simplesmente não conseguia ver onde estava o problema. Eu verifiquei todos os meus apelidos e sintaxe e nada parecia fora do lugar. A consulta era semelhante à que eu escrevo o tempo todo.

Decidi reescrever a consulta (originalmente eu a copiei de um arquivo .rdl de relatório) abaixo, novamente, e ela correu bem. Olhando para as consultas agora, elas parecem iguais para mim, mas minha reescrita funciona.

Só queria dizer que pode valer a pena tentar se nada mais funcionar.

clamum
fonte
1

Quando você digita a tabela FROM, esses erros desaparecem. Digite FROM abaixo do que sua digitação, o Intellisense funcionará e o identificador de várias partes funcionará.

David Morrow
fonte
0

Eu enfrentei esse problema e o resolvi, mas há uma diferença entre o seu e o meu. Apesar de eu acho que você pode entender o que é "o identificador de várias partes não pôde ser vinculado"

Quando eu usei esse código

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

Enfrentei o problema do identificador de várias partes

mas quando eu uso aspas simples para o endereço de email Ele resolveu

 select * from tbTest where email = '[email protected]'
Neloy Sarothi
fonte