簡體   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