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