tsql returning a table from a function or store procedure

前端 未结 4 2100
慢半拍i
慢半拍i 2020-11-27 14:15

This is more of a syntax question I\'m trying to write a store procedure or function that I can embed into a query such as:

select * from MyBigProcOrFunction         


        
4条回答
  •  悲哀的现实
    2020-11-27 14:40

    You need a special type of function known as a table valued function. Below is a somewhat long-winded example that builds a date dimension for a data warehouse. Note the returns clause that defines a table structure. You can insert anything into the table variable (@DateHierarchy in this case) that you want, including building a temporary table and copying the contents into it.

    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
    

提交回复
热议问题