Using IF / ELSE to determine a SELECT INTO statement - sql

I'm having some strange issues using IF / ELSE to determine which one or two SELECT statements to execute. The error message I'm getting when running the full statement is that my temporary table already exists, but that does not occur if I run two separate executions of two separate IF statements.
Here is the code in SQL Server:
IF (select BusinessDayCount from Calendartbl) <= 1
BEGIN
SELECT * into #temp1
FROM PreviousMonthTbl
END
ELSE
BEGIN
SELECT * into #temp1
FROM CurrentMonthTbl
END

It's a "feature" of the syntax checking in SQL Server. You simply cannot "create" a #temporary table twice within the same batch.
This is the pattern you need.
SELECT * into #temp1
FROM PreviousMonthTbl
WHERE 1=0;
IF (select BusinessDayCount from Calendartbl) <= 1
BEGIN
INSERT into #temp1 SELECT *
FROM PreviousMonthTbl
END
ELSE
BEGIN
INSERT into #temp1 SELECT *
FROM CurrentMonthTbl
END
If you prefer, you can also express the branch (in this case) as a WHERE clause:
SELECT * into #temp1
FROM PreviousMonthTbl
WHERE (select BusinessDayCount from Calendartbl) <= 1
UNION ALL
SELECT *
FROM CurrentMonthTbl
WHERE isnull((select BusinessDayCount from Calendartbl),2) > 1

You can't use SELECT INTO for a tables with same name in the same batch. Use a different name for a temporary table
IF EXISTS(
SELECT 1
FROM Calendartbl
WHERE BusinessDayCount <= 1
)
BEGIN
IF OBJECT_ID('tempdb.dbo.#PreviousMonthTbl') IS NULL DROP TABLE dbo.#PreviousMonthTbl
SELECT *
INTO #PreviousMonthTbl
FROM PreviousMonthTbl
END
ELSE
BEGIN
IF OBJECT_ID('tempdb.dbo.#CurrentMonthTbl') IS NULL DROP TABLE dbo.#CurrentMonthTbl
SELECT *
INTO #CurrentMonthTbl
FROM CurrentMonthTbl
END

From what I understand the problem is this:
When you run the below statement,
SELECT * into #temp1 FROM CurrentMonthTbl
you are creating a temp table on the fly.
If before that line you had a create table statement, then this Select into statement will fail because the table already exists.
If in your case you already have a temp table created, then try replacing:
SELECT * into #temp1 FROM CurrentMonthTbl
with:
Insert into #temp1
Select * from CurrentMonthTbl
Also look at There is already an object named '##Temp' in the database

You can use actual table in place of #temp1 table in if else statement. After that you can insert the data from actual to temp table and drop the actual table.
IF OBJECT_ID('tempdb..#temp1') is not null
drop table #temp1
IF (select BusinessDayCount from Calendartbl) <= 1
BEGIN
SELECT * into dbo.TempTable
FROM PreviousMonthTbl
END
ELSE
BEGIN
SELECT * into dbo.TempTable
FROM CurrentMonthTbl
END
select * into #temp1
from dbo.TempTable
IF OBJECT_ID('dbo.TempTable', 'U') is not null
drop table dbo.TempTable

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

If Else Statement to Skip Value if populated

I am trying to create an if else script to skip a record if there is a specific value in a column of the table and continue to insert records into a different table.
How do I create the script to perform this action?
IF EXISTS (Select * From Table A where X =1)
BEGIN
Do nothing
END
ELSE
BEGIN
INSERT INTO TABLE Y
SELECT * FROM TABLE Z
END
Instead, write a single statement:
INSERT INTO TABLE Y
SELECT *
FROM TABLE Z
WHERE NOT EXISTS (Select 1 From Table A where X = 1);
The conditional is not needed at all.
If you want it in a proc to execute, use it this way
create procedure usp_insert
as
BEGIN
declare #rowcount int = (Select count(*) From TableA where X <>'1')
Begin
if #rowcount>=1
INSERT INTO TABLE Y
SELECT * FROM TABLE Z
end
END

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

Test ALL rows exists

