Поделиться через


MSSQLSERVER_4104

Область применения: SQL Server

Сведения

Атрибут Значение
Название продукта SQL Server
ИД события 4104
Источник событий MSSQLSERVER
Компонент SQLEngine
Символическое имя ALG_MULTI_ID_BAD
Текст сообщения Не удалось выполнить привязку составного идентификатора "%.*ls".

Описание

Имя сущности в SQL Server называется его идентификатором. Идентификаторы используются, например, всегда при ссылках на сущности путем указания в запросе имен столбца и таблицы. Составной идентификатор содержит один или несколько квалификаторов, являющихся префиксом для идентификатора. Например, перед идентификатором таблицы можно указывать такие квалификаторы, как имя базы данных и имя схемы, в которых содержится таблица, а перед идентификатором столбца могут находиться такие квалификаторы, как имя таблицы или псевдоним таблицы.

Ошибка 4104 указывает, что заданный составной идентификатор не может быть сопоставлен существующей сущности. Эта ошибка может быть возвращена при следующих условиях.

  • Квалификатор, заданный в качестве префикса для имени столбца, не совпадает ни с одним именем таблицы или псевдонима, используемым в запросе.

    Например, в следующей инструкции псевдоним таблицы (Dept) используется как префикс столбца, но в предложении FROM нет ссылки на псевдоним таблицы.

    SELECT Dept.Name FROM HumanResources.Department;  
    

    В следующих инструкциях составной идентификатор столбца TableB.KeyCol задан в предложении WHERE как часть условия JOIN между двумя таблицами, но в запросе нет явной ссылки на таблицу TableB.

    DELETE FROM TableA WHERE TableA.KeyCol = TableB.KeyCol;  
    
    SELECT 'X' FROM TableA WHERE TableB.KeyCol = TableA.KeyCol;  
    
  • Имя псевдонима для таблицы указывается в предложении FROM, но квалификатор, указанный для столбца, является именем таблицы. Например, в следующей инструкции имя таблицы (Department) используется как префикс столбца; но у таблицы есть псевдоним (Dept), ссылка на который содержится в предложении FROM.

    SELECT Department.Name FROM HumanResources.Department AS Dept;  
    

    Когда используется псевдоним, имя таблицы не может использоваться в других частях инструкции.

  • SQL Server не может определить, относится ли идентификатор нескольких частей к столбцу, префиксуемого таблицей или свойству определяемого пользователем типа данных CLR (UDT), префиксам столбца. Это происходит потому, что ссылка на свойства столбцов определяемых пользователем типов задается с использованием точки (.) в качестве разделителя между именем столбца и именем свойства, так же как имя столбца предваряется именем таблицы. В следующем примере создается две таблицы, a и b. Таблица b содержит столбец a, в котором в качестве типа данных используется определяемый пользователем тип данных CLR dbo.myudt2. Инструкция SELECT содержит составной идентификатор a.c2.

    CREATE TABLE a (c2 int);   
    GO  
    
    CREATE TABLE b (a dbo.myudt2);   
    GO  
    
    SELECT a.c2 FROM a, b;   
    

    Если у определяемого myudt2 пользователем типа нет свойства с именем c2, SQL Server не может определить, относится ли идентификатор a.c2к столбцу c2 в таблице a или к столбцу a, свойству c2 в таблице b.

Действие пользователя

  • Префиксы столбцов должны быть согласованы с именами таблиц или псевдонимами, указанными в предложении FROM запроса. Если псевдоним определен для имени таблицы в предложении FROM, то псевдоним можно использовать только как квалификатор для столбцов, связанных с этой таблицей.

    Приведенные выше инструкции, которые содержат ссылки на таблицу HumanResources.Department, можно исправить следующим образом:

    SELECT Dept.Name FROM HumanResources.Department AS Dept;  
    GO  
    
    SELECT Department.Name FROM HumanResources.Department;  
    GO  
    
  • Проверьте, что все таблицы указаны в запросе и условия JOIN между таблицами заданы верно. Инструкция DELETE выше может быть исправлена следующим образом:

    DELETE FROM dbo.TableA  
    WHERE TableA.KeyCol = (SELECT TableB.KeyCol   
                            FROM TableB   
                            WHERE TableA.KeyCol = TableB.KeyCol);  
    GO  
    

    Приведенная выше инструкция SELECT для таблицы TableA может быть исправлена следующим образом:

    SELECT 'X' FROM TableA, TableB WHERE TableB.KeyCol = TableA.KeyCol;  
    

    or

    SELECT 'X' FROM TableA INNER JOIN TableB ON TableB.KeyCol = TableA.KeyCol;  
    
  • Используйте для идентификаторов уникальные, понятные имена. В результате будет проще читать и исправлять исходный текст, и снижается опасность неоднозначных ссылок на несколько сущностей.

См. также

MSSQLSERVER_107
Идентификаторы баз данных