2008-10-15 5 views
96

Je reçois continuellement ces erreurs lorsque j'essaie de mettre à jour des tables en fonction d'une autre table. Je finis par réécrire la requête, changer l'ordre des jointures, changer certains groupements et finalement ça marche, mais je ne comprends pas tout à fait.Qu'est-ce qu'un 'identificateur multi-parties' et pourquoi ne peut-il pas être lié?

Qu'est-ce qu'un 'identificateur multi-parties'?
Quand un 'identificateur multi-parties' ne peut-il pas être lié?
De quoi s'agit-il quand même?
Dans quels cas cette erreur se produit-elle?
Quels sont les meilleurs moyens de l'empêcher?

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

The multi-part identifier "..." could not be bound.

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, Level 16, State 1, Line 3 The multi-part identifier "dbBWKMigration.dbo.Company.COMPANYNAME" could not be bound.

Répondre

72

Un identificateur multi-parties 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 qu'il y a un problème - soit vous avez une simple faute de frappe, ou une confusion entre table et colonne. Il peut également être provoqué en utilisant des mots réservés dans vos noms de table ou de champ et ne pas les entourer de [].

Quelque chose comme redgate sql prompt est brillant pour éviter d'avoir à taper manuellement ces derniers (il complète même automatiquement les jointures basées sur des clés étrangères), mais n'est pas gratuit. SQL Server 2008 prend en charge IntelliSense dès sa sortie de l'emballage, bien qu'il ne soit pas aussi complet que la version Redgate.

+0

Still réelle: votre faute de frappe indice a sauvé ma journée. – Stefan

4

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

L'identifiant en plusieurs parties pourrait être: MyDatabase.dbo.MyTable. Si l'un de ces identifiants est incorrect, vous avez un identifiant en plusieurs parties qui ne peut pas être mappé. Le meilleur moyen de l'éviter est d'écrire la requête dès la première fois, ou d'utiliser un plugin pour le studio de gestion qui fournit intellisense et ainsi vous aider en évitant les fautes de frappe.

3

Vous avez probablement une faute de frappe. Par exemple, si vous avez une table nommée Customer dans une base de données nommée Sales, vous pouvez vous référer à 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 .Customer.

Si vous tapez ... client Sales, vous pourriez avoir reçu le message que vous avez obtenu.

13

Il est probablement une faute de frappe. Recherchez les endroits dans votre code où vous appelez [schéma]. [TableName ] (fondamentalement partout où vous faites référence à 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 aide énormément quand vous pouvez raccourcir un long nom de table à un acronyme de cela s description (c.-à-d. WorkOrderParts -> WOP), et rend également votre requête plus lisible. Edit: En bonus, vous économiserez des TONS de frappes lorsque tout ce que vous devez taper est un alias de trois ou quatre lettres par rapport aux noms de schéma, de table et de champ tous ensemble.

3

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

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

3

Je trouve que je reçois ces beaucoup lorsque je tente de abrégez, tels que:

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

Changer à:

Table1, Table2 
where Table1.ID = Table2.ID 

rend le travail de recherche et ne pas jeter l'erreur.

+0

Oh, cela a résolu mon problème. Merci beaucoup ! –

39

En fait, lorsque vous mettez à jour une table à partir des données d'une autre table, l'un des problèmes courants provoquant cette erreur est lorsque vous utilisez incorrectement vos abréviations ou. La déclaration correcte est la suivante:

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

Notez que SomeField colonne de Tableau 1 ne pas le qualificatif t1 comme t1.SomeField mais est juste SomeField.

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

+1

Merci! +1 Dans mon cas, c'était le problème. – Sabuncu

0

J'ai eu ce problème et il s'est avéré être un alias de table incorrect. Corriger cela a résolu le problème. Lors de la mise à jour des tables, assurez-vous de ne pas référencer le champ de votre mise à jour via l'alias

3

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 d'alias dans l'instruction set il se lit comme ce

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

mine a été de mettre le schéma sur la Alias ​​de table par erreur:

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

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

0

J'ai oublié en fait à se joindre à la table aux autres qui est la raison pour laquelle je suis l'erreur

Censé être ainsi:

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

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 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 voir, le code d'erreur, dbo.SubModule est déjà définie comme SM, mais je me sers dbo.SubModule dans la ligne suivante, donc il y avait une erreur. utilise le nom déclaré au lieu du nom réel. Problème résolu.

0

Mon meilleur conseil en ayant l'erreur est d'utiliser [] braquets pour SORROUND noms de table, l'abréviation des tables provoque parfois des erreurs, (abréviations de table parfois fonctionnent très bien ... bizarre)

Questions connexes