简体   繁体   English

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

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

I have a stored procedure that returns columns . 我有一个返回列的存储过程。 This stored procedure is mainly being used by other query for functional reasons 出于功能原因,该存储过程主要由其他查询使用

So my stored procedure: 所以我的存储过程:

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

So when i excute my procedure without #TMP1 work fine but i want to insert the result into temp table 所以当我执行我的程序没有#TMP1工作正常,但我想将结果插入临时表

You can't use temporary table in such a manner. 您不能以这种方式使用临时表。

By this code: SELECT INTO #TMP1 you're implicity creating temporary table, and it is accessible in the scope of your stored procedure - but not outside of this scope. 通过此代码: SELECT INTO #TMP1您无意中创建临时表,并且可以在存储过程的范围内访问它 - 但不在此范围之外。

If you need this temporary table to be accessible outside of stored procedure, you have to remove INTO #TMP1 from stored procedure and explicitly create it outside: 如果您需要在存储过程之外访问此临时表,则必须从存储过程中删除INTO #TMP1并在外部明确创建它:

create table #tmp1 (columns_definitions_here)

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

select * from #TMP1

Notice you have to explicitly create temporary table in this case, supplying all column names and their data types. 请注意,在这种情况下,您必须显式创建临时表,提供所有列名及其数据类型。

Alternatively you can change your stored procedure to be user-defined table function, and in this case you will be able to implicitly create and populate your temporary table: 或者,您可以将存储过程更改为用户定义的表函数,在这种情况下,您将能够隐式创建和填充临时表:

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)

Temp tables are scoped (in this case) to the stored procedure in which they're created. 临时表的范围(在本例中)是创建它们的存储过程。 That is, when your stored procedure completes, the temp table is dropped. 也就是说,当您的存储过程完成时,将删除临时表。

If you need the contents of the temp table, select from it before the end of the procedure - IOW, select * from #TMP1 should be the output of the procedure, not a separate statement executed outside of it. 如果您需要临时表的内容,请在过程结束从中选择 - IOW, select * from #TMP1应该是过程的输出,而不是在它之外执行的单独语句。

While @AndyKorneyev is good enough, there're some caveats in it. 虽然@AndyKorneyev足够好,但它有一些警告。 For example, you have to keep structure of the table and dataset returned by procedure synchronized, also insert into exec calls cannot be nested. 例如,您必须保持表的结构和过程返回的数据集同步,也insert into exec调用不能嵌套。

So, as far as I know - there're no silver bullet in terms of sharing data between procedures, so you have to think about best suitable solution for you case. 所以,据我所知 - 在程序之间共享数据方面没有灵丹妙药,所以你必须考虑最合适的解决方案。

Just to give your more information about topic - here's nice article by Sommarskog concerning sharing data between stored procedures. 只是为了提供有关主题的更多信息 - 这是Sommarskog关于在存储过程之间共享数据的好文章

For example, I also sometimes use 'shared table' solution (be warned it could lead to recompilations): 例如,我有时也使用'共享表'解决方案(警告它可能会导致重新编译):

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 is a local temp table its, Scope is limited to its query layer only. - #TMP1是一个本地临时表,Scope仅限于其查询层。

if you want to access it out side its query layer use global temp table as ##TMP1 如果要在其查询层外访问它,请将全局临时表用作## 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

Temp tables are scoped to current connection. 临时表的范围限定为当前连接。 So that is the reason why you are not able to get the result. 这就是为什么你无法得到结果的原因。

If you want query the temp table, then query in procedure itself. 如果要查询临时表,则在过程本身中查询。

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

Now give a try to execute statement. 现在尝试执行语句。

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

I don't prefer Stored procedures to use in this way. 我不喜欢以这种方式使用存储过程。 For your requirement you can go for Functions instead. 根据您的要求,您可以选择功能。

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

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