tags:

views:

362

answers:

6

Okay, I've got what is probably a very easy question for you Sql gurus out there...

Given a boolean of some kind, T, I want to populate a temp table with data set A, if T is true, or data set B, if T is false. I thought this would be how to do it:

DECLARE @foo INT
SET @foo = null

IF (@foo is null)
    BEGIN
        SELECT 'foo was null' INTO #TempTable
    END
ELSE
    BEGIN
        SELECT 'foo not null' INTO #TempTable
    END

But this doesn't work. I get an error that reads "There is already an object named '#TempTable' in the database."

Apparently Sql is trying to create the table in each case, before it evaluates the condition...? That seems odd to me, but okay... But what's the proper way to do something like this?

Edit: I'm in Sql Server, but I suspect that this is a more universal issue...but if I'm wrong, please let me know.

+3  A: 

You'll need to create your temporary table first (it should be done once):

CREATE TABLE #TempTable TABLE (
        message VARCHAR(50)
)

, then issue:

DECLARE @foo INT
SET @foo = null

IF (@foo is null)
    BEGIN
        INSERT
        INTO    #TempTable
        SELECT 'foo was null'
    END
ELSE
    BEGIN
        INSERT
        INTO    #TempTable
        SELECT 'foo not null'
    END

Probably you want not a TEMPORARY TABLE, but a TABLE VARIABLE (which lives only during the session and does not persist in the database schema):

DECLARE @foo INT
DECLARE @TempTable TABLE (
        message VARCHAR(50)
        )
SET @foo = null

IF (@foo is null)
    BEGIN
        INSERT
        INTO    @TempTable
        SELECT 'foo was null'
    END
ELSE
    BEGIN
        INSERT
        INTO    @TempTable
        SELECT 'foo not null'
    END
Quassnoi
Yes. But they can be slow sometimes while handling large amounts of data.
Kirtan
This is very good and helpful. I'm likely to give it accepted answer...but the first part doesn't quite work for me, because it changes the format from "select..into" into a "insert into..select", which is fine, but it means that I have to create and drop the temp table manually. (Which is fine, of course...I'd just like to see that part of the answer updated for posterity). I like the second answer...I haven't used Table Variables before...I'll have to do some research on them! Seem great!
Beska
Good update. There you go.
Beska
@Kirtan...good point...after testing, I'm actually going to end up using a temp table because of performance issues.
Beska
+1  A: 

The table has been created already, you'll have to drop it first and then insert into it again.

EDIT: As you said, its not an issue of table being already present in the database, you can try to do it like this -

IF EXISTS (SELECT * FROM sysobjects WHERE object_id = OBJECT_ID(N'#TempTable')
    DROP TABLE #TempTable


CREATE TABLE #TempTable (Col1 INT, ...)

IF TRUE
BEGIN
    INSERT INTO #TempTable
    SELECT VAL1
END
ELSE
BEGIN
    INSERT INTO #TempTable
    SELECT VAL2
END
Kirtan
Nope. Checked. Table doesn't exist before the statement is run. It just doesn't like both of the references in there. If I remove a ref, it creates it without a problem.
Beska
+1  A: 

See if this helps...link

You have to create your temp table outside of your select statements and then insert into it. For example,

CREATE TABLE #tmp_table AS SELECT * FROM PRODUCTS WHERE 1 = 2

IF @condition = 0 BEGIN INSERT #tmp_table SELECT * FROM products .... END ELSE ....

aintnoprophet
+2  A: 

SQL is running into this issue because the parsing step is noticing that there are two SELECT INTO statements. Even though your logic would dictate that the temporary table would only be created once, the parser still complains about it.

One way to get around this is by using GO statements after the SELECT INTOs, but that won't work with the conditional logic.

Otherwise, just create the table seperately and insert into it like so:

CREATE TABLE #TempTable (result varchar(50))

IF @foo is null
BEGIN
   insert into #TempTable values ('foo was null')
END
ELSE
BEGIN
   insert into #TempTable values('foo was not null')
END
Ryan Brunner
+3  A: 

Why not use a set-based, rather than procedural solution:

SELECT CASE WHEN @foo is null 
            THEN 'foo was null'
            ELSE 'foo not null'
       END                      AS result
INTO  #TempTable
Ed Harper
Very good point. This is much less code and much easier to read and maintain.
Rob Garrison