MSSQLSERVER_4104
Applies to: SQL Server
Details
Attribute | Value |
---|---|
Product Name | SQL Server |
Event ID | 4104 |
Event Source | MSSQLSERVER |
Component | SQLEngine |
Symbolic Name | ALG_MULTI_ID_BAD |
Message Text | The multi-part identifier "%.*ls" could not be bound. |
Explanation
The name of an entity in SQL Server is referred to as its identifier. You use identifiers whenever you reference entities, for example, by specifying column and table names in a query. A multi-part identifier contains one or more qualifiers as a prefix for the identifier. For example, a table identifier may be prefixed with qualifiers such as the database name and schema name in which the table is contained, or a column identifier may be prefixed with qualifiers such as a table name or table alias.
Error 4104 indicates that the specified multi-part identifier could not be mapped to an existing entity. This error can be returned under the following conditions:
The qualifier supplied as a prefix for a column name does not correspond to any table or alias name used in the query.
For example, the following statement uses a table alias (
Dept
) as a column prefix, but the table alias is not referenced in the FROM clause.SELECT Dept.Name FROM HumanResources.Department;
In the following statements, a multi-part column identifier
TableB.KeyCol
is specified in the WHERE clause as part of a JOIN condition between two tables, however,TableB
is not explicitly referenced in the query.DELETE FROM TableA WHERE TableA.KeyCol = TableB.KeyCol;
SELECT 'X' FROM TableA WHERE TableB.KeyCol = TableA.KeyCol;
An alias name for the table is supplied in the FROM clause, but the qualifier supplied for a column is the table name. For example, the following statement uses the table name
Department
as the column prefix; however, the table has an alias (Dept
) referenced in the FROM clause.SELECT Department.Name FROM HumanResources.Department AS Dept;
When an alias is used, the table name cannot be used elsewhere in the statement.
SQL Server is unable to determine if the multi-part identifier refers to a column prefixed by a table or to a property of a CLR user-defined data type (UDT) prefixed by a column. This happens because properties of UDT columns are referenced by using the period separator (.) between the column name and the property name in the same way that a column name is prefixed with a table name. The following example creates two tables,
a
andb
. Tableb
contains columna
, which uses a CLR UDTdbo.myudt2
as its data type. The SELECT statement contains a multi-part identifiera.c2
.CREATE TABLE a (c2 int); GO
CREATE TABLE b (a dbo.myudt2); GO
SELECT a.c2 FROM a, b;
Assuming that the UDT
myudt2
does not have a property namedc2
, SQL Server cannot determine whether identifiera.c2
refers to columnc2
in tablea
or to the columna
, propertyc2
in tableb
.
User Action
Match the column prefixes against the table names or alias names specified in the FROM clause of the query. If an alias is defined for a table name in the FROM clause, you can only use the alias as a qualifier for columns associated with that table.
The statements above that reference the
HumanResources.Department
table can be corrected as follows:SELECT Dept.Name FROM HumanResources.Department AS Dept; GO
SELECT Department.Name FROM HumanResources.Department; GO
Ensure that all tables are specified in the query and that the JOIN conditions between tables are specified correctly. The DELETE statement above can be corrected as follows:
DELETE FROM dbo.TableA WHERE TableA.KeyCol = (SELECT TableB.KeyCol FROM TableB WHERE TableA.KeyCol = TableB.KeyCol); GO
The SELECT statement above for
TableA
can be corrected as follows:SELECT 'X' FROM TableA, TableB WHERE TableB.KeyCol = TableA.KeyCol;
or
SELECT 'X' FROM TableA INNER JOIN TableB ON TableB.KeyCol = TableA.KeyCol;
Use unique, clearly defined names for identifiers. Doing so makes your code easier to read and maintain, and it also minimizes the risk of ambiguous references to multiple entities.