There is already an object named '#columntable' in the database - sql

I am trying the following query
if exists (select 1 from emp where eid = 6)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))
end
else
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (newcolumns varchar(100))
end
But I am getting the error
Msg 2714, Level 16, State 1, Line 8
There is already an object named '#columntable' in the database.
Can anyone suggest why? The same query works fine if I do not write the else part.

This is a SQL Server parser error unfortunately (confirmed by Microsoft).
#DizGrizz is also right - SELECT .. INTO #SomeTable doesn't work if repeated in IF .. ELSE statements.
IF .. ELSE .. CREATE TABLE #SomeTempTable
In answer to the actual question, creating then altering the table works (you also only have to check and drop once)...
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL
BEGIN
DROP TABLE #MyTempTable
END
CREATE TABLE #MyTempTable (DummyColumn BIT)
IF EXISTS (SELECT 1 FROM EMP WHERE EID = 6)
BEGIN
ALTER TABLE #MyTempTable
ADD MyColumnType1 VARCHAR(100)
ALTER TABLE #MyTempTable
DROP COLUMN DummyColumn
END
ELSE
BEGIN
ALTER TABLE #MyTempTable
ADD MyColumnType2 VARCHAR(100)
ALTER TABLE #MyTempTable
DROP COLUMN DummyColumn
END
IF .. ELSE .. SELECT INTO #SomeTempTable
The issue I had however was the same as #DizGrizz: IF .. ELSE combined with SELECT .. INTO #SomeTable fails. As a workaround it's possible to select the top 0 rows (i.e. none) to create the table with the correct column types. (This insulates the script from column type changes and also avoids the pain of declaring every type.) INSERT INTO can then be used, provided IDENTITY_INSERT is set to ON to prevent errors:
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL
DROP TABLE #MyTempTable
-- This creates the table, but avoids having to declare any column types or sizes
SELECT TOP 0 KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
-- Required to prevent IDENTITY_INSERT error
SET IDENTITY_INSERT #MyTempTable ON
IF #something = 1
BEGIN
-- Insert the actual rows required into the (currently empty) temp table
INSERT INTO #MyTempTable (KeyNm)
SELECT KeyNm
FROM dbo.MyDataTable2
WHERE CatNum = 2
END
ELSE
BEGIN
-- Insert the actual rows required into the temp table
INSERT INTO #MyTempTable (KeyNm)
SELECT KeyNm
FROM dbo.MyDataTable2
WHERE CatNum = 8
END
SET IDENTITY_INSERT #MyTempTable OFF

Temp tables are not dropped automatically at the end of a query, only when the current connection to the DB is dropped or you explicitly delete them with DROP TABLE #columntable
Either test for the existence of the table at the start of the query or alwayas delete it at the end (preferably both)
EDIT: As Matrin said in his comment, this is actually a parse error. You get the same error if you only parse the SQL as when you execute it.
To test that out I split up your query and tried:
if exists (select 1 from emp where id = 6)
create table #columntable (newcolumns varchar(100))
GO
if not exists (select 1 from emp where id = 6)
create table #columntable (oldcolumns varchar(100))
GO
The parser is happy with that. Interestingly if you change to using non-temp tables the original query parses fine (I realise the problems that would create, I was just interested to find out why the query would not parse).

