Reputation: 7628
I have a SQL Server query like this:
CREATE TABLE ##Temp(
OrderID NVARCHAR(100),
ID INT,
Prices INT,
Total INT
);
INSERT INTO ##Temp (ID, Prices, OrderID, Total)
SELECT fc.ID, f.Prices, f.OrderID,
(SUM(f.Prices) OVER()) AS Total
FROM FruitCrates fc
LEFT JOIN Fruits f ON fc.ID = f.FruitCrateID
WHERE fc.OrderID LIKE '18_1635'
AND fc.Rights = 1
AND fc.Cancelled = 0
AND f.OrderID IS NOT NULL;
SELECT * FROM ##Temp;
But I keep getting an error:
Msg 207, Level 16, State 1, Line 12
Invalid column name 'Total'.
Which I think is because I am not using OVER()
properly BUT I am not sure how to fix it.
PLEASE NOTE
SELECT
statement works on its on when not put in after INSERT
.
Results without INSERT
╔═════╦════════╦══════════╦═══════╗
║ ID ║ Prices ║ OrderID ║ Total ║
╠═════╬════════╬══════════╬═══════╣
║ 77 ║ 1 ║ 1_370 ║ 104 ║
║ 19 ║ 101 ║ 1811_171 ║ 104 ║
║ 77 ║ 2 ║ 1811_171 ║ 104 ║
╚═════╩════════╩══════════╩═══════╝
Upvotes: 3
Views: 86
Reputation: 175994
Error message with insert Invalid column name 'Total'.
indicates clearly that ##Temp
table has different schema than column list in INSERT INTO (...)
statement.
To troubleshoot it you should always check metadata(column names) right before insert:
SELECT *
FROM ##Temp
WHERE 1=2;
Then you could easily spot that it is different that what you've assumed to be.
Now you are using global temp table, it will live as long as last connection that refer to it is active. You should consider using local temp tables.
To solve your case you could:
Right before you could (if not used in nested procedures):
IF OBJECT_ID('tempdb..##temp') IS NOT NULL DROP TABLE ##temp CREATE TABLE ##temp...
There is also one nasty case when stored procedure called another stored procedure and both (outer and inner) creates temp table with the same name. You should avoid it.
CREATE PROCEDURE #outer
AS
BEGIN
CREATE TABLE ##temp (id INT, guid UNIQUEIDENTIFIER, col2 VARCHAR(100));
INSERT INTO ##temp VALUES(1,NEWID(), 'a');
SELECT * FROM ##temp;
EXEC [#inner];
END
GO
CREATE PROCEDURE #inner
AS
BEGIN
CREATE TABLE ##temp (id INT, total INT); -- no error during creation
INSERT INTO ##temp(id, total)
SELECT 2, 10;
SELECT * FROM ##temp;
END
GO
EXEC #outer
-- Invalid column name 'total'.
The funniest thing is when you use local temp tables with the same number of columns(or defaults) and implicit casts are possible, it will pass:
CREATE PROCEDURE #outer
AS
BEGIN
CREATE TABLE #temp (id INT, col2 varchar(10));
INSERT INTO #temp VALUES(1, 'a');
SELECT * FROM #temp;
EXEC [#inner];
END
GO
CREATE PROCEDURE #inner
AS
BEGIN
CREATE TABLE #temp (id INT, total INT);
INSERT INTO #temp
SELECT 2, 10;
SELECT * FROM #temp;
END
GO
EXEC #outer
And example with incompatible types:
CREATE PROCEDURE #outer
AS
BEGIN
CREATE TABLE #temp (id INT, col2 UNIQUEIDENTIFIER);
INSERT INTO #temp VALUES(1, NEWID());
SELECT * FROM #temp;
EXEC [#inner];
END
GO
CREATE PROCEDURE #inner
AS
BEGIN
CREATE TABLE #temp (id INT, total INT);
INSERT INTO #temp
SELECT 2, 10;
SELECT * FROM #temp;
END
GO
EXEC #outer
Operand type clash: int is incompatible with uniqueidentifier
Upvotes: 1