SQL Server临时表和连接池
我有一个针对SQL Server运行的多用户ASP.NET应用,希望StoredProcA创建一个#temptable临时表而不是一个表变量来插入一些数据,然后跳转到StoredProcB,StoredProcC和StoredProcD来处理#temptable中的数据根据业务规则。
与SQL对话时,Web应用程序使用连接池。我每次致电StoredProcA都会获得一个新的#temptable临时区域吗?还是连接池在用户之间共享#temptable?
解决方案
要在用户之间共享临时表,请在名称## like_this之前使用两个散列。
在这种情况下,请确保采取措施避免与程序的多个实例冲突。
#table将由所有用户共享。我认为这不是意图。
单个临时表对于调用堆栈下的所有存储过程都是可见的,但在该范围之外不可见。如果可以让Proc A呼叫B,C和D,则应该没问题。
编辑:我现在应该处理的报告程序非常类似。 :)我在应用程序调用的根proc中创建一个临时表(#results),然后在一系列子过程中进行一些复杂的数据处理,以达到1)抽象重复的代码,以及2)阻止根过程运行的目的。到500条以上的线。
#temptable不能在声明它的过程结束后继续存在,因此其他用户将永远看不到它。
编辑:呵呵,事实证明,自SQL Server 7.0起,临时表的"嵌套可见性"已经起作用,但是我从未更新任何代码来利用这一点。我想我正在约会自己-很多人可能无法想象在6.0和6.5天之内是SQL Server的地狱...
临时表是在幕后使用名称修饰来创建的,因此不同的存储过程调用之间不应存在冲突。
如果我们需要在后续的存储过程调用中处理相同的临时数据,则最好只使用一个真实表并使用某种唯一标识符以确保我们仅在处理相关数据。如果数据仅是暂时有价值的,请在完成后手动将其删除。
重用连接时,连接池(使用任何现代版本的SQL Server)将调用sp_reset_connection
。除其他外,此存储的proc会删除该连接拥有的任何临时表。
从MS文档:
http://msdn.microsoft.com/zh-CN/library/ms177399(SQL.90).aspx
临时表
临时表类似于永久表,不同之处在于临时表存储在tempdb中,并且在不再使用时会自动删除。
有两种类型的临时表:本地和全局。它们的名称,可见性和可用性彼此不同。本地临时表的名称的第一个字符带有一个数字符号(#)。它们仅对用户的当前连接可见,并且当用户与SQL Server实例断开连接时,它们将被删除。
全局临时表的名称的第一个字符有两个数字符号(##);它们在创建后对任何用户都是可见的,并且当所有引用该表的用户与SQL Server实例断开连接时,它们将被删除。
例如,如果我们创建表employees,则该表可以被数据库中具有安全权限的任何人使用,直到该表被删除为止。如果数据库会话创建本地临时表#employees,则只有该会话可以使用该表,并且在会话断开连接时将其删除。如果创建全局临时表## employees,则数据库中的任何用户都可以使用该表。如果创建该表后没有其他用户使用该表,则在断开连接时将删除该表。如果在创建表后另一个用户使用该表,则在断开连接并且所有其他会话不再有效使用该表之后,SQL Server会将其删除。
另外,来自Curt的人纠正了我的做法的错误,以防万一我们错过评论中的引用:
http://msdn.microsoft.com/en-us/library/ms191132.aspx
- 如果在存储过程内创建本地临时表,则该临时表仅出于存储过程的目的而存在。当我们退出存储过程时,它消失了。
- 如果我们执行一个存储过程来调用另一个存储过程,则被调用的存储过程可以访问由第一个存储过程创建的所有对象,包括临时表。