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
, в котором в качестве типа данных используется определяемый пользователем тип данных CLRdbo.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;
Используйте для идентификаторов уникальные, понятные имена. В результате будет проще читать и исправлять исходный текст, и снижается опасность неоднозначных ссылок на несколько сущностей.