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

时间:2008-10-15 21:22:00

标签: sql sql-server

当我尝试根据另一个表更新表时,我不断收到这些错误。我最终重写了查询,更改了连接的顺序,更改了一些分组然后它最终起作用,但我只是不太明白。

什么是'多部分标识符'?
何时“多部件标识符”无法绑定?
无论如何它会受到什么影响?
在什么情况下会发生此错误?
什么是预防它的最佳方法?

SQL Server 2005的具体错误是:

  

无法绑定多部分标识符“...”。

以下是一个例子:

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

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

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

实际错误:

  

消息4104,级别16,状态1,行3多部分标识符   

20 个答案:

答案 0 :(得分:81)

多部分标识符是包含多个部分的字段或表的任何描述 - 例如MyTable.SomeRow - 如果它不能被绑定意味着它有问题 - 要么你有一个简单的拼写错误,要么表和列之间的混淆。它也可能是由于在表或字段名中使用保留字而不是用[]包围它们。 它也可能是由于未在目标表中包含所有必需的列而引起的。

redgate sql prompt这样的东西非常出色,可以避免手动输入这些内容(它甚至可以根据外键自动完成连接),但不是免费的。 SQL Server 2008支持intellisense开箱即用,虽然它不像redgate版本那么完整。

答案 1 :(得分:48)

实际上,有时当您从另一个表的数据更新一个表时,我认为导致此错误的常见问题之一是,当您错误地使用表缩写或不需要时。正确的陈述如下:

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

请注意 Table1 中的 SomeField 列没有t1限定符 t1.SomeField 但只是SomeField

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

答案 2 :(得分:16)

这可能是一个错字。查找代码中您调用[schema]的位置。[TableName](基本上是您引用字段的任何位置)并确保所有内容拼写正确。

就个人而言,我试图通过为所有表使用别名来避免这种情况。当你可以将长表名缩短为其描述的首字母缩写(即WorkOrderParts - > WOP)时,它会有很大的帮助,同时也使你的查询更具可读性。

编辑:作为一个额外的好处,当你需要输入的是三个或四个字母的别名而不是模式,表格和字段名称时,你将节省大量的击键次数。

答案 3 :(得分:5)

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

如果您输入Sales ... Customer,您可能已收到所收到的消息。

答案 4 :(得分:5)

Binding =特定列的文本表示形式被映射到某些服务器上某些数据库中的物理列。

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

避免它的最好方法是在第一时间正确编写查询,或者使用提供intellisense的管理工作室插件,从而避免拼写错误。

答案 5 :(得分:4)

如果你确定这不是一个拼写错误的拼写,也许这是一个错字的情况。

您使用的是哪种排序规则?检查一下。

答案 6 :(得分:4)

当我尝试缩写时,我发现我得到了很多,例如:

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

将其更改为:

Table1, Table2 
where Table1.ID = Table2.ID

使查询起作用而不是抛出错误。

答案 7 :(得分:4)

更新表时,请确保不通过别名引用更新字段。

我刚刚遇到以下代码的错误

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

答案 8 :(得分:2)

我遇到了这个问题,结果证明是一个不正确的表别名。纠正这个问题解决了这个问题。

答案 9 :(得分:2)

我错误地将模式放在表Alias上:

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

答案 10 :(得分:1)

