Select into Temp table cannot exist in seperate IF condition? - sql-server

IF OBJECT_ID('tempdb..#tempTable2') IS NOT NULL
DROP TABLE #tempTable2;
IF #someCondition is not null
BEGIN
SELECT * INTO #tempTable2 FROM Table; --No problem, no error
END
ELSE
BEGIN
SELECT * INTO #tempTable2 FROM Table; --Execution failed
END
Msg 2714, Level 16, State 1, Line 197 There is already an object named
'#tempTable2' in the database.
May I know what could be the reason for the above case? Procedurally, the query in first IF section was not being executed and hence it should not create #tempTable2

You cannot have two statements in the same procedure that create a temp table with the same name.
This is a leftover from SQL 6.5 which did not have deferred name resolution.
Instead of using select into, use create table + insert.
Answer by Erland Sommarskog on MSDN Social
if object_id('tempdb..#tempTable2') is not null
drop table #tempTable2;
create table #tempTable2 (...);
if #someCondition is not null
begin
insert into #tempTable2
select * from Table;
end
else
begin
insert into #tempTable2
select * from Table;
end

I hope you can understand my pour english.
the problem is not "if" but the statement of "select"
with the structure "select * into table2 from table1"will create the ssms a new table automatically.
that means,when you use the same statement in another time,the table2 has already created in your database.
you don't need to create it again or you can create it with another name.

Related

How To Get Temp Table to Run Multiple Time

I'm using MS SQL Server. I'm currently working on a query for pulling headcount. In this process, I'm creating temp tables, but noticed that I can only run the query once. If I try running it again after making changes, it gives me the 'There is already an object named '#Test1' in the database.'
My SQL looks like this:
SET NOCOUNT ON SET ANSI_WARNINGS OFF
IF OBJECT_ID('Tempdb..#Headcount') IS NOT NULL
Drop Table #Test1
Select Coalesce(Enddate,GETDATE()) as EndDate1,FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Into #Test1
from EmployeeDM.dbo.vEmployeeJobReporting EJ
--Group By FirstName,LastName,EmployeeID,CostCenter
Order by 1
IF OBJECT_ID('Tempdb..#Headcount') IS NOT NULL
Drop Table #Final1
Select max(EndDate1) as Date1, FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Into #Final1
From #Test1
Group by FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Order by 1
SELECT F.CostCenter,F.FirstName,F.LastName, F.Date1, F.CompanyCode, F.JobCode,F.EmployeeID,(t3.Day_of_Month-t2.Day_of_Month+1)*1.0/t4.Day_of_Month as Headcount,
Case
The last Select statement is the start of the non-temp table query. What can I do / write in the code to be able to run multiple times in a row? Also, the error I'm receiving:
Msg 2714, Level 16, State 6, Line 4
There is already an object named '#Test1' in the database.
Thanks!
When you write ...INTO #test1, you are creating the table based on the content of the select statement. You need to either 1) drop the temp tables at the end of your query, 2) check for them existing at the front end and drop if they exist, 3) both.
You are already checking for #headcount, but dropping #final and #test1 at the beginning. I dont see where you are declaring #headcount as a table?

Temp table in Azure SQL Server returns error on second insert in Stored Procedure

I have a temp table declared in a stored procedure within an Azure SQL Server instance.
After declaring it with
WITH temp
(cols) AS
(SELECT * FROM goaltable
WHERE someCondition = true)
and utilizing it in a couple of INSERT statements, SQL Server returns an error on the second INSERT that invalid object name 'temp'.
Will I have to declare the table again before my second INSERT statement, or is there a better way to do it?
WITH key word is used to initialise a CTE (Comman Table Expression), it is not a Temporary Table.
Temp Tables are prefixed with a pound sign # or ##(Global Temp tables, google for the differences).
A CTE's scope is limited to the very first statement after the CTE has been initialised.
WITH CTE AS
( /* Your query here */)
SELECT FROM CTE --<-- Scope of above CTE
-- it maybe select , delete, update statement here
SELECT FROM CTE --<-- this statement is out of scope
-- this will return an error
Temp Tables
In your case if you want to create a temp table and use it on multiple places you would need to do something like this...
SELECT * INTO #Temp
FROM goaltable
WHERE someCondition = true
Now this #Temp table's scope is the connection in which it is created. You can select from it multiple times anywhere in this session.
for example the following queries will be executed without any errors as long as they are executed in the same connection.
SELECT TOP 10 * FROM #Temp
SELECT * FROM #Temp
Note
Even though the scope of the temp table is your session, yet it is a good practice to drop temp tables once you are done working with them.
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
DROP TABLE #Temp

SQL Server, Insert into table from select query?

I would fill a table from a query in a stored procedure,
This works:
SELECT *
INTO #tmpTable
FROM MyTable
This works:
SELECT TOP (1) *
FROM MyTable
WHERE Land = #Land
but how do I fill #tmpTable with
SELECT TOP (1) *
FROM MyTable
WHERE Land = #Land
Because the #temp Table's scope is limited to its session (SPID), i.e. the Stored Procedure itself. After the SP execution completes the #temp table is Dropped.
Also while the SP is being executed you cannot see the #temp Table from other sessions (SPID)
USE Global temp table like ##temp even it can be accessible after execution of sp also

Temporary table in SQL Server - error occurs if the query takes long time to complete

