我有一个针对SQL Server运行的多用户ASP.NET应用程序,希望StoredProcA创建#temptable临时表(不是表变量)来插入一些数据,然后分别调用StoredProcB、StoredProcC和StoredProcD,根据业务规则操作#temptable中的数据。
当与SQL通信时,Web应用程序使用连接池。每次调用StoredProcA都会得到一个新的#temptable临时区域吗?还是连接池会在用户之间共享#temptable?
我有一个针对SQL Server运行的多用户ASP.NET应用程序,希望StoredProcA创建#temptable临时表(不是表变量)来插入一些数据,然后分别调用StoredProcB、StoredProcC和StoredProcD,根据业务规则操作#temptable中的数据。
当与SQL通信时,Web应用程序使用连接池。每次调用StoredProcA都会得到一个新的#temptable临时区域吗?还是连接池会在用户之间共享#temptable?
在任何现代版本的SQL Server中,连接池将在重用连接时调用 sp_reset_connection
。这个存储过程会在其他操作之外,删除该连接所拥有的任何临时表。
所有用户都将共享一张##表格。我认为这不是你的意图。
一个单独的#临时表格对于调用堆栈中的所有存储过程可见,但在该范围之外不可见。如果您可以让Proc A调用B、C和D,那么应该没问题。
编辑:我现在应该在处理类似于此的报告程序。 :)我在由应用程序调用的根过程中创建了一个临时表格(#results),然后在一系列子过程中进行了一些复杂的数据操作,以1)抽象重复代码,2)避免根过程运行到500多行。
#temptable
声明的存储过程结束后就不再存在,因此其他用户将永远无法看到它。
编辑:嘿,事实证明,自SQL Server 7.0以来,临时表的“嵌套可见性”就已经可以使用了,但我从未更新过任何代码来利用这一点。我想我正在让自己过时了——很多人可能无法想象曾经是在SQL Server 6.0和6.5中翻遍天地的苦难日子...
根据MS文档:
http://msdn.microsoft.com/en-us/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
如果在存储过程内部创建本地临时表,则该临时表仅存在于存储过程的目的中;当您退出存储过程时,它会消失。
如果执行调用另一个存储过程的存储过程,则被调用的存储过程可以访问由第一个存储过程创建的所有对象,包括临时表。
要在用户之间共享临时表,请在名称前使用两个井号##like_this。
在这种情况下,确保采取措施避免程序的多个实例之间发生冲突。
临时表在幕后使用名称混淆创建,因此不应该存在不同存储过程调用之间的冲突。
如果您需要在后续存储过程调用中操作相同的临时数据,则最好使用真实表并使用某种唯一标识符来确保您只处理相关数据。如果数据仅有临时价值,请在完成后手动删除它。