我有2个带有动态sql的存储过程(ms sql 2005)。首先创建临时表(## Table)并填充数据。第二个过程从第一个过程创建的临时表中选择数据。
第一个sp:
set @cmd = 'create table ' + @tableName +
'(ORDERS_DT_ID int' +
...
',WAREHOUSE_RESULT numeric(15, 3)) ' +
' insert into ' + @tableName + ' ( ORDERS_DT_ID, ... WAREHOUSE_RESULT )' +
' select ro.ORDERS_DT_ID, ... ro.WAREHOUSE_RESULT ' +
' from WH_REMAINS_BY_ORDER_FN ( ' + cast(@orderId as varchar(10)) + ' ) as ro '
exec (@cmd)
第二个sp(例如):
set @cmd = 'select r.ORDERS_DT_ID, ... r.WAREHOUSE_RESULT' +
' from ' + @tableName + ' as r'
exec (@cmd)
其中@tableName - sp的输入参数(例如,'## Table')
我使用asp.net mvc应用程序中的那些程序。我调用第一个程序,从MSSMS检查临时表(表存在)然后应用程序在断点处停止(在第二个sp之前),接下来我调用第二个程序并且表不存在(但是在第一个和第二个程序之间存在调用表)。 / p>
var result = dataContext.firstSP(table, orderId).FirstOrDefault(); // create temp table and fill data (+ return status)
var data = dataContext.secondSP( table, orderId ).AsQueryable(); // before execute we have temp table (check from MSSMS) and we have error after execute that code.
如果我们检查第二个程序中的临时表,我们可以看到该表不存在:
if object_id ( N'tempdb.dbo.' + ltrim(@tableName) ) is null
begin
exec dbo.firstSP @tableName, @orderId
end
当我们运行第二个sp?
时,为什么第一个sp的临时表会丢失答案 0 :(得分:2)
创建会话结束后,全局临时表将被删除,并且不会从另一个会话中主动查询。
如果您想控制生命周期,请创建一个永久表(可能在tempdb
)
答案 1 :(得分:1)
当没有打开的连接查询时,会自动删除全局临时表。这是最可能的原因。就个人而言,我不会这样做,因为无论如何两个单独的DB调用。
我的建议是将第一个SP转换为表值函数,然后第二个SP可以简单地查询TVF。这样就不需要执行DDL,进行两次单独的数据库调用,而且通常会更容易。
如果你真的想要临时表,那就是这样。如果您希望此生成的表保留的时间超过一次,请不要使用临时表。