It is very simple to test when row exists or not.
if exists(select * from dbo.APQP_head where zestaw=#zestaw)
I want to test in my query whether all rows satisfy the condition.
I need use some query like this
if All exists(select * from dbo.APQP_head where zestaw=#zestaw and type=3)
But this syntax is not correct.
if NOT exists(select * from dbo.APQP_head where zestaw<>#zestaw OR type<>3)
--all rows satisfy the condition
if your columns can be nullable, then
if NOT exists(select * from dbo.APQP_head where zestaw<>#zestaw OR type<>3)
AND NOT exists(select * from dbo.APQP_head where zestaw IS NULL OR type IS NULL)
This may perform better than an OR because it keep the AND and uses semi-joins
IF NOT EXISTS (
SELECT zestaw, [type] FROM #foo
EXCEPT
SELECT zestaw, [type] FROM #foo where zestaw=#zestaw and type=3
)
-- all rows etc
Edit, quick and dirty test (SQL Server 2008 R2 Express on workstation), the EXCEPT uses more IO (2 touches) but less CPU (more efficient plan)
If you replace #zestaw with a constant, the NOT EXISTS .. OR .. wins
CREATE TABLE excepttest (zestaw int, [type] int);
INSERT excepttest VALUES (1, 3);
GO
INSERT excepttest SELECT excepttest.* FROM excepttest
GO 21
SELECT COUNT(*) FROM excepttest
GO
CREATE INDEX IX_Test ON excepttest (zestaw, [type]);
GO
DECLARE #zestaw int = 1;
SET STATISTICS IO ON
SET STATISTICS TIME ON
if NOT exists(select * from excepttest where zestaw<>#zestaw OR [type]<>3)
SELECT 'all match'
ELSE
SELECT 'some match';
IF NOT EXISTS (
SELECT zestaw, [type] FROm excepttest
EXCEPT
SELECT zestaw, [type] FROm excepttest where zestaw=#zestaw and [type]=3
)
SELECT 'all match'
ELSE
SELECT 'some match';
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
DROP TABLE excepttest
You can invert the conditions in the WHERE clause and the whole exists expression:
if NOT exists select(select * from dbo.APQP_head where zestaw <> #zestaw OR type <> 3)
This uses a well known fact that NOT(A1 AND A2 AND ... An) == NOT(A1) OR NOT(A2)... OR NOT(An).
if not exists(select * from dbo.APQP_head where not (zestaw=#zestaw and type=3))
this is a solution for some problems:
select distinct AccAccountId from AccAccountTafsilType where AccAccountId
in (select Id From AccountForSooratVaziatFunc(5))
and AccAccountId in (select AccAccountId from AccAccountTafsilType where
TafsilTypeId in (select Id from AccTafsilType where ComplexId = 5 and
Code = 115))
and AccAccountId in (select AccAccountId from AccAccountTafsilType where
TafsilTypeId in (select Id from AccTafsilType where ComplexId = 5 and
Code = 116))

How can I use if statement after a CTE (SQL Server 2005)

Last night I was writing a simple T-SQL program something like this
DECLARE #ROLEID AS INT
SELECT #ROLEID = [ROLE ID] FROM TBLROLE
;WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
IF (#ROLEID = 1)
BEGIN
//SOMECODE
END
ELSE IF(#ROLEID = 2)
BEGIN
//SOMECODE
END
ELSE
BEGIN
//SOMECODE
END
I found after compilation that it is throwing error something like "Incorrect statement near if"
What is wrong?
However, I did that by using some other way. But I wanted to know why it did not work!
Common table expressions are defined within the context of a single statement:
WITH cte_name AS (
<cte definition>)
<statement that uses cte>;
So you can do something like:
WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
SELECT * FROM CTE;
or
WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
UPDATE CTE
SET somefield = somevalue
WHERE id = somekey;
A CTE must be followed by a single
SELECT, INSERT, UPDATE, MERGE, or
DELETE statement that references some
or all the CTE columns. A CTE can also
be specified in a CREATE VIEW
statement as part of the defining
SELECT statement of the view
A little late but I can't be the only one bumping into this.
A solution could be to create a temporary table like this:
-- If previous run of this query fails, the temp table will be deleted.
-- Selecting into creates the temp table which fails if it already exists
IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#dtBalansOpgesteldGefilterd%') BEGIN
DROP TABLE #temp
END;
;WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
-- Followed by select statement as required
SELECT *
INTO #temp
FROM CTE
IF #awsome = 1
BEGIN
SELECT 'WHATEVERYOUWANT' AS WhateverColumnNameYouWant, *
FROM #temp
END
The closest you'll get is using a UNION ALL to do a crude switched select:
DECLARE #ROLEID AS INT
SELECT #ROLEID = [ROLE ID] FROM TBLROLE
;WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
SELECT
--somecolumns
FROM
CTE
--other stuff too
WHERE
#ROLEID = 1
UNION ALL
SELECT
--somecolumns
FROM
CTE
--other stuff too
WHERE
#ROLEID = 2
UNION ALL
SELECT
--somecolumns
FROM
CTE
--other stuff too
WHERE
#ROLEID = 3
...
UNION ALL
SELECT
--somecolumns
FROM
CTE
--other stuff too
WHERE
#ROLEID = n
Try putting the CTE in the IF. It worked for me.
IF #awsome = 1
BEGIN
;WITH CTE
AS
(
SELECT * FROM SOMETABLE
)
SELECT 'WHATEVERYOUWANT' FROM CTE
END
ELSE IF #awesome = 2
BEGIN
;WITH CTE2
AS
(
SELECT * FROM SOMETABLE
)
SELECT 'WHATEVERYOUWANT' FROM CTE2
END