<p>Recently, I started changing some of our applications to support <code>MS SQL Server</code> as an alternative back end. </p>

<p>One of the compatibility issues I ran into is the use of MySQL's CREATE TEMPORARY TABLE to create in-memory tables that hold data for very fast access during a session with no need for permanent storage.</p>

<p>What is the equivalent in MS SQL?</p>

<p>A requirement is that I need to be able to use the temporary table just like any other, especially <code>JOIN</code> it with the permanent ones.</p>

[{'answer_id': 27840, 'author': 'Iain Holder', 'author_id': 1122, 'author_profile': 'https://Stackoverflow.com/users/1122', 'pm_score': 0, 'selected': False, 'text': '<p>CREATE TABLE #tmptablename</p>\n\n<p>Use the hash/pound sign prefix</p>\n'}, {'answer_id': 27842, 'author': 'Matt Hamilton', 'author_id': 615, 'author_profile': 'https://Stackoverflow.com/users/615', 'pm_score': 2, 'selected': False, 'text': '<p>You can declare a "table variable" in SQL Server 2005, like this:</p>\n\n<pre><code>declare @foo table (\n    Id int,\n    Name varchar(100)\n);\n</code></pre>\n\n<p>You then refer to it just like a variable:</p>\n\n<pre><code>select * from @foo f\n    join bar b on b.Id = f.Id\n</code></pre>\n\n<p>No need to drop it - it goes away when the variable goes out of scope.</p>\n'}, {'answer_id': 27844, 'author': 'Tundey', 'author_id': 1453, 'author_profile': 'https://Stackoverflow.com/users/1453', 'pm_score': 0, 'selected': False, 'text': '<p>The syntax you want is:</p>\n\n<p>create table #tablename</p>\n\n<p>The # prefix identifies the table as a temporary table.</p>\n'}, {'answer_id': 27848, 'author': 'JamesSugrue', 'author_id': 1075, 'author_profile': 'https://Stackoverflow.com/users/1075', 'pm_score': 1, 'selected': False, 'text': '<p>A good <a href="http://arplis.com/temporary-tables-in-microsoft-sql-server/" rel="nofollow noreferrer">blog post here</a> but basically prefix local temp tables with # and global temp with ## - eg</p>\n\n<pre><code>CREATE TABLE #localtemp\n</code></pre>\n'}, {'answer_id': 27849, 'author': 'Keith', 'author_id': 905, 'author_profile': 'https://Stackoverflow.com/users/905', 'pm_score': 4, 'selected': False, 'text': '<p>You can create table variables (in memory), and two different types of temp table:</p>\n\n<pre><code>--visible only to me, in memory (SQL 2000 and above only)\ndeclare @test table (\n    Field1 int,\n    Field2 nvarchar(50)\n);\n\n--visible only to me, stored in tempDB\ncreate table #test (\n    Field1 int,\n    Field2 nvarchar(50)\n)\n\n--visible to everyone, stored in tempDB\ncreate table ##test (\n    Field1 int,\n    Field2 nvarchar(50)\n)\n</code></pre>\n\n<hr>\n\n<p><strong>Edit:</strong></p>\n\n<p>Following feedback I think this needs a little clarification.</p>\n\n<p><code>#table</code> and <code>##table</code> will always be in TempDB.</p>\n\n<p><code>@Table</code> variables will normally be in memory, but are not guaranteed to be. SQL decides based on the query plan, and uses TempDB if it needs to.</p>\n'}, {'answer_id': 27895, 'author': 'Manu', 'author_id': 2133, 'author_profile': 'https://Stackoverflow.com/users/2133', 'pm_score': 5, 'selected': True, 'text': '<p>@Keith</p>\n\n<p>This is a common misconception: Table variables are NOT necessarily stored in memory. In fact SQL Server decides whether to keep the variable in memory or to spill it to TempDB. There is no reliable way (at least in SQL Server 2005) to ensure that table data is kept in memory. For more detailed info look <a href="http://blogs.msdn.com/sqlserverstorageengine/archive/2008/03/30/sql-server-table-variable-vs-local-temporary-table.aspx" rel="noreferrer">here</a></p>\n'}, {'answer_id': 977076, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>I understand what you're trying to achieve. Welcome to the world of a variety of databases!</p>\n\n<p>SQL server 2000 supports temporary tables created by prefixing a # to the table name, making it a locally accessible temporary table (local to the session) and preceding ## to the table name, for globally accessible temporary tables e.g #MyLocalTable and ##MyGlobalTable respectively.</p>\n\n<p>SQL server 2005 and above support both temporary tables (local, global) and table variables - watch out for new functionality on table variables in SQL 2008 and release two! The difference between temporary tables and table variables is not so big but lies in the the way the database server handles them.</p>\n\n<p>I would not wish to talk about older versions of SQL server like 7, 6, though I have worked with them and it's where I came from anyway :-)</p>\n\n<p>It’s common to think that table variables always reside in memory but this is wrong. Depending on memory usage and the database server volume of transactions, a table variable's pages may be exported from memory and get written in tempdb and the rest of the processing takes place there (in tempdb).</p>\n\n<p>Please note that tempdb is a database on an instance with no permanent objects in nature but it’s responsible for handling workloads involving side transactions like sorting, and other processing work which is temporary in nature. On the other hand, table variables (usually with smaller data) are kept in memory (RAM) making them faster to access and therefore less disk IO in terms of using the tempdb drive when using table variables with smaller data compared to temporary tables which always log in tempdb.</p>\n\n<p>Table variables cannot be indexed while temporary tables (both local and global) can be indexed for faster processing in case the amount of data is large. So you know your choice in case of faster processing with larger data volumes by temporary transactions. It's also worth noting that transactions on table variables alone are not logged and can't be rolled back while those done on temporary tables can be rolled back!</p>\n\n<p>In summary, table variables are better for smaller data while temporary tables are better for larger data being processed temporarily. If you also want proper transaction control using transaction blocks, table variables are not an option for rolling back transactions so you're better off with temporary tables in this case.</p>\n\n<p>Lastly, temporary tables will always increase disk IO since they always use tempdb while table variables may not increase it, depending on the memory stress levels.</p>\n\n<p>Let me know if you want tips on how to tune your tempdb to earn much faster performance to go above 100%!</p>\n"}, {'answer_id': 27886095, 'author': 'Joezer', 'author_id': 1994420, 'author_profile': 'https://Stackoverflow.com/users/1994420', 'pm_score': 2, 'selected': False, 'text': '<p>It is possible with MS SQL Server 2014.</p>\n\n<p>See: <em><a href="http://msdn.microsoft.com/en-us/library/dn133079.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/dn133079.aspx</a></em></p>\n\n<p>Here is an example of SQL generation code (from MSDN):</p>\n\n<pre><code>-- create a database with a memory-optimized filegroup and a container.\nCREATE DATABASE imoltp \nGO\n\nALTER DATABASE imoltp ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA \nALTER DATABASE imoltp ADD FILE (name=\'imoltp_mod1\', filename=\'c:\\data\\imoltp_mod1\') TO FILEGROUP imoltp_mod \nALTER DATABASE imoltp SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=ON\nGO\n\nUSE imoltp\nGO\n\n\n-- create a durable (data will be persisted) memory-optimized table\n-- two of the columns are indexed\nCREATE TABLE dbo.ShoppingCart ( \n  ShoppingCartId INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,\n  UserId INT NOT NULL INDEX ix_UserId NONCLUSTERED HASH WITH (BUCKET_COUNT=1000000), \n  CreatedDate DATETIME2 NOT NULL, \n  TotalPrice MONEY\n  ) WITH (MEMORY_OPTIMIZED=ON) \nGO\n\n -- create a non-durable table. Data will not be persisted, data loss if the server turns off unexpectedly\nCREATE TABLE dbo.UserSession ( \n  SessionId INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT=400000), \n  UserId int NOT NULL, \n  CreatedDate DATETIME2 NOT NULL,\n  ShoppingCartId INT,\n  INDEX ix_UserId NONCLUSTERED HASH (UserId) WITH (BUCKET_COUNT=400000) \n  ) WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY) \nGO\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/27835', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2077/']