我有available.packages <- installed.packages() suppressMessages(if(!"XML" %in% available.packages) install.packages("XML",repos = "https://cran.cnr.berkeley.edu/")) library(XML) # Function to get data from help console help_console <- function(topic, format=c("text", "html", "latex", "Rd"), lines=NULL, before=NULL, after=NULL, pkg) { format=match.arg(format) if (!is.character(topic)) topic <- deparse(substitute(topic)) helpfile <- tryCatch({ helpfile <- utils:::.getHelpFile(help(topic, package = as.character(pkg))) }, error = function(err) { helpfile <- NA }) if(!is.na(helpfile[1])) {hs <- capture.output(switch(format, text=tools:::Rd2txt(helpfile), html=tools:::Rd2HTML(helpfile), latex=tools:::Rd2latex(helpfile), Rd=tools:::prepare_Rd(helpfile))) if(!is.null(lines)) hs <- hs[lines] hs <- c(before, hs, after) html <- paste(hs, sep="\n", collapse = "") } else{ html <- NA } return(html) } # Function to retrieve information on functions within a package get.funcs <- function(pkg){ if(pkg %in% available.packages){ print(pkg) require(pkg, character.only = TRUE) df <- as.data.frame(as.vector(lsf.str(paste0("package:", pkg))), stringsAsFactors = FALSE) colnames(df) <- "function.name" df$usage <- sapply(df$function.name, function(x) capture.output(str(get(x)))[1]) df$package <- pkg df$description <- mapply(function(x,y) { html <- help_console(x, "html", lines = 1:25, before = "", after = "", pkg = y) if(!is.na(html)){ doc <- htmlParse(html, asText = TRUE) plain.text <- xpathSApply(doc, "//p", xmlValue)[1] } else{ plain.text <- NA } }, df$function.name, df$package) return(df[,c("package","function.name","usage","description")]) } else{ print(paste(pkg, "- has not been installed and cannot be processed!")) return(NULL) } } # Create a vector of packages to process packages <- c("base","dplyr","lubridate","plyr","readr","readxl","reshape2","RODBC","stringr","tidyr","XLConnect","xlsx","XML","zoo") # Create a list of dataframes containing package information ldf <- lapply(packages, get.funcs) # Combine all dataframes in the list to a single dataframe df <- do.call(rbind, ldf) 并且两个注释行引发了此错误

答案 11 :(得分:1)

当您键入FROM表时,这些错误将消失。 在您输入的内容下方输入FROM,然后Intellisense将起作用,并且多部分标识符将起作用。

答案 12 :(得分:1)

我遇到此错误,只是看不到问题出在哪里。我仔细检查了所有别名和语法,没有发现任何异常。该查询类似于我一直写的查询。

我决定再次重写下面的查询(我最初是从报表.rdl文件复制该查询)的,然后运行良好。现在查看查询,它们对我来说看起来是一样的,但是我重写的查询有效。

只想说,如果没有其他办法,那就值得一试。

答案 13 :(得分:1)

在我的情况下,在前面的Set字段中添加表别名会导致此问题。

更新表1 设置SomeField = t2.SomeFieldValue 从表1 t1 内部联接表2作为t2     在t1.ID = t2.ID

错误 更新表1 设置t1.SomeField = t2.SomeFieldValue 从表1 t1 内部联接表2作为t2     在t1.ID = t2.ID

答案 14 :(得分:1)

出现错误时,我最好的建议是使用[] braquets来覆盖表名称,表格的缩写有时会导致错误,(有时表格缩写只是工作正常......很奇怪)

答案 15 :(得分:1)

错误代码

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,因此出现了错误。 使用声明的名称而不是实际名称。问题解决了。

答案 16 :(得分:1)

我实际上忘了加入其他人,这就是我收到错误的原因

假设是这样的:

  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)

答案 17 :(得分:0)

我已经解决了这个问题,但是您的代码和我的代码之间有区别。尽管我认为您可以理解什么是“无法绑定多部分标识符”

当我使用此代码时

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

我遇到了多部分标识符问题

但是当我使用单引号作为电子邮件地址时,它就解决了

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

答案 18 :(得分:0)

我遇到了完全相同的问题,与您的编码类似,我错过了 FROM 字段,一旦添加,查询就知道要从哪个表读取数据

答案 19 :(得分:0)

我在 SUBSTRING 方法中删除方括号后工作。我改自

<块引用>

SUBSTRING([dbo.table].[column],15,2)

<块引用>

SUBSTRING(dbo.table.column,15,2)