Почему Microsoft SQL Server проверяет столбцы, но не таблицы в хранимых процедурах?
Кажется, что Microsoft SQL Server проверяет правильность имени столбца, но не действительность имени таблицы при определении хранимых процедур. Если он обнаруживает, что существующее имя таблицы существует в настоящее время, оно проверяет имена столбцов в инструкции по отношению к столбцам в этой таблице. Так, например, это будет работать нормально:
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
SELECT
Col1, Col2, Col3
FROM
NonExistentTable
END
GO
... как это будет:
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
SELECT
ExistentCol1, ExistentCol2, ExistentCol3
FROM
ExistentTable
END
GO
... но это не удается с помощью "Недопустимое имя столбца":
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
SELECT
NonExistentCol1, NonExistentCol2, NonExistentCol3
FROM
ExistentTable
END
GO
Почему SQL Server проверяет столбцы, но не таблицы, на существование? Конечно, это противоречиво; он должен делать то и другое, либо нет. Для нас полезно иметь возможность определять SP, которые могут ссылаться на таблицы AND/OR, которые еще не существуют в схеме, так есть ли способ отключить проверку SQL Server существования столбцов в существующих в настоящее время таблицах?
Ответы
Ответ 1
Это называется отложенным разрешением имени.
Нет способа отключить его. Вы можете использовать динамический SQL или (неприятный взлом!) Добавить ссылку на несуществующую таблицу, чтобы компиляция этого оператора была отложена.
CREATE PROCEDURE [dbo].[MyProcedure]
AS
BEGIN
CREATE TABLE #Dummy (c int)
SELECT
NonExistantCol1, NonExistantCol2, NonExistantCol3
FROM
ExistantTable
WHERE NOT EXISTS(SELECT * FROM #Dummy)
DROP TABLE #Dummy
END
GO
Ответ 2
Эта статья в MSDN должна ответить на ваш вопрос.
Из статьи:
Когда хранимая процедура выполняется в первый раз, запрос процессор считывает текст хранимой процедуры из В представлении каталога sys.sql_modules проверяется, что имена объектов используемые процедурой. Этот процесс называется отложенным разрешение имен, поскольку объекты таблицы, на которые ссылаются сохраненные процедура не должна существовать при создании хранимой процедуры, но только когда он выполнен.