[英]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.