Have a look a the following query.
select *
into TempTable
from MainTable
select * from TempTable
WAITFOR DELAY '00:00:10'
drop table TempTable
After executing this query, I open other window and execute the query:
select *
into TempTable
from MainTable
select * from TempTable
drop table TempTable
I get the following error:
There is already an object named 'TempBucket' in the database.
Suppose that it a part of the stored procedure, and it takes a long time to finish. If there's a second call to this stored procedure, this error will occur. How do I fix this error?
I assume you are using MSSQL DBMS by the tags against your post.
Use a genuine temp table: prefix the name of the table with '#'.
Using this method the temp table will exist only in the scope of the procedure within which it was created.
select *
into #TempTable
from MainTable
select * from #TempTable
No drop actually neccessary but is probably better practice.
Try this one -
IF OBJECT_ID (N'tempdb.dbo.#TempTable', 'U') IS NOT NULL
DROP TABLE #TempTable
SELECT *
INTO #TempTable
FROM dbo.MainTable
SELECT *
FROM #TempTable

Unable to drop a temporary table

I have a stored procedure which uses a temporary table. The thing is that I've tried to use the temporary table more than one time in different SELECT INTO statements. Of course, before issuing the next statement I have issued a DROP #TempTableName and then issue the SELECT INTO statement. Apparently this DROP statement isn't enough since the next SELECT INTO statement complains that the object #TempTableName already exist - SSMS output is:
Msg 2714, Level 16, State 1, Procedure SYNC_SpreadMembers, Line 23
There is already an object named '#MM_SYNC_MEMBERS' in the database.
And here is my T-SQL code:
CREATE PROCEDURE SYNC_SpreadMembers
AS
BEGIN
BEGIN
-- Member
IF (OBJECT_ID('tempdb..#MM_SYNC_MEMBERS') IS NOT NULL)
DROP TABLE #MM_SYNC_MEMBERS;
-- Imported members
SELECT DISTINCT MemberInr INTO #MM_SYNC_MEMBERS FROM
(
SELECT DISTINCT DmInr AS MemberInr FROM MM_SYNC_EBOLIGWS WHERE NOT DmInr IS NULL
UNION
SELECT DISTINCT AmInr AS MemberInr FROM MM_SYNC_EBOLIGWS WHERE NOT AmInr IS NULL
) MemberHeap
;
DELETE #MM_SYNC_MEMBERS FROM #MM_SYNC_MEMBERS Sync INNER JOIN MM_Member Member ON Sync.MemberInr = Member.InteressentNr;
INSERT INTO MM_Member(InteressentNr) SELECT MemberInr FROM #MM_SYNC_MEMBERS;
END
-- Hardcoded members
DROP TABLE #MM_SYNC_MEMBERS;
SELECT DISTINCT InteressentNr AS MemberInr INTO #MM_SYNC_MEMBERS FROM MM_SYNC_HardcodedMemberRoles;
DELETE #MM_SYNC_MEMBERS FROM #MM_SYNC_MEMBERS Sync INNER JOIN MM_Member Member ON Sync.MemberInr = Member.InteressentNr;
INSERT INTO MM_Member(InteressentNr) SELECT MemberInr FROM #MM_SYNC_MEMBERS;
-- MemberRole
-- Area Managers
DELETE MM_MemberRole;
INSERT INTO MM_MemberRole(MemberSid, RoleSid)
SELECT DISTINCT Member.[Sid], (SELECT [Sid] FROM MM_Role WHERE Cipher LIKE 'AMA')
FROM MM_SYNC_EBOLIGWS Sync
INNER JOIN MM_Member Member ON Sync.AmInr = Member.InteressentNr
WHERE Sync.AmInr IS NOT NULL
;
-- Department Managers
INSERT INTO MM_MemberRole(MemberSid, RoleSid)
SELECT DISTINCT Member.[Sid], (SELECT Sid FROM MM_Role WHERE Cipher LIKE 'DM')
FROM MM_SYNC_EBOLIGWS Sync
INNER JOIN MM_Member Member ON Sync.DmInr = Member.InteressentNr
WHERE Sync.DmInr IS NOT NULL
;
-- Hardcoded Roles
INSERT INTO MM_MemberRole(MemberSid, RoleSid)
SELECT Member.Sid, Roles.Sid
FROM MM_SYNC_HardcodedMemberRoles HCR
INNER JOIN MM_Member Member ON HCR.InteressentNr = Member.InteressentNr
INNER JOIN MM_Role Roles ON HCR.RoleCipher = Roles.Cipher
;
END
GO
T-SQL is a very simple language - it basically compiles all of the code in the current scope/batch as soon as possible. At various times (such as when a new table is created) it will recompile the batch.
The error is actually being thrown when it does the recompile immediately after you first create the new temp table. At that point, when it tries to recompile the later statement that also tries to create a temp table with the same name, it produces the error.
It doesn't wait to see whether the normal flow of execution (including control flow) will prevent an error occurring when the statement is reached. E.g. this produces a similar error:
create table #Blah (ID int)
if 1 = 0
begin
create table #Blah (Foo int)
end
Even though we can look at it and know that no harm would actually occur
Msg 2714, Level 16, State 1, Line 4
There is already an object named '#Blah' in the database.
Since the table has the same columns in both inserts, why not just create the table once, and instead of dropping it:
TRUNCATE TABLE #MM_SYNC_MEMBERS
Temporary tables are tied to a connection. So when the connection is
dropped, the temporary table is dropped.
So it won't be dropped in the middle of the stored procedure.
This will be tied to the instance it is in, it could fit your needs:
DECLARE #TemporaryTable TABLE
(
id int,
name nvarchar(50)
)
Extra:
Maybe you could also have a look at CTE's as it may be a solution for your problem:
http://msdn.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
why done you create structure of #MM_SYNC_MEMBERS globally and then you can delete or insert data in temp according to conditions.
EX-
create table #Temp
(name varchar(20))
IF(condtion1)
insert into temp (or delete)
else if(condition2)
insert to temp
.........

Resources