web-dev-qa-db-fra.com

Qu'est-ce qu'un "identifiant en plusieurs parties" et pourquoi ne peut-il pas être lié?

Je reçois continuellement ces erreurs lorsque j'essaie de mettre à jour des tables basées sur une autre table. Je finis par réécrire la requête, modifier l'ordre des jointures, modifier certains regroupements, puis tout fonctionne, mais je ne comprends tout simplement pas.

Qu'est-ce qu'un "identifiant en plusieurs parties"?
Quand un 'identifiant en plusieurs parties' ne peut-il pas être lié?
À quoi est-il lié de toute façon?
Dans quels cas cette erreur se produira-t-elle?
Quels sont les meilleurs moyens de le prévenir? 

L'erreur spécifique de SQL Server 2005 est la suivante:

L'identifiant en plusieurs parties "..." n'a pas pu être lié.

Voici un exemple:

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

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

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

L'erreur réelle:

Msg 4104, Niveau 16, État 1, Ligne 3 Identificateur en plusieurs parties "dbBWKMigration.dbo.Company.COMPANYNAME" n'a pas pu être lié.

108
Even Mien

Un identificateur multipart est une description d’un champ ou d’une table contenant plusieurs parties - par exemple, MyTable.SomeRow - s’il ne peut pas être lié, cela signifie que quelque chose ne va pas, soit vous avez une simple faute de frappe, soit une confusion entre table et colonne. Cela peut également être provoqué par l’utilisation de mots réservés dans les noms de table ou de champ sans les entourer de [].

Quelque chose comme redgate sql Prompt est génial pour éviter d’avoir à les taper manuellement (il complète même automatiquement les jointures en fonction de clés étrangères), mais n’est pas gratuit. SQL Server 2008 prend en charge intellisense immédiatement, bien que ce ne soit pas aussi complet que la version redgate.

78
Whisk

En fait, parfois, lorsque vous mettez à jour une table à partir des données d’une autre table, je pense que l’un des problèmes courants à l’origine de cette erreur réside dans l’utilisation incorrecte de vos abréviations de table ou lorsqu’elles ne sont pas nécessaires. La déclaration correcte est ci-dessous:

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

Notez queSomeFieldcolumn from Table1 n'a pas le qualificatif t1 en tant quet1.SomeFieldmais est simplement SomeField

Si vous essayez de le mettre à jour en spécifiantt1.SomeField, l'instruction retournera l'erreur en plusieurs parties que vous avez remarquée.

45
amadelle

C'est probablement une faute de frappe. Recherchez les endroits de votre code où vous appelez [schéma]. [Nom de la table] (en gros où vous référencez un champ) et assurez-vous que tout est orthographié correctement.

Personnellement, j'essaie d'éviter cela en utilisant des alias pour toutes mes tables. Il est extrêmement utile de pouvoir raccourcir un nom de table long en un acronyme de sa description (par exemple, WorkOrderParts -> WOP) et de rendre votre requête plus lisible.

Éditer: En prime, vous économiserez des TONNES de frappe lorsque tout ce que vous aurez à taper sera un alias de trois ou quatre lettres au lieu des noms de schéma, de table et de champ.

15
Lieutenant Frost

Liaison = votre représentation textuelle d'une colonne spécifique est mappée à une colonne physique dans une table, une base de données ou un serveur.

L'identifiant en plusieurs parties peut être: MyDatabase.dbo.MyTable. Si l'un de ces identificateurs est incorrect, vous disposez d'un identificateur en plusieurs parties qui ne peut pas être mappé.

La meilleure façon de l'éviter est d'écrire la requête correctement la première fois ou d'utiliser un plug-in pour studio de gestion qui fournit intellisense et vous aidera ainsi en évitant les fautes de frappe.

4
Mark S. Rasmussen

Lors de la mise à jour des tables, assurez-vous de ne pas référencer le champ lors de la mise à jour via l'alias.

Je viens d'avoir l'erreur avec le code suivant

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

Je devais supprimer la référence de pseudonyme dans la déclaration set afin qu'elle se lise comme ceci

update [page] 
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
3
Upio

J'ai constaté que je les ai souvent lorsque j'essaie d'abréger, par exemple:

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

Le changer pour: 

Table1, Table2 
where Table1.ID = Table2.ID

Fait fonctionner la requête et ne pas jeter l'erreur.

3
jo-mso

Vous avez probablement une faute de frappe. Par exemple, si vous avez une table nommée Client dans une base de données nommée Sales, vous pouvez vous y référer en tant que Sales..Customer (bien qu'il soit préférable de s'y référer, y compris le nom du propriétaire (dbo est le propriétaire par défaut) comme Sales.dbo. .Client.

Si vous avez tapé Sales ... Customer, vous avez peut-être reçu le message que vous avez reçu.

3
HLGEM

Si vous êtes sûr que ce n'est pas une faute de frappe orthographique, c'est peut-être une faute de frappe.

Quelle collation utilisez-vous? Vérifie ça.

3
Pittsburgh DBA

J'ai eu ce problème et il s'est avéré être un alias de table incorrect. Corriger ceci a résolu le problème.

1
Matt Setter

Le mien posait le schéma sur la table Alias ​​par erreur:

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

Code d'erreur

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 

Code de solution

 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 

comme vous pouvez le constater, dans le code d'erreur, dbo.SubModule est déjà défini en tant que SM, mais j'utilise dbo.SubModule à la ligne suivante. Il y a donc une erreur . utilisez le nom déclaré au lieu du nom réel. Problème résolu.

0
Onkar Vidhate

Lorsque vous tapez la table FROM, ces erreurs disparaissent. Tapez FROM en dessous de votre frappe, puis Intellisense fonctionnera et l'identificateur en plusieurs parties fonctionnera.

0
David Morrow

En fait, j'ai oublié de rejoindre la table aux autres c'est pourquoi j'ai l'erreur

Censé être de cette façon:

  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)

Et pas de cette façon:

  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)
0
MT_Shikomba

J'avais cette erreur et je ne pouvais tout simplement pas voir où était le problème. J'ai vérifié tous mes alias et ma syntaxe et rien ne semblait hors de propos. La requête était semblable à celle que j'écris tout le temps.

J'ai décidé de réécrire simplement la requête (je l'avais initialement copiée à partir d'un fichier de rapport .rdl) ci-dessous, à nouveau, et tout s'est bien déroulé. En regardant les questions maintenant, elles me ressemblent, mais celle que j'ai réécrite fonctionne.

Je voulais juste dire que ça pourrait valoir le coup si rien d’autre ne marche.

0
clamum

Le meilleur conseil que je puisse avoir quand l'erreur est d'utiliser des crochets [] pour entourer les noms de table, l'abréviation de table provoque parfois des erreurs (parfois, les abréviations de table fonctionnent très bien ... bizarre)

0
ramnz

L'ajout d'alias de table dans le champ Set provoque ce problème dans mon cas. 

Droite Mettez à jour Table1 Définissez SomeField = t2.SomeFieldValue À partir de Table1 t1 Inner Join Table2 comme t2 Sur t1.ID = t2.ID

Wrong Update Table1 Définissez t1.SomeField = t2.SomeFieldValue De Table1 t1 Inner Join Table2 comme t2 Sur t1.ID = t2.ID

0
Malhaar Punjabi

J'ai eu P.PayeeName AS 'Payer' --, Et les deux lignes de commentaire ont jeté cette erreur

0
Andrew Day