繁体   English   中英

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

[英]Can't store procedure into dynamic temp table

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

所以我的存储过程:

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工作正常,但我想将结果插入临时表

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

通过此代码: 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)

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

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

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

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

只是为了提供有关主题的更多信息 - 这是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

- #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

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

如果要查询临时表,则在过程本身中查询。

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';

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM