SQL Server T-SQL – How to Pass Multiple Rows to a Function

sql servert-sql

I was looking into XLeratorDB's XIRR function and I see they have an example like this:

SELECT wct.XIRR(cf_amt, cf_date, NULL) as IRR
FROM (VALUES
            ('01/01/2010',8039),
            ('01/01/2010',-8039),
            ('02/01/2010',9333),
            ('02/01/2010',-9333),
            ('03/01/2010',9783),
            ('03/01/2010',-9783),
            ('04/01/2010',8373),
            ('04/01/2010',-8373),
            ('05/01/2010',7493),
            ('05/01/2010',-7493),
            ('06/01/2010',9738),
            ('06/01/2010',-9738),
            ('07/01/2010',6382),
            ('07/01/2010',-6382),
            ('08/01/2010',8627),
            ('08/01/2010',-8627),
            ('09/01/2010',6871),
            ('09/01/2010',-6871),
            ('10/01/2010',9091),
            ('10/01/2010',-9091),
            ('11/01/2010',9153),
            ('11/01/2010',-9153),
            ('12/01/2010',7253),
            ('12/01/2010',-7253),
            ('01/01/2011',8197)
            ) n(cf_date, cf_amt)
This produces the following result.
                   IRR
----------------------
                  NULL

(1 row(s) affected)

I didn't know that it was possible to send a table to a function in this way. I'm wondering how that is done in SQL Server.

Note: I'm not asking about how to do an XIRR calculation, rather about the syntax that can let you pass the result of a select like that to a function without first inserting it into a table variable and passing that variable.

Best Answer

That particular function is a SQLCLR User-Defined Aggregrate (UDA). It is being called multiple times, once per each output row (pre-HAVING clause, if one is present). A UDA maintains state between executions so in some respects it does access all rows within a particular group, but it only gets one row at a time, and needs to store info for future calls.

Otherwise, SQLCLR functions cannot accept multiple rows. T-SQL functions, however, do have the ability to accept multiple rows via a Table-Valued Parameter (TVP).