352

I have the following code in one of my Sql (2008) Stored Procs which executes perfectly fine:

    CREATE PROCEDURE [dbo].[Item_AddItem]
        @CustomerId uniqueidentifier,
        @Description nvarchar(100),
        @Type int,
        @Username nvarchar(100),
    AS
    BEGIN

        DECLARE @TopRelatedItemId uniqueidentifier;
        SET @TopRelatedItemId = 
        (
           SELECT top(1) RelatedItemId 
           FROM RelatedItems 
           WHERE CustomerId = @CustomerId
        ) 

        DECLARE @TempItem TABLE
        (
            ItemId uniqueidentifier,
            CustomerId uniqueidentifier,
            Description nvarchar(100),
            Type int,
            Username nvarchar(100),
            TimeStamp datetime
        );

        INSERT INTO Item
        OUTPUT INSERTED.* INTO @TempItem
        SELECT NEWID(), @CustomerId, @Description, @Type, @Username, GETDATE()

        SELECT
            ItemId,
            CustomerId,
            @TopRelatedItemId,
            Description,
            Type,
            Username,
            TimeStamp
        FROM
            @TempItem
END
GO

So the question for you guys is is there a possibility to do something along the lines of:

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

So that I could reuse this data from memory in other following statements? SQL Server throws a fit with the above statement, however i don't want to have to create separate variables and initialize each one of them via a separate SELECT statement against the same table.... UGH!!!

Any suggestions on how to achieve something along the lines without multiple queries against the same table?

2
  • 1
    "to create separate variables and initialize each one of them via a separate SELECT statement" - why would you need to do that? declare @t table once, and if you need to reuse it, fire a DELETE @TempCustomer before inserting into it again Commented Jan 28, 2011 at 1:40
  • You can use the Table Variable - mssqltips.com/sqlservertip/6039/… Commented Feb 25, 2022 at 8:30

8 Answers 8

674

If you wanted to simply assign some variables for later use, you can do them in one shot with something along these lines:

declare @var1 int,@var2 int,@var3 int;

select 
    @var1 = field1,
    @var2 = field2,
    @var3 = field3
from
    table
where
    condition

If that's the type of thing you're after

Sign up to request clarification or add additional context in comments.

6 Comments

Best answer imho, but what happens if the results are more than one?
If the results are more than one, you will get one of the available values. That could make for an interesting puzzle! See mssqltips.com/sqlservertip/1888/…
To force the query to return a single row use SELECT TOP 1
@Adrian Yes, the above query assumes you've selected a single row. You could also use ordering and aggregate functions if you want more fancy logic.
In case if you aren't using the database type that the OP is using, not all support TOP 1 as Adrian mentioned. SQL Server / MS Access use TOP, MySQL uses LIMIT, and Oracle uses ROWNUM. See w3schools.com/sql/sql_top.asp for more information.
|
250

You cannot SELECT .. INTO .. a TABLE VARIABLE. The best you can do is create it first, then insert into it. Your 2nd snippet has to be

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT INTO 
    @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

3 Comments

Should note that this works just fine in a CTE context as well. Bazinga!
Anyone have an answer as to why one cannot select into a table variable like you can with an actual temporary table?
Why it's not possible? Probably to prevent the possibility of blowing up your database server with out of memory exception. The DB server needs to be a very stable process...
45

You can do this:

SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email
INTO #tempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

then later

SELECT CustomerId FROM #tempCustomer

you don't need to declare the structure of #tempCustomer

3 Comments

@webturner Neither of those points are true. Temp tables aren't scoped outside of the proc and table variables aren't any more "memory only" than temp tables.
Don't forget to add a DROP TABLE #tempCustomer when #tempCustomer is not needed anymore otherwise the next select will cause a #tempCustomer already exists error
@ViRuSTriNiTy It is only visible to the current session. Once the session ends or the connection is terminated, this table is automatically dropped.
21

It looks like your syntax is slightly out. This has some good examples

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

Then later

SELECT CustomerId FROM @TempCustomer

1 Comment

Due to a redirect from dbforums, that "good examples" link has transformed into an ad. Is there a better link for what you intended?
4

Sounds like you want temp tables. http://www.sqlteam.com/article/temporary-tables

Note that #TempTable is available throughout your SP.

Note the ##TempTable is available to all.

4 Comments

##temptable - until the owner(creator) deletes it or gets disconnected
I don't want temp tables. Temp tables are expensive and slow. I just want to keep a bit of data for a specific record for a small amount of time and make it available to multiple sql statements, without subsequent lookups. Since Table Variables have scope within the stored proc they were defined in, they are the perfect solution for storing tuppled data for that one stored proc call...
I also forgot to mention that the DB resides in Azure.... I don't want to introduce a mess out of managing temp tables.
Variable table is the way to go. declare @varTable Table (....)
3

I found your question looking for a solution to the same problem; and what other answers fail to point is a way to use a variable to change the name of the table for every execution of your procedure in a permanent form, not temporary.

So far what I do is concatenate the entire SQL code with the variables to use. Like this:

declare @table_name as varchar(30)
select @table_name = CONVERT(varchar(30), getdate(), 112)
set @table_name = 'DAILY_SNAPSHOT_' + @table_name

EXEC('
        SELECT var1, var2, var3
        INTO '+@table_name+'
        FROM my_view
        WHERE string = ''Strings must use double apostrophe''
    ');

I hope it helps, but it could be cumbersome if the code is too large, so if you've found a better way, please share!

Comments

0

Another option is to set a default for your variables. This way you don't need to create a temp table or execute multiple statements against the database. This worked for me on a query where I only needed 1 field; I don't know if this will translate to multiple fields.

DECLARE @Result CHAR(1) = 'N'; -- Default if no row is found
SELECT TOP(1) @Result = Field FROM Table WHERE whatever
SELECT @Result

Comments

-2
"SELECT *
  INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId"

Which means creating a new @tempCustomer tablevariable and inserting data FROM Customer. You had already declared it above so no need of again declaring. Better to go with

INSERT INTO @tempCustomer SELECT * FROM Customer

1 Comment

It doesn't work. You still need to declare the table variable beforehand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.