我有一个返回列的存储过程。出于功能原因,此存储过程主要由其他查询使用
所以我的存储过程:
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的情况下执行我的程序工作正常但我想将结果插入临时表
答案 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';
我不喜欢以这种方式使用存储过程。根据您的要求,您可以选择功能。