Sie sind auf Seite 1von 6

// home // advanced search // news // categories // sql build chart // downloads // statistics

ASP FAQ
Home A SP FA Q Tutorials :: Databases :: Other A rticles :: Should I use a #temp table or a @table v ariable?
A SP FA Q Tutorials
Ads by Google
Temp Agencies
Temp Work
Variable Annuity
Table Function
Temp Probes LosIngenierosUT P.com/Admision Ads by Google

8000XXXX Errors
Alerts
Should I use a #temp table or a @table variable?
ASP.NET 2.0 In a stored procedure, y ou often hav e a need for storing a set of data within the procedure, without necessarily needing
Classic ASP 1.0 that data to persist bey ond the scope of the procedure. If y ou actually need a table structure, there are basically four
way s y ou can "store" this data: local temporary tables (#table_name), global temporary tables (##table_name), permanent
Databases tables (table_name), and table v ariables (@table_name).
Access DB & ADO
General SQL Serv er & A ccess A rticles There is a partial list of questions and answers about table v ariables, including some differences between table v ariables and
#temp tables, in KB #305977 - INF: Frequently Ask ed Questions - SQL Serv er 2000 - Table Variables.
My SQL
Other A rticles
Local Temporary Tables
Schema Tutorials
Sql Serv er 2000
CREATE TABLE #people
Sql Serv er 2005 (
id INT,
General Concepts
name VARCHAR(32)
Search Engine Optimization (SEO) )

A temporary table is created and populated on disk , in the sy stem database tempdb — with a session-specific identifier
Fast Voas pack ed onto the name, to differentiate between similarly -named #temp tables created from other sessions. The data in this
Solid-state , 1,4,8 #temp table (in fact, the table itself) is v isible only to the current scope (usually a stored procedure, or a set of nested
C hanne ls Sub stored procedures). The table gets cleared up automatically when the current procedure goes out of scope, but y ou
Micro-se cond should manually clean up the data when y ou're done with it:
R e sponse
www.kotura.com
DROP TABLE #people
MEDWA Y®
Variable Speed This will be better on resources ("release early ") than if y ou let the sy stem clean up *after* the current session finishes the
Ma nufacture r of rest of its work and goes out of scope.
Va riable Spe e d
Be lts W 16 - A common use of #temp tables is to summarize/compact/reorganize data coming from another stored procedure. So, tak e
W 100,13x 6 - 55x 16 this example, which pares down the results of the sy stem procedure sp_who2 into only the SPID, Status, and HostName of
size s *activ e* processes that are *not* part of the regular operation of the sy stem:
www.medwaypt.co.uk
VOA , Optical
Switch CREATE TABLE #sp_who3
1-ch, 2-ch VO A, (
m ulti-ch VO A array SPID INT,
1x 2, 1x 4, 1x 8 Status VARCHAR(32) NULL,
Login SYSNAME NULL,
O ptical Switch
www.VitexTech.com HostName SYSNAME NULL,
BlkBy SYSNAME NULL,
Newfoil Printing DBName SYSNAME NULL,
Machines Command VARCHAR(32) NULL,
Ma nufacture Hot CPUTime INT NULL,
Foil Labe l Stam ping DiskIO INT NULL,
Die C utting and LastBatch VARCHAR(14) NULL,
ProgramName VARCHAR(32) NULL,
C onve rting
SPID2 INT
Ma chine s )
www.newfoilmachines.co.uk
SQL Server ODBC
INSERT #sp_who3 EXEC sp_who2 'active'
Drivers
Q uick & se cure SELECT SPID, Status, HostName FROM #sp_who3
acce ss from Linux , WHERE spid > 15
W indows, O SX &
othe r Unix O Ss... DROP TABLE #sp_who3
www.openlinksw.com

