views:

2104

answers:

8

Let's say I have to implement a piece of T-SQL code that must return a table as result. I can implement a table-valued function or else a stored procedure that returns a set of rows. What should I use?

In short, what I want to know is:

Which are the main differences between functions and stored procedures? What considerations do I have to take into account for using one or the other?

+11  A: 

If you're likely to want to combine the result of this piece of code with other tables, then obviously a table-valued function will allow you to compose the results in a single SELECT statement.

Generally, there's a hierarchy (View < TV Function < Stored Proc). You can do more in each one, but the ability to compose the outputs, and for the optimizer to get really involved decreases as the functionality increases.

So use whichever one minimally allows you to express your desired result.

Damien_The_Unbeliever
+2  A: 

I personally use table valued functions when all I am returning is a single table with no affects. Basically I treat them like parameterized views.

If I need multiple recordsets returned or if there will be values updated in tables, I use a stored procedure.

My 2 cents

wcm
+1  A: 

If you have a function you could use it as a part of your SQL statement, for example

SELECT function_name(field1) FROM table

It does not work this way for the stored procedures.

Ilya Kochetov
I think he was talking about functions that return table values.
wcm
Well, I'm talking in general. But for my specific case I'm now currently between a stored procedure or a table-valued function.
Auron
+16  A: 

Functions must be deterministic, and cannot be used to make changes to the database, whereas stored procedures allow you to do inserts and updates, etc.

You should limit your use of functions, since they pose a huge scalability problem for big, complex queries. They become sort of a "black box" for the query optimizer, and you'll see enormous differences in performance between using functions and simply inserting the code into a query.

But they are definitely useful for table-valued returns in very specific cases.

If you need to parse a comma-delimited list, to simulate passing an array to a procedure, a function can turn the list into a table for you. This is common practice with Sql Server 2005, since we can't pass in tables to stored procedures yet (we can with 2008).

Eric Z Beard
But you CAN send XML to a stored procedure: http://stackoverflow.com/questions/144550/sql-server-dynamic-where-clause
roosteronacid
+1  A: 

It depends :) If you want to use the table-valued result in another procedure, you're better of using a TableValued Function. If the results is for a client, the stored proc is usualy the better way to go.

edosoft
+4  A: 

From the docs:

If a stored procedure meets the following criteria, it is a good candidate for being rewritten as a table-valued function:

  • The logic is expressible in a single SELECT statement but is a stored procedure, rather than a view, only because of the need for parameters.

  • The stored procedure does not perform update operations, except to table variables.

  • There is no need for dynamic EXECUTE statements.

  • The stored procedure returns one result set.

  • The primary purpose of the stored procedure is to build intermediate results that are to be loaded into a temporary table, which is then queried in a SELECT statement.

Lette
+1  A: 

I would perfromance test both. It is likely the sp approach or a derived table would be significantly faster than a function and if so that approach should be used. In general I avoid functions becasue they can be performance hogs.

HLGEM
+1  A: 

As mentioned above, functions are more readable/composable/self documenting, but are less performant in general, and can be seriously less performant if you get carried away with them in joins such as


SELECT *
FROM
           dbo.tvfVeryLargeResultset1(@myVar1) tvf1
INNER JOIN dbo.tvfVeryLargeResultset1(@myVar2) tvf2
    ON             (tvf1.JoinId = tvf2.JoinId)

Often, you just have to accept the redundancy of code
that a tvf could eliminate (at a unacceptable performance cost.)

One other point I haven't yet seen mentioned is that you can't use database state-changing temp tables inside of a multi-statement tvf. The most functionally equivalent mechanism to a temp table is the non-state changing, in memory table variable, and for large datasets, a temp table will likely be more performant than a table variable. (Other alternatives include dynamic tables & common table valued expressions, but at some level of complexity, these cease to be a good option IMO.)

6eorge Jetson
You made a good point! Thanks!
Auron