This also occurs if you create the tables with SELECT INTO...as in
IF OBJECT_ID('tempdb..#MyTempTable', 'U') IS NOT NULL
DROP TABLE #MyTempTable
SELECT TOP 1 #MyVariable = ScaleValue
FROM MyDataTable1
WHERE ProductWeight > 1000
IF #MyVariable = 1
BEGIN
SELECT KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
WHERE CatNum = 2
END
ELSE
BEGIN
SELECT KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
WHERE CatNum = 8
END
The parser should not even attempt to detect this because, in many cases, it would be impossible for the parser to determine if the table would already exist. The code above is a perfect example...there would be no way for the parser to determine the value of #MyVariable.
I hope that someone has informed MS of this bug (I don't have their ear).

You can check if it exists by doing:
IF OBJECT_ID('tempdb..#columntable') IS NOT NULL
BEGIN
DROP TABLE #columntable
PRINT 'Dropped table...'
END

Use global temp tables and wrap the select in exec.
Example:
Fail
declare #a int = 1
if object_id('tempdb..##temp') is not null drop table ##temp
if(#a = 1) select * into ##temp from table_1
else if(#a = 2) select * into ##temp from table_2
Win
declare #a int = 1
if object_id('tempdb..##temp') is not null drop table ##temp
if(#a = 1) exec('select * into ##temp from table_1')
else if(#a = 2) exec('select * into ##temp from table_2')
This will fool the buggy parser that is trying to be smarter than it is.
And Microsoft - please fix this.

The error is wrong, remove the if clause and it runs through fine. Thus the problem is in the exists:
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))

Well I got the answer...
As Martin said this is a parse/compile issue. So I Tried changing my script as below
if exists (select 1 from emp where eid = 6)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))
end
go
if exists (select 1 from emp where eid = 1)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (newcolumns varchar(100))
end
And this worked for me.

I have been experiencing this issue. My query consisted of several joined SELECT statements in the form of:
DROP TABLE IF EXISTS ##TempTableName
SELECT statement ...
So, every time I tried to alter SQL code I would get the above error. I have changed all my temp tables from ##global to #local and now I am able to alter my SQL as many times as needed. So the example above would become:
DROP TABLE IF EXISTS #TempTableName
SELECT statement ...

Related

There is already an object named '#BaseData' in the database

Below is a snippet of my code.
I am wanting to filter my data based upon a variable.
When I try to run the code, it returns an error of "There is already an object named '#BaseData' in the database.". I am not sure as to why this is the case; I have put extra checks within the IF statements to drop the temp table if it already exists but to no avail.
Are you able to help or provide an alternative solution please?
DECLARE #Variable AS VARCHAR(20) = 'Example1'
IF OBJECT_ID(N'TEMPDB..#BaseData') IS NOT NULL
DROP TABLE #BaseData
IF #Variable = 'Example1'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
END
IF #Variable = 'Example2'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
WHERE
[column] = 1
END
IF #Variable = 'Example3'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
WHERE
[column] = 0
END
While code is compiled by SQL, creation of same #table is found in each condition so it doesn't work.
One possible solution would be to create table and than insert data conditionally.
-- DROP TEMP TABLE IF EXISTS
IF OBJECT_ID(N'TEMPDB..#BaseData') IS NOT NULL
DROP TABLE #BaseData
GO
-- CRATE TEMP TABLE WITH TempId, AND SAME STRUCTURE AS YOUR TABLE
SELECT TOP 0 CONVERT(INT, 0)TempId, * INTO #BaseData FROM TestTable
-- DECLARE VARIABLE
DECLARE #Variable AS VARCHAR(20)= 'Example1'
-- INSERT DATA IN TABLE DEPENDING FROM CONDITION
IF (#Variable = 'Example1')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable
END
IF (#Variable = 'Example2')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable WHERE Id = 1
END
IF (#Variable = 'Example3')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable WHERE Id = 2
END

SQL Server 2008 Column name or number of supplied values does not match table definition

I have to get some data from a table who's name is defined at run time, so I'm using the method of first selecting the data into a global temp table and the to my actual temp table. But I'm getting Column name or number of supplied values does not match table definition.
A don't get why it is trying to match the columns as its a select into statement. My code is:
IF OBJECT_ID('tempdb.dbo.#tempData') IS NOT NULL
DROP TABLE #tempData
if object_id('tempdb..##temptbl') is not null
begin
drop table ##temptbl
end
execute('select * INTO ##temptbl from Repo.dbo.'+#tableName)
select * INTO #tempData from ##temptbl
Can anyone tell me what I'm doing wrong?
Looks like you've missed the begin...end from your first IF statement. This is likely making the drop of the global temp table fail as it's still working out the first part;
IF OBJECT_ID('tempdb.dbo.#tempData') IS NOT NULL
BEGIN
DROP TABLE #tempData
END
GO
IF object_id('tempdb..##temptbl') IS NOT NULL
BEGIN
DROP TABLE ##temptbl
END
EXECUTE('select * INTO ##temptbl from Repo.dbo.'+#tableName)
SELECT * INTO #tempData FROM ##temptbl
simpe use this
declare #tableName nvarchar(50) = 'tblTest'
IF OBJECT_ID('tempdb.dbo.#tempData') IS NOT NULL
DROP TABLE #tempData
IF OBJECT_ID(N'tempdb..##temptbl') IS NOT NULL
BEGIN
DROP TABLE ##temptbl
END
execute('select * INTO ##temptbl from dbo.'+ #tableName)
select * from ##temptbl
Below query might solve your issue :-
declare #tableName varchar(50) = 'Test'
IF OBJECT_ID('tempdb.dbo.#tempData') IS NOT NULL
DROP TABLE #tempData
IF OBJECT_ID('tempdb.dbo.##temptbl') IS NOT NULL
DROP TABLE ##temptbl
execute('select * INTO ##temptbl from dbo.'+#tableName)
select * INTO #tempData from ##temptbl

Inserting into one Temp table with If condition [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL IF statement is being ignored
Odd error using IF/ELSE IF statements
I'm trying to do inserting into one temptable. But it is throwing an error. Please help
Declare #Live BIT = 'True'
Step 1:-
If #Live = 'True'
BEGIN
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
DROP TABLE #tempTable
SELECT TOP 1 INTO #tempTable FROM Table1
END
ELSE
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
DROP TABLE #tempTable
SELECT TOP 5 INTO #tempTable FROM Table1
Step 2:-
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
DROP TABLE #tempTable
If #Live = 'True'
BEGIN
SELECT TOP 1 INTO #tempTable FROM Table1
END
ELSE
SELECT TOP 5 INTO #tempTable FROM Table1
In Step1 & Step2, error showing as
"There is already an object named '#tempTable' in the database."
Condition: I have to insert the records into one #tempTable
Is there any other alternate to achieve this requirement?
I would recommend delcaring the temp table before hand then using an INSERT INTO instead of a SELECT INTO
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
BEGIN
DROP TABLE #tempTable
END
CREATE TABLE #tempTable
(
--columns go here
)
If #Live = 'True'
BEGIN
INSERT INTO #tempTable
SELECT TOP 1 * FROM Table1
END
ELSE
INSERT INTO #tempTable
SELECT TOP 5 * FROM Table1
run this command before running query cause there is already a #tempTable
DROP TABLE #tempTable
and try this code
IF OBJECT_ID('tempdb..#tempTable') is not null
drop table #tempTable
create table #tempTable (a int)
insert into #tempTable (a) select 1
select * from #tempTable

T-SQL IF statement explanation

I'm really puzzled by this one!! I'm sure it's simple but really can't figure it out!!
DECLARE #jobid INT = 100
IF (#JobID >= 0)
BEGIN
SELECT * into #tmp FROM Persons
end
ELSE
BEGIN
SELECT * into #tmp FROM Persons1
end
It gives an error that the #tmp table already exists! Why it would validate both statements !
Of course my original query is huge and doing more, but that's a sample to illustrate my error.
Can anybody explain it please?
The #tmp table is not there, even when you try to drop it or change the name, still the engine validates both statements!
I'm using 2008 R2.
Thanks
Jason
You run it over Linked Server? Or you not deleted the one from previous run.
Try to create #tmp table prior to IF statement:
CREATE TABLE #tmp(fields...)
DECLARE #jobid INT = 100
IF (#JobID >= 0)
BEGIN
INSERT #tmp
SELECT * FROM Persons
end
ELSE
BEGIN
INSERT #Tmp
SELECT * FROM Persons1
end
or delete provious one
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
EXEC('DROP TABLE #tmp')
GO
DECLARE #jobid INT = 100
IF (#JobID >= 0)
BEGIN
SELECT * into #tmp FROM Persons
end
ELSE
BEGIN
SELECT * into #tmp FROM Persons1
end
#tmp may already be created in tempDB from previous runs of your query. If you are not using #tmp anywhere in your query prior to that block, you could do something like the following prior to that block of code to ensure it's always ready to go:
IF OBJECT_ID('tempDB..#tmp') IS NOT NULL
DROP TABLE #tmp

create temp table of trigger data

I am trying to create an audit trigger without having to specifiy the column list more than once.
To this end, I want to product a temporary table of the content of the INSERTED or DELETED data in the trigger, then process that into an audit table.
If I use this:
IF #ChangeType = 'D'
SELECT * INTO #tmp FROM DELETED
ELSE
SELECT * INTO #tmp FROM INSERTED
Then I get a compilation error at the 2nd SELECT * INTO that the table #tmp already exists.
If I try and work around this using dynamic SQL:
SET #Sql = 'SELECT * INTO #tmp FROM '
IF #ChangeType = 'D'
SET #Sql = #Sq + 'DELETED'
ELSE
SET #Sql = #Sql + 'INSERTED'
EXEC (#Sql)
Then I get an error that the DELETED and INSERTED tables do not exist.
How can I get the INSERTED and DELETED tables in a trigger into a temporary or other in-memory table?
Try to create the temporary table outside the if, like:
SELECT TOP 0 * INTO #tmp FROM DELETED
IF #ChangeType = 'D'
INSERT INTO #tmp SELECT * FROM DELETED
ELSE
INSERT INTO #tmp SELECT * FROM INSERTED
This is a known problem due to the resolve-on-parse of the temp table object. With two SELECT - INTO statements in the same scope, SQL Server throws the towel.
SELECT * INTO #tmp FROM DELETED WHERE 1=0
IF #ChangeType = 'D'
INSERT #tmp SELECT * FROM DELETED
ELSE
INSERT #tmp SELECT * FROM INSERTED
I'd be interested as to why you need to copy the data into another table in the first place. But, that's off-topic...
Temporary table (#temp) are notionally stored on disc, and Table Variables (#temp) are notionally only in memory and may be more optimal for small tasks. (Assumes writes to the table will normally only affect small numbers of rows.)
Temporary tables, however, can be created using the SELECT INTO trick, avoiding the need to know the table definition in advance.
If you do know the table definition in advance, however, can't you simply use something such as the following?
DECLARE #temp TABLE (id AS INT, val as INT)
IF #ChangeType = 'D'
INSERT INTO #temp SELECT * FROM DELETED
ELSE
INSERT INTO #temp SELECT * FROM INSERTED
Personally, I'd even avoid using * if possible. Your subsequent queries will only use specific fields, so I'd only copy the fields I was using. This has the added benefit that if fields are added to the table, the code doesn't break...
DECLARE #temp TABLE (id AS INT, val as INT)
IF #ChangeType = 'D'
INSERT INTO #temp SELECT id, val FROM DELETED
ELSE
INSERT INTO #temp SELECT id, val FROM INSERTED
In my mind, the advantage of specifying the fields (which is what you wish to avoid), is that you can ensure that you always only copy what you need.