Почему 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 проверяется, что имена объектов используемые процедурой. Этот процесс называется отложенным разрешение имен, поскольку объекты таблицы, на которые ссылаются сохраненные процедура не должна существовать при создании хранимой процедуры, но только когда он выполнен.