简体   繁体   中英

Session-global temporary tables in SQL Server

In SQL Server, temporary tables with a name like #temp has a local scope. If you create them in your session, everything in your session can see them, but not outside your session. If you create such a table within a stored procedure, the scope is local to that procedure. So when the proc exits, the table vanishes.

The only alternative I am aware of, is to use tables with a name like ##temp. These are temporary, but are visible server-wide. So if I create the table in my session, Bob in the office next door will also see them.

What I am looking for is somewhere in the middle, so I can create the table within a stored procedure and have that table be available to my session even after the stored proc exits. The nearest I have been able to find, is to create the table with only one field on it and then alter it within the stored proc. That seems like a bit of a kludge, though.

Another kludge that may work for you - it depends on how many temp tables are involved here.

Create your temp tables as real tables, with an extra column called SPID, defaulting to @@SPID .

Then create a view that accesses these tables, but filters based on the @@SPID value. All operations that take place through this view should look as if they're isolated on a per-session basis. Eg:

create table temp_Boris (
    SPID int default @@SPID,
    ColA int,
    ColB varchar(10)
)
go
create view vBoris
as
    select ColA,ColB from temp_Boris where SPID = @@SPID
go

Then, on one connection, run the following:

insert into vBoris(ColA,ColB)
select 10,'abc' union all
select 20,'def'
go
select * from vBoris

And on another connection, run the following:

insert into vBoris(ColA,ColB)
select 10,'abc' union all
select 20,'def'
go
select * from vBoris
select * from temp_Boris
go
delete from vBoris
go
select * from vBoris
select * from temp_Boris

And you'll see that each connection is able to treat "vBoris" somewhat like a temp table - of course, you might need to add additional routines around this (and possibly more columns) to clear the table of old/stale results.

Okay, I'll admit, it feels ugly too.

You'd cache the results in your client code if the data is not meant to be persisted or shared. If it is meant to be persisted or shared, then you'd use a normal table.

In other words, from a result and calling perspective a stored procedure call should be stateless. If the data is private to the session then it should be in the client. This avoids using server resourcey and means you don't need to keep the connection open between calls

Saying that, you can persist small amounts (128 bytes) of data on an open connection for that connection only using CONTEXT_INFO .

启动会话,然后执行存储的proc,然后在执行存储的proc之后对表做其他事情,是否可以不创建表?

i dont think theres an out of the box solution in SQL server for what you require. i think the only way is to mange it yourself. is it acceptable to you create a normal table with some suffix instead of using the blobal table (where you have contorl over its full name)? since the global tables go to the tempdb, this will also help you isolate data to your database as a side effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM