Reputation: 30872
According to MSDN:
A procedure can reference tables that do not yet exist. At creation time, only syntax checking is performed. The procedure is not compiled until it is executed for the first time. Only during compilation are all objects referenced in the procedure resolved. Therefore, a syntactically correct procedure that references tables that do not exist can be created successfully; however, the procedure fails at execution time if the referenced tables do not exist.
I was always under the impression that referenced tables are checked. For example if you reference an incorrect column in an existing view it complains at compile time:
So what is going on here, why are columns checked within the procedure but not views / tables?
Upvotes: 1
Views: 776
Reputation: 95574
The document is referencing that, at the time to Stored Procedure is created, it isn't validated. Take this batch:
USE Sandbox;
GO
CREATE PROC dbo.MyProc @ID int AS
BEGIN
SELECT *
FROM dbo.MyTable
WHERE ID = @ID;
END;
GO
CREATE TABLE dbo.MyTable (ID int,
SomeValue varchar(20));
INSERT INTO dbo.MyTable
VALUES(1,'asdjka'),
(2,'asdkj');
GO
EXEC dbo.MyProc 1;
GO
DROP TABLE dbo.MyTable;
DROP PROC dbo.MyProc;
Notice that I CREATE
dbo.MyProc
before dbo.MyTable
, even though it references that object. That's because the validity of the objects in the procedure isn't checked at the point the procedure is created or altered.
A VIEW
on the other hand, is checked at the time that it is created.
CREATE TABLE dbo.MyTable (ID int,
SomeValue varchar(20));
INSERT INTO dbo.MyTable
VALUES(1,'asdjka'),
(2,'asdkj');
GO
--Fails
CREATE VIEW dbo.MyView AS
SELECT ID,
SomeValue,
SomeInt
FROM dbo.MyTable;
GO
--Fails
CREATE VIEW dbo.MyOtherView AS
SELECT *
FROM dbo.MyOtherTable;
GO
DROP TABLE dbo.MyTable;
Depending on the object type depends on what is validated and isn't when the DDL statement is issued.
Edit: It seems that what the OP is questioning is why do that get an error if the object does exist, but they reference a column that doesn't. For exmaple take the below batch:
USE Sandbox;
GO
CREATE TABLE dbo.MyTable (ID int,
SomeValue varchar(20));
INSERT INTO dbo.MyTable
VALUES(1,'asdjka'),
(2,'asdkj');
GO
CREATE PROC dbo.MyProc @ID int AS
BEGIN
SELECT ID,
SomeValue,
AnotherValue
FROM dbo.MyTable
WHERE ID = @ID;
END;
GO
DROP TABLE dbo.MyTable;
GO
DROP PROC dbo.MyProc;
GO
This fails as the column AnotherValue
does not exist. This is actually covered in the very documentation you quote:
A procedure can reference tables that do not yet exist. At creation time, only syntax checking is performed.
It explicitly states you can reference a table that does not exist. It makes no mention of objects that don't, or (more specifically) columns in a table/object. Referencing a table that does exist will be validated at creation time.
Upvotes: 1