无法将过程存储到动态临时表中

时间:2016-01-21 12:04:32

标签: sql sql-server tsql stored-procedures

我有一个返回列的存储过程。出于功能原因,此存储过程主要由其他查询使用

所以我的存储过程:

IF OBJECT_ID ( 'dbo.ProcDim', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.ProcDim;
GO
CREATE PROCEDURE dbo.ProcDim
                            @Dim1 nvarchar(50), 
                            @Dim2 nvarchar(50) 
AS 
    SET NOCOUNT ON;
    IF OBJECT_ID('tempdb..#TMP1') IS NOT NULL
    DROP TABLE #TMP1

    SELECT  
    INTO    #TMP1           
    FROM  DBase.dbo.Table1  AS Parameter
    WHERE Parameter.Dim1    = @Dim1 
    AND   Parameter.Dim2    = @Dim2;
GO

EXECUTE dbo.ProcDim N'value1', N'value2';
SELECT * from #TMP1

所以当我在没有#TMP1的情况下执行我的程序工作正常但我想将结果插入临时表

5 个答案:

答案 0 :(得分:6)

您不能以这种方式使用临时表。

通过以下代码:SELECT INTO #TMP1您无需创建临时表,并且可以在存储过程的范围内访问 - 但不在此范围之外。

如果您需要在存储过程之外访问此临时表,则必须从存储过程中删除INTO #TMP1并在外部明确创建它:

create table #tmp1 (columns_definitions_here)

insert into #tmp1
exec  dbo.ProcDim N'value1', N'value2';

select * from #TMP1

请注意,在这种情况下,您必须显式创建临时表,提供所有列名及其数据类型。

或者,您可以将存储过程更改为用户定义的表函数,在这种情况下,您将能够隐式创建和填充临时表:

create function dbo.FuncDim
(
    @Dim1 nvarchar(50), 
    @Dim2 nvarchar(50)
)
returns @result TABLE (columns_definition_here) 
as
begin
    ... your code
   return
end

select  *
into  #TMP1
from dbo.FuncDim(@Dim1, @Dim2)

答案 1 :(得分:2)

临时表的范围(在本例中)是创建它们的存储过程。也就是说,当您的存储过程完成时,临时表将被删除。

如果你需要临时表的内容,在过程结束之前从中选择 - IOW,select * from #TMP1应该是过程的输出,而不是执行单独的语句在它之外。

答案 2 :(得分:1)

虽然@AndyKorneyev足够好,但其中有一些警告。例如,您必须保持过程返回的表和数据集的结构同步,同时insert into exec调用也不能嵌套。

因此,据我所知 - 在程序之间共享数据方面没有灵丹妙药,所以你必须考虑最合适的解决方案。

只是提供有关主题的更多信息 - 这里有关于在存储过程之间共享数据的不错article by Sommarskog

例如,我有时也会使用“共享表格”。解决方案(警告它可能导致重新编译):

create procedure dbo.p_test
as
begin
    set nocount on

    insert into #temp_shared (col1, col2)
    select col1, col2 from <...>
end
go

-- creating table so it'll be used inside temp
create table #temp ...

exec dbo.p_test

-- now you have data in your table
select * from #temp

答案 3 :(得分:0)

- #TMP1是一个本地临时表,Scope仅限于其查询层。

如果要在其查询层外访问它,请将全局临时表用作## TMP1

IF OBJECT_ID ( 'dbo.ProcDim', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.ProcDim;
GO
CREATE PROCEDURE dbo.ProcDim
                            @Dim1 nvarchar(50), 
                            @Dim2 nvarchar(50) 
AS 
    SET NOCOUNT ON;
    IF OBJECT_ID('tempdb..##TMP1') IS NOT NULL
    DROP TABLE ##TMP1

    SELECT  
    INTO    ##TMP1           
    FROM  DBase.dbo.Table1  AS Parameter
    WHERE Parameter.Dim1    = @Dim1 
    AND   Parameter.Dim2    = @Dim2;
GO

EXECUTE dbo.ProcDim N'value1', N'value2';
SELECT * from ##TMP1

答案 4 :(得分:0)

临时表的范围限定为当前连接。这就是为什么你无法得到结果的原因。

如果要查询临时表,请在程序本身中查询。

IF OBJECT_ID ( 'dbo.ProcDim', 'P' ) IS NOT NULL 
DROP PROCEDURE dbo.ProcDim;
GO
CREATE PROCEDURE dbo.ProcDim
                        @Dim1 nvarchar(50), 
                        @Dim2 nvarchar(50) 
AS 
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#TMP1') IS NOT NULL
DROP TABLE #TMP1

SELECT  *
INTO    #TMP1           
FROM  DBase.dbo.Table1  AS Parameter
WHERE Parameter.Dim1    = @Dim1 
AND   Parameter.Dim2    = @Dim2;

---Here write query to fetch the data from temp table.
SELECT * FROM  #TMP1 

GO

现在尝试执行语句。

  EXECUTE dbo.ProcDim N'value1', N'value2';

我不喜欢以这种方式使用存储过程。根据您的要求,您可以选择功能。