SQL Server 中的会话全局临时表

发布于 2024-10-20 18:48:54 字数 327 浏览 2 评论 0原文

在 SQL Server 中,名称类似于 #temp 的临时表具有本地作用域。如果您在会话中创建它们,则会话中的所有内容都可以看到它们,但会话外则看不到它们。如果您在存储过程中创建这样的表,则作用域是该过程的本地范围。所以当进程退出时,表就消失了。

我知道的唯一选择是使用名称类似于 ##temp 的表。这些是临时的,但在服务器范围内可见。因此,如果我在会话中创建表,隔壁办公室的鲍勃也会看到它们。

我正在寻找的是中间的某个地方,因此我可以在存储过程中创建表,并且即使在存储过程退出后也可以让该表可供我的会话使用。我能找到的最接近的方法是创建仅包含一个字段的表,然后在存储过程中更改它。不过,这似乎有点拼凑。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

呆° 2024-10-27 18:48:54

另一个可能对您有用的杂凑 - 这取决于这里涉及多少个临时表。

将临时表创建为真实表,并添加一个名为 SPID 的额外列,默认为 @@SPID

然后创建一个访问这些表的视图,但根据 @@SPID 值进行过滤。通过此视图进行的所有操作都应该看起来像是在每个会话的基础上隔离的。例如:

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

然后,在一个连接上,运行以下命令:

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

在另一个连接上,运行以下命令:

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

您将看到每个连接都能够将“vBoris”视为临时表 - 当然,您可能需要添加围绕此的附加例程(可能还有更多列)来清除旧/陈旧结果表。

好吧,我承认,感觉也很丑。

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. E.g.:

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.

旧夏天 2024-10-27 18:48:54

如果数据不打算保留或共享,您可以将结果缓存在客户端代码中。如果要持久化或共享它,那么您将使用普通表。

换句话说,从结果和调用的角度来看,存储过程调用应该是无状态的。如果数据对于会话来说是私有的,那么它应该位于客户端中。这可以避免使用服务器资源,并且意味着您不需要在调用之间保持连接打开

也就是说,您可以使用 仅在该连接上在打开的连接上保留少量数据(128 字节) a href="http://msdn.microsoft.com/en-us/library/ms187768.aspx" rel="nofollow">CONTEXT_INFO。

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.

东走西顾 2024-10-27 18:48:54

您是否可以在启动会话时创建表,然后执行存储过程,然后在存储过程执行后对表执行任何其他操作?

Could you not create the table when you start the session, then execute the stored proc, then do whatever else you want to do to the table after the stored proc executes?

半仙 2024-10-27 18:48:54

我认为 SQL Server 中没有现成的解决方案可以满足您的需求。我认为唯一的办法就是自己管理。您创建一个带有某些后缀的普通表而不是使用 blobal 表(您可以控制其全名)是否可以接受?
由于全局表转到 tempdb,因此这也将帮助您将数据隔离到数据库,这是一个副作用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文