One of the main benefits of using a #temp table, as opposed to a permanent table, is the reduction in the amount of
Contact Us lock ing required (since the current user is the only user accessing the table), and also there is much less logging inv olv ed.
Site Map (You could also increase this performance by placing tempdb on a separate driv e... but that's another story .)
Search
One minor problem with #temp tables is that, because of the session-specific identifier that is tack ed onto the name, the
name y ou giv e it is limited to 116 characters, including the # sign (while other table ty pes are limited to 128). If y ou try ,
y ou will see this:
Web
aspfaq.com Server: Msg 193, Level 15, State 1, Line 1
The object or column name starting with '#<long string here>' is too long. The maximum length is 116
tutorials.aspfaq.com characters.
databases.aspfaq.com
S earch N ow Hopefully this won't be a limitation in y our env ironment, because I can't imagine a table name that long being useful or
manageable.

A nother potential problem with #temp tables is that, if y ou enter a transaction and use a #temp table, and then cancel
without ev er issuing a ROLLBA CK or COMMIT, y ou could be causing unnecessary lock s in tempdb (for more information,
see KB #159747 ).
Global Temporary Tables

CREATE TABLE ##people


(
id INT,
name VARCHAR(32)
)

Global temporary tables operate much lik e local temporary tables; they are created in tempdb and cause less lock ing and
logging than permanent tables. Howev er, they are v isible to all sessions, until the creating session goes out of scope (and
the global ##temp table is no longer being referenced by other sessions). If two different sessions try the abov e code, if
the first is still activ e, the second will receiv e the following:

Server: Msg 2714, Level 16, State 6, Line 1


There is already an object named '##people' in the database.

I hav e y et to see a v alid justification for the use of a global ##temp table. If the data needs to persist to multiple users, then
it mak es much more sense, at least to me, to use a permanent table. You can mak e a global ##temp table slightly more
permanent by creating it in an autostart procedure, but I still fail to see how this is adv antageous ov er a permanent table.
With a permanent table, y ou can deny permissions; y ou cannot deny users from a global ##temp table.

Permanent Tables

CREATE TABLE people


(
id INT,
name VARCHAR(32)
)

A permanent table is created in the local database, howev er y ou can (unlik e #temp tables) choose to create a table in
another database, or ev en on another serv er, for which y ou hav e access. Lik e global ##temp tables, a permanent table
will persist the session in which it is created, unless y ou also explicitly drop the table. (For contention and concurrency
reasons, creating a "temporary " permanent table in this manner doesn't really mak e a lot of sense.) If y ou are planning to
create a permanent table when the procedure runs, y ou should check to see if it exists, in order to av oid errors lik e the
one mentioned abov e. For more information about check ing for the existence of both local #temp tables and permanent
tables, see A rticle #2458 .

Lik e global ##temp tables, there seems to be little reason to use a permanent table unless the data is going to persist... and
if that is the case, why not create the permanent table before the stored procedure is ev er run, thereby eliminating all the
CREA TE / DROP logic?

Table Variables

DECLARE @people TABLE


(
id INT,
name VARCHAR(32)
)

A table v ariable is created in memory , and so performs slightly better than #temp tables (also because there is ev en less
lock ing and logging in a table v ariable). A table v ariable might still perform I/O to tempdb (which is where the
performance issues of #temp tables mak e themselv es apparent), though the documentation is not v ery explicit about this.

Table v ariables are automatically cleared when the procedure or function goes out of scope, so y ou don't hav e to
remember to drop or clear the data (which can be a good thing or a bad thing; remember "release early "?). The tempdb
transaction log is less impacted than with #temp tables; table v ariable log activ ity is truncated immediately , while #temp
table log activ ity persists until the log hits a check point, is manually truncated, or when the serv er restarts.

Table v ariables are the only way y ou can use DML statements (INSERT, UPDATE, DELETE) on temporary data within a
user-defined function. You can create a table v ariable within a UDF, and modify the data using one of the abov e
statements. For example, y ou could do this:

CREATE FUNCTION dbo.example1


(
)
RETURNS INT
AS
BEGIN
DECLARE @t1 TABLE (i INT)
INSERT @t1 VALUES(1)
INSERT @t1 VALUES(2)
UPDATE @t1 SET i = i + 5
DELETE @t1 WHERE i < 7

DECLARE @max INT


SELECT @max = MAX(i) FROM @t1
RETURN @max
END
GO

Howev er, try that with a #temp table:


CREATE FUNCTION dbo.example2
(
)
RETURNS INT
AS
BEGIN
CREATE TABLE #t1 (i INT)
INSERT #t1 VALUES(1)
INSERT #t1 VALUES(2)
UPDATE #t1 SET i = i + 5
DELETE #t1 WHERE i < 7

DECLARE @max INT


SELECT @max = MAX(i) FROM #t1
RETURN @max
END
GO

Results:

Server: Msg 2772, Level 16, State 1, Procedure example2, Line 7


Cannot access temporary tables from within a function.

Or try accessing a permanent table:

CREATE TABLE table1


(
id INT IDENTITY,
name VARCHAR(32)
)
GO

CREATE FUNCTION dbo.example3


(
)
RETURNS INT
AS
BEGIN
INSERT table1(name) VALUES('aaron')
RETURN SCOPE_IDENTITY()
END
GO

Results:

Server: Msg 443, Level 16, State 2, Procedure example3, Line 8


Invalid use of 'INSERT' within a function.

Table v ariables can lead to fewer stored procedure recompilations than temporary tables (see KB #243586 and KB
#305977 ), and — since they cannot be rolled back — do not bother with the transaction log.

So, why not use table v ariables all the time? W ell, when something sounds too good to be true, it probably is. Let's v isit
some of the limitations of table v ariables (part of this list was deriv ed from KB #305977 ):

Table v ariables are only allowed in SQL Serv er 2000+, with compatibility lev el set to 80 or higher.

You cannot use a table v ariable in either of the following situations:

INSERT @table EXEC sp_someProcedure

SELECT * INTO @table FROM someTable

You cannot truncate a table v ariable.

Table v ariables cannot be altered after they hav e been declared.

You cannot explicitly add an index to a table v ariable, howev er y ou can create a sy stem index through a PRIMA RY
KEY C ONSTRAINT, and y ou can add as many indexes v ia UNIQUE C ONSTRA INTs as y ou lik e. What the optimizer
does with them is another story . <G> One thing to note is that y ou cannot explicitly name y our constraints, e.g.:

DECLARE @myTable TABLE


(
CPK1 int,
CPK2 int,
CONSTRAINT myPK PRIMARY KEY (CPK1, CPK2)
)

-- yields:
Server: Msg 156, Level 15, State 1, Line 6
Incorrect syntax near the keyword 'CONSTRAINT'.

-- yet the following works:


DECLARE @myTable TABLE
(
CPK1 int,
CPK2 int,
PRIMARY KEY (CPK1, CPK2)
)
You cannot use a user-defined function (UDF) in a CHECK CONSTRA INT, computed column, or DEFA ULT
CONSTRA INT.

You cannot use a user-defined ty pe (UDT) in a column definition.

Unlik e a #temp table, y ou cannot drop a table v ariable when it is no longer necessary —y ou just need to let it go
out of scope.

You cannot generate a table v ariable's column list dy namically , e.g. y ou can't do this:

SELECT * INTO @tableVariable

-- yields:

Server: Msg 170, Level 15, State 1, Line 1


Line 1: Incorrect syntax near '@tableVariable'.

You also can't build the table v ariable inside dy namic SQL, and expect to use it outside that scope, e.g.:

DECLARE @colList VARCHAR(8000), @sql VARCHAR(8000)


SET @colList = 'a INT,b INT,c INT'
SET @sql = 'DECLARE @foo TABLE('+@colList+')'
EXEC(@sql)
INSERT @foo SELECT 1,2,3

-- this last line fails:

Server: Msg 137, Level 15, State 2, Line 5


Must declare the variable '@foo'.

This is because the rest of the script k nows nothing about the temporary objects created within the dy namic SQL.
Lik e other local v ariables, table v ariables declared inside of a dy namic SQL block (EXEC or sp_executeSQL) cannot
be referenced from outside, and v ice-v ersa. So y ou would hav e to write the whole set of statements to create and
operate on the table v ariable, and perform it with a single call to EXEC or sp_executeSQL.

The sy stem will not generate automatic statistics on table v ariables. Lik ewise, y ou cannot manually create statistics
(statistics are used to help the optimizer pick the best possible query plan).

A n INSERT into a table v ariable will not tak e adv antage of parallelism.

A table v ariable will alway s hav e a cardinality of 1, because the table doesn't exist at compile time.

Table v ariables must be referenced by an alias, except in the FROM clause. Consider the following two scripts:

CREATE TABLE #foo(id INT)


DECLARE @foo TABLE(id INT)
INSERT #foo VALUES(1)
INSERT #foo VALUES(2)
INSERT #foo VALUES(3)
INSERT @foo SELECT * FROM #foo

SELECT id
FROM @foo
INNER JOIN #foo
ON @foo.id = #foo.id

DROP TABLE #foo

The abov e fails with the following error:

Server: Msg 137, Level 15, State 2, Line 11


Must declare the variable '@foo'.

This query , on the other hand, work s fine:

SELECT id
FROM @foo f
INNER JOIN #foo
ON f.id = #foo.id

Table v ariables are not v isible to the calling procedure in the case of nested procs. The following is legal with #temp
tables:

CREATE PROCEDURE faq_outer


AS
BEGIN
CREATE TABLE #outer
(
letter CHAR(1)
)

EXEC faq_inner

SELECT letter FROM #outer


DROP TABLE #outer
END
GO

CREATE PROCEDURE faq_inner


AS
BEGIN
INSERT #outer VALUES('a')
END
GO

EXEC faq_outer

Results:

letter
------
a

(1 row(s) affected)

Howev er, y ou cannot do this with table v ariables. The parser will find the error before y ou can ev en create it:

CREATE PROCEDURE faq_outer


AS
BEGIN
DECLARE @outer TABLE
(
letter CHAR(1)
)

EXEC faq_inner

SELECT letter FROM @outer


END
GO

CREATE PROCEDURE faq_inner


AS
BEGIN
INSERT @outer VALUES('a')
END
GO

Results:

Server: Msg 137, Level 15, State 2, Procedure faq_inner, Line 4


Must declare the variable '@outer'.

For more information about sharing data between stored procedures, please see this article by Erland
Sommarsk og.

Conclusion

Lik e many other areas of technology , there is no "right" answer here. For data that is not meant to persist bey ond the
scope of the procedure, y ou are ty pically choosing between #temp tables and table v ariables. Your ultimate decision
should depend on performance and reasonable load testing. A s y our data size gets larger, and/or the repeated use of the
temporary data increases, y ou will find that the use of #temp tables mak es more sense. Depending on y our env ironment,
that threshold could be any where — howev er y ou will obv iously need to use #temp tables if any of the abov e limitations
represents a significant roadblock .

Related Articles

How do I build a query with optional parameters?


How do I calculate the median in a table?
How do I create a store locator feature?
How do I deal with MEMO, TEXT, HYPERLINK, and CURRENCY columns?
How do I deal with multiple resultsets from a stored procedure?
How do I debug my SQL statements?
How do I determine if a column exists in a giv en table?
How do I enable or disable connection pooling?
How do I enumerate through the DSNs on a machine?
How do I find a stored procedure containing <text>?
How do I get a list of Access tables and their row counts?
How do I get the latest v ersion of the JET OLEDB driv ers?
How do I handle alphabetic paging?
How do I handle BIT / BOOLEA N columns?
How do I handle error check ing in a stored procedure?
How do I ignore common words in a search?
How do I page through a recordset?
How do I present one-to-many relationships in my ASP page?
How do I prev ent duplicates in a table?
How do I prev ent my ASP pages from waiting for back end activ ity ?
How do I prev ent NULLs in my database from muck ing up my HTML?
How do I protect my Access database (MDB file)?
How do I protect my stored procedure code?
How do I protect my self against the W32.Slammer worm?
How do I remov e duplicates from a table?
How do I rename a column?
How do I retriev e a random record?
How do I return row numbers with my query ?
How do I send a database query to a text file?
How do I simulate an array inside a stored procedure?
How do I solv e 'Could not find installable ISA M' errors?
How do I solv e 'Operation must use an updateable query ' errors?
How do I temporarily disable a trigger?
How do I use a SELEC T list alias in the WHERE or GROUP BY clause?
How do I use a v ariable in an ORDER BY clause?
Should I index my database table(s), and if so, how?
Should I store images in the database or the filesy stem?
Should I use a v iew, a stored procedure, or a user-defined function?
Should I use recordset iteration, or GetRows(), or GetString()?
What are all these dt_ stored procedures, and can I remov e them?
What are the limitations of MS A ccess?
What are the limitations of MSDE?
What are the v alid sty les for conv erting datetime to string?
What dataty pe should I use for my character-based database columns?
What dataty pe should I use for numeric columns?
What does "ambiguous column name" mean?
What is this 'Multiple-step OLE DB' error?
What is wrong with 'SELECT *'?
What naming conv ention should I use in my database?
What should I choose for my primary k ey ?
What should my connection string look lik e?
When should I use CreateObject to create my recordset objects?
Where can I get this 'Book s Online' documentation?
Where do I get MSDE?
Which database platform should I use for my A SP application?
Which tool should I use: Enterprise Manager or Query A naly zer?
Why are there gaps in my IDENTITY / AUTO INCREMENT column?
Why can I not 'open a database created with a prev ious v ersion...'?
Why can't I access a database or text file on another serv er?
Why can't I use the TOP k ey word?
Why do I get 'A rgument data ty pe text is inv alid for argument [...]'?
Why do I get 'Not enough space on temporary disk ' errors?
Why does A SP giv e me A ctiv eX errors when connecting to a database?
Should I use C OALESCE() or ISNULL()?
Where can I get basic info about using stored procedures?

Created: 8/20/2003 | Last Updated: 1/22/2005 | brok en link s | helpful | not helpful | statistics
© Copy right 2006, UBR, Inc. A ll Rights Reserv ed. (196)

Copy right 1999-2006, A ll rights reserv ed.

LosIngenierosUT P.com/ Ads by Google


Finding content. An error has occured...

Das könnte Ihnen auch gefallen