tsql从函数或存储过程返回一个表

这是更多的一个语法问题,我试图写一个存储过程或函数,我可以embedded到一个查询,如:

select * from MyBigProcOrFunction 

我试图定义一个表格函数,但我不明白如何做,因为我build立tmp表格来处理数据,然后才能最终返回到结束表。 我的代码是:

 create function FnGetCompanyIdWithCategories() returns table as return ( select * into a #tempTable from stuff ' etc ' select companyid,Company_MarketSector from #tempTables 'the returning table data ) 

如果我定义了一个函数,我如何将它作为表格返回?

您不能从SQL函数内访问临时表。 你将需要使用表variables,所以本质上:

 ALTER FUNCTION FnGetCompanyIdWithCategories() RETURNS @rtnTable TABLE ( -- columns returned by the function ID UNIQUEIDENTIFIER NOT NULL, Name nvarchar(255) NOT NULL ) AS BEGIN DECLARE @TempTable table (id uniqueidentifier, name nvarchar(255)....) insert into @myTable select from your stuff --This select returns data insert into @rtnTable SELECT ID, name FROM @mytable return END 

编辑

根据对这个问题的意见,这是我的build议。 您希望在另一个查询中join过程或表值函数的结果。 我会告诉你如何做到这一点,然后你select一个你喜欢的。 我将要使用来自我的模式之一的示例代码,但是你应该能够适应它。 两个都是先存储过程的可行解决scheme。

 declare @table as table (id int, name nvarchar(50),templateid int,account nvarchar(50)) insert into @table execute industry_getall select * from @table inner join [user] on account=[user].loginname 

在这种情况下,您必须声明临时表或表variables来存储过程的结果。 现在让我们看看如果你使用UDF,你将如何做到这一点

 select * from fn_Industry_GetAll() inner join [user] on account=[user].loginname 

正如你所看到的,UDF更简洁易读,并且由于不使用辅助临时表(性能是我完全猜测的),因此可以更好地执行一些更好的操作。

如果你要在很多其他地方重复使用你的函数/过程,我认为UDF是你最好的select。 唯一的问题是你将不得不停止使用#Temp表并使用表variables。 除非你为临时表build立索引,否则应该没有问题,因为表variables保存在内存中,所以你将会使用tempDb。

使用这个作为模板

 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE FUNCTION <Table_Function_Name, sysname, FunctionName> ( -- Add the parameters for the function here <@param1, sysname, @p1> <data_type_for_param1, , int>, <@param2, sysname, @p2> <data_type_for_param2, , char> ) RETURNS <@Table_Variable_Name, sysname, @Table_Var> TABLE ( -- Add the column definitions for the TABLE variable here <Column_1, sysname, c1> <Data_Type_For_Column1, , int>, <Column_2, sysname, c2> <Data_Type_For_Column2, , int> ) AS BEGIN -- Fill the table variable with the rows for your result set RETURN END GO 

这将定义你的function。 那么你可以像其他表一样使用它:

 Select * from MyFunction(Param1, Param2, etc.) 

您需要一个称为表值函数的特殊types的函数。 下面是一个有点冗长的例子,为数据仓库build立一个date维度。 请注意定义表结构的returns子句。 你可以插入任何东西到你想要的表variables( @DateHierarchy )中,包括构build一个临时表并将其中的内容复制到其中。

 if object_id ('ods.uf_DateHierarchy') is not null drop function ods.uf_DateHierarchy go create function ods.uf_DateHierarchy ( @DateFrom datetime ,@DateTo datetime ) returns @DateHierarchy table ( DateKey datetime ,DisplayDate varchar (20) ,SemanticDate datetime ,MonthKey int ,DisplayMonth varchar (10) ,FirstDayOfMonth datetime ,QuarterKey int ,DisplayQuarter varchar (10) ,FirstDayOfQuarter datetime ,YearKey int ,DisplayYear varchar (10) ,FirstDayOfYear datetime ) as begin declare @year int ,@quarter int ,@month int ,@day int ,@m1ofqtr int ,@DisplayDate varchar (20) ,@DisplayQuarter varchar (10) ,@DisplayMonth varchar (10) ,@DisplayYear varchar (10) ,@today datetime ,@MonthKey int ,@QuarterKey int ,@YearKey int ,@SemanticDate datetime ,@FirstOfMonth datetime ,@FirstOfQuarter datetime ,@FirstOfYear datetime ,@MStr varchar (2) ,@QStr varchar (2) ,@Ystr varchar (4) ,@DStr varchar (2) ,@DateStr varchar (10) -- === Previous =================================================== -- Special placeholder date of 1/1/1800 used to denote 'previous' -- so that naive date calculations sort and compare in a sensible -- order. -- insert @DateHierarchy ( DateKey ,DisplayDate ,SemanticDate ,MonthKey ,DisplayMonth ,FirstDayOfMonth ,QuarterKey ,DisplayQuarter ,FirstDayOfQuarter ,YearKey ,DisplayYear ,FirstDayOfYear ) values ( '1800-01-01' ,'Previous' ,'1800-01-01' ,180001 ,'Prev' ,'1800-01-01' ,18001 ,'Prev' ,'1800-01-01' ,1800 ,'Prev' ,'1800-01-01' ) -- === Calendar Dates ============================================= -- These are generated from the date range specified in the input -- parameters. -- set @today = @Datefrom while @today <= @DateTo begin set @year = datepart (yyyy, @today) set @month = datepart (mm, @today) set @day = datepart (dd, @today) set @quarter = case when @month in (1,2,3) then 1 when @month in (4,5,6) then 2 when @month in (7,8,9) then 3 when @month in (10,11,12) then 4 end set @m1ofqtr = @quarter * 3 - 2 set @DisplayDate = left (convert (varchar, @today, 113), 11) set @SemanticDate = @today set @MonthKey = @year * 100 + @month set @DisplayMonth = substring (convert (varchar, @today, 113), 4, 8) set @Mstr = right ('0' + convert (varchar, @month), 2) set @Dstr = right ('0' + convert (varchar, @day), 2) set @Ystr = convert (varchar, @year) set @DateStr = @Ystr + '-' + @Mstr + '-01' set @FirstOfMonth = convert (datetime, @DateStr, 120) set @QuarterKey = @year * 10 + @quarter set @DisplayQuarter = 'Q' + convert (varchar, @quarter) + ' ' + convert (varchar, @year) set @QStr = right ('0' + convert (varchar, @m1ofqtr), 2) set @DateStr = @Ystr + '-' + @Qstr + '-01' set @FirstOfQuarter = convert (datetime, @DateStr, 120) set @YearKey = @year set @DisplayYear = convert (varchar, @year) set @DateStr = @Ystr + '-01-01' set @FirstOfYear = convert (datetime, @DateStr) insert @DateHierarchy ( DateKey ,DisplayDate ,SemanticDate ,MonthKey ,DisplayMonth ,FirstDayOfMonth ,QuarterKey ,DisplayQuarter ,FirstDayOfQuarter ,YearKey ,DisplayYear ,FirstDayOfYear ) values ( @today ,@DisplayDate ,@SemanticDate ,@Monthkey ,@DisplayMonth ,@FirstOfMonth ,@QuarterKey ,@DisplayQuarter ,@FirstOfQuarter ,@YearKey ,@DisplayYear ,@FirstOfYear ) set @today = dateadd (dd, 1, @today) end -- === Specials =================================================== -- 'Ongoing', 'Error' and 'Not Recorded' set two years apart to -- avoid accidental collisions on 'Next Year' calculations. -- insert @DateHierarchy ( DateKey ,DisplayDate ,SemanticDate ,MonthKey ,DisplayMonth ,FirstDayOfMonth ,QuarterKey ,DisplayQuarter ,FirstDayOfQuarter ,YearKey ,DisplayYear ,FirstDayOfYear ) values ( '9000-01-01' ,'Ongoing' ,'9000-01-01' ,900001 ,'Ong.' ,'9000-01-01' ,90001 ,'Ong.' ,'9000-01-01' ,9000 ,'Ong.' ,'9000-01-01' ) insert @DateHierarchy ( DateKey ,DisplayDate ,SemanticDate ,MonthKey ,DisplayMonth ,FirstDayOfMonth ,QuarterKey ,DisplayQuarter ,FirstDayOfQuarter ,YearKey ,DisplayYear ,FirstDayOfYear ) values ( '9100-01-01' ,'Error' ,null ,910001 ,'Error' ,null ,91001 ,'Error' ,null ,9100 ,'Err' ,null ) insert @DateHierarchy ( DateKey ,DisplayDate ,SemanticDate ,MonthKey ,DisplayMonth ,FirstDayOfMonth ,QuarterKey ,DisplayQuarter ,FirstDayOfQuarter ,YearKey ,DisplayYear ,FirstDayOfYear ) values ( '9200-01-01' ,'Not Recorded' ,null ,920001 ,'N/R' ,null ,92001 ,'N/R' ,null ,9200 ,'N/R' ,null ) return end go 

据我所知,你不需要(不应该使用)一个函数。 存储过程将从包含返回表格数据的任何SELECT语句中返回表格数据。

存储的proc不使用RETURN语句。

CREATE PROCEDURE名称AS

SELECT stuff INTO#temptbl1

…….

select列从#temptbln