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:
- Use different name to avoid collision
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'.
LiveDemo
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
LiveDemo2
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