So, as I discovered, SQL Server kind of “caches” View columns, which can be a problem if you use SELECT *.
Let’s demonstrate:
Create the tables and the view:
CREATE TABLE Categories(CategoryID INT, CategoryName VARCHAR(50)) INSERT INTO Categories SELECT 1, 'Category1' UNION SELECT 2, 'Category2' CREATE TABLE Products (ProductID INT, Description VARCHAR(50), CategoryID INT) INSERT INTO Products SELECT 1, 'Product1', 1 UNION SELECT 2, 'Product2', 1 UNION SELECT 3, 'Product3', 2 GO CREATE VIEW TestView AS SELECT c.*, p.Description FROM Categories c JOIN Products p ON c.CategoryID = p.CategoryID GO
Expected output of SELECT * FROM TestView:
Now let’s add a column to the Categories table:
ALTER TABLE Categories ADD NewColumn VARCHAR(50) NULL
Output of SELECT * FROM TestView:
And… our Description column is showing the data of our NewColumn! As you see, things can get real messy. The best thing would be not to use SELECT * at all, but if it’s too late and you’re seeing the issue described, you can use 2 options to refresh the View metadata and fix the problem:
- Use sp_refreshview
- ALTER or DROP and RECREATE the View
As a side point, it seems SQL Server Management Studio automatically converts SELECT * to individual column names when executing or saving the View in the designer / UI – probably for this reason.