什么是'多部分标识符',为什么不能绑定?

问题描述:

当我尝试基于另一个表更新表时,我不断得到这些错误。我最终重写了查询,改变了连接的顺序,改变了一些分组,然后它最终起作用,但我只是不太明白。什么是'多部分标识符',为什么不能绑定?

什么是'多部分标识符'?
何时“多部分标识符”不能被绑定?
无论如何它受到了什么?
在哪些情况下会发生此错误?
防止它的最佳方法是什么?

从SQL Server 2005中特定的错误是:

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

下面是一个例子:

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

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

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

实际的错误:

Msg 4104, Level 16, State 1, Line 3 The multi-part identifier "dbBWKMigration.dbo.Company.COMPANYNAME" could not be bound.

多部分标识符是包含多个部分的字段或表的任何描述 - 例如MyTable.SomeRow - 如果它不能被绑定,那意味着它有什么问题 - 要么是简单的错字,或表和列之间的混淆。它也可能是由于在表格或字段名称中使用保留字造成的,而不是用[]包围它们。

redgate sql prompt之类的东西很适合避免必须手动输入这些内容(它甚至会根据外键自动完成连接),但不是免费的。 SQL Server 2008支持开箱即用的智能感知,尽管它并不像完整的redgate版本那么完整。

+0

不过实际:你的错字提示节省了我的一天。 – Stefan 2018-02-05 16:08:35

绑定=的你的文字表述特定列被映射到某个表中的某个物理列,某些数据库中的某个服务器上。

多部分标识符可以是:MyDatabase.dbo.MyTable。如果您遇到任何这些标识符错误,那么您有一个无法映射的多部分标识符。

避免它的最好方法是首次正确编写查询,或者使用提供intellisense的管理工作室插件,从而避免输入错误以帮助您。

您可能有一个错字。例如,如果在名为Sales的数据库中有一个名为Customer的表,则可以将其引用为Sales..Customer(尽管最好引用它,包括所有者名称(dbo是默认所有者),如Sales.dbo 。客户。

如果键入销售...客户,你可能已经得到了你的消息。

这可能是一个错字,看看在你的代码中调用[方案]的地方。[表名](基本上你在任何地方引用一个字段),并确保一切拼写正确。

就个人而言,我尝试通过对我所有的表使用别名来避免这种情况。当你可以缩短长表名到首字母缩写词它的' (即WorkOrderParts - > WOP),并使您的查询更具可读性。

编辑:作为一个额外的好处,当所有你必须键入的是一个三或四个字母的别名,而模式,表和字段名称都在一起时,你可以节省按键吨数。

如果您确定它不是拼写错误的拼写错误,可能是拼写错误。

您使用的是什么排序规则?核实。

我发现,我得到这些很多,当我尝试缩写,如:

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

将其更改为:

Table1, Table2 
where Table1.ID = Table2.ID 

,使查询工作,而不是抛出错误。

+0

哦,这解决了我的问题。非常感谢你 ! – 2016-11-13 11:35:02

其实有时候,当你正在更新从另一个表中的数据一个表,我认为导致此错误的常见问题之一,就是当你用你的表缩写正确或者当他们不需要。正确的说法是如下:

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

注意,从表1 SomeField列不具有t1预选赛t1.SomeField但只是SomeField

如果试图通过指定t1.SomeField来更新它,该语句将返回您已经注意到的多部分错误。

+1

谢谢! +1在我的情况下,这是问题。 – Sabuncu 2017-02-12 11:48:30

我有这个问题,它原来是一个不正确的表别名。纠正这个问题解决了这个问题。

当更新表格时,请确保您不要通过别名引用更新的字段。

我不得不用下面的代码错误

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 

,我不得不删除在SET语句中别名参考,所以它读取像这样

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

矿是把架构上表别名:

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

我有P.PayeeName AS 'Payer' --, 个两个注释行抛出此错误

我居然忘了加入该表到别人,这就是为什么我得到了错误

应该是这个样子:

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) 

而且不这样:

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) 

错误代码

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 

解决方案代码

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 

,你可以看到,在错误代码,dbo.SubModule已经被定义为SM,但我在下一行使用dbo.SubModule,因此出现了错误。 使用声明的名称而不是实际的名称。问题解决了。

我当具有错误是用[] braquets到sorround表名最好的建议,表的缩写,有时会导致错误,(有时表的缩写只是正常工作...怪异)