Demo Performance Penalty Of User Defined Functions
Feb 5, 2007
SQL Server User defined functions can be a powerful tool, but they can also create a substantial performance penalty in a query where they are called a large number of times. Sometimes it is something that must be accepted to get the job done, but there is often an alternative of putting the code from the function “in-line� in a SQL query. That also has a penalty in development time, so judgment about which way to go is called for.
I did some testing on three different methods of converting combinations of integer values of Year, Month, Day, Hour, Minute, and Second to Datetime values and compared the runtime of each. In the first method, I did the conversion in-line in the query. In the second method, I used a UDF to do the conversion using the same algorithm as the in-line query. In the third method, I used a UDF that called two more UDFs to do the conversion.
To perform the test, I loaded a table with 3,999,969 randomly generated date/times, along with the matching year, month, day, hour, minute, and seconds, in the range of 1753-01-01 to 9999-12-31. I re-indexed the table with fill factor of 100 to make the physical size as small as possible.
For the actual test, I ran queries that converted the year, month, day, hour, minute, and second on each row to a datatime, and compared it to the datetime from that row. I ran the query using the in-line conversion, single UDF (DateTime1), and with the UDF (DateTime2) that called two more UDFs (Date and Time). I ran the tests several times, and saw only minor variations in run time. The single UDF took over 8 times as long to run as the in-line conversion. The test with the UDF that called other UDFs took over 36 times as long to run as the in-line conversion, and took over 4 times as long to run as the single UDF.
These results show that there can be a substantial performance penalty for using a UDF in place of in-line code, and that UDFs that call other UDFs can also have a substantial performance penalty compared to a UDF that does not call other UDFs.
Code to load table with test data. The functions used in the script to load the test data can be found on these links:
Random Datetime Function:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=69499
Number Table Function:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47685
create table T_DATE (
[DATE] datetime not null primary key clustered ,
[YEAR]smallint not null ,
[MONTH]tinyint not null ,
[DAY]tinyint not null ,
[HOUR]tinyint not null ,
[MINUTE]tinyint not null ,
[SECOND]tinyint not null
)
insert into T_DATE
select distinct top 100 percent
[DATE] = dateadd(ms,-datepart(ms,a.[DATE]),a.[DATE]),
[YEAR]= year(a.[DATE]),
[MONTH]= month(a.[DATE]),
[DAY]= day(a.[DATE]),
[HOUR]= datepart(hour,a.[DATE]),
[MINUTE]= datepart(minute,a.[DATE]),
[SECOND]= datepart(second,a.[DATE])
from
(
selecttop 100 percent
[DATE] =
[dbo].[F_RANDOM_DATETIME]( '17530101', '99991231',newid() )
from
f_table_number_range(1,4000000) aa
order by
1
) a
order by
a.[DATE]
dbcc dbreindex(T_DATE,'',100)
exec sp_spaceused 'T_DATE','true'
select count(*) from T_DATE
Code to create functions used in the test. These functions are based on functions that Jeff posted in his blog on this link, modified with some suggestions of mine:
http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx
create function DateTime1
(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int)
-- returns a dateTime value for the date and time specified.
returns datetime
as
begin
returndateadd(month,((@Year-1900)*12)+@Month-1,
dateadd(ss,(@Hour*3600)+(@Minute*60)+@Second,@Day-1))
end
go
create function Date(@Year int, @Month int, @Day int)
-- returns a datetime value for the specified year, month and day
returns datetime
as
begin
return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
end
go
create function Time(@Hour int, @Minute int, @Second int)
-- Returns a datetime value for the specified time at the "base" date (1/1/1900)
returns datetime
as
begin
return dateadd(ss,(@Hour*3600)+(@Minute*60)+@Second,0)
end
go
create function DateTime2
(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int)
-- returns a dateTime value for the date and time specified.
returns datetime
as
begin
return dbo.Date(@Year,@Month,@Day) + dbo.Time(@Hour, @Minute,@Second)
end
go
Test code:
set nocount on
go
select [T_DATE Rowcount] = count(*) from T_DATE
go
declare @count int
declare @st datetime
select @st = getdate()
select
@count = count(*)
from
T_DATE a
where
a.[DATE] <> 0+a.[DATE]
select [MS No Action] = datediff(ms,0,getdate()-@st)
go
declare @count int
declare @st datetime
select @st = getdate()
select
@count = count(*)
from
T_DATE a
where
a.[DATE] <>
dateadd(month,((a.YEAR-1900)*12)+a.MONTH-1,
dateadd(ss,(a.HOUR*3600)+(a.MINUTE*60)+a.SECOND,a.DAY-1))
select [MS No Function] = datediff(ms,0,getdate()-@st)
go
declare @count int
declare @st datetime
select @st = getdate()
select
@count = count(*)
from
T_DATE a
where
a.[DATE] <> dbo.DateTime1(a.YEAR,a.MONTH,a.DAY,a.HOUR,a.MINUTE,a.SECOND)
select [MS DateTime1] = datediff(ms,0,getdate()-@st)
go
declare @count int
declare @st datetime
select @st = getdate()
select
@count = count(*)
from
T_DATE a
where
a.[DATE] <> dbo.DateTime2(a.YEAR,a.MONTH,a.DAY,a.HOUR,a.MINUTE,a.SECOND)
select [MS DateTime2] = datediff(ms,0,getdate()-@st)
go
I have a search returning many 'car' records (regno, mileage, color, etc)
In a seperate table I have two columns: accessory and regno. This can have many rows for each regnumber.
Within the storedprocedure that returns the 'car' records I need to also return the relevant accessories for that car as one column.
I have written a function as such (with some help!):
ALTER Function getAccs(@regNo varChar(20)) RETURNS varChar AS BEGIN Declare @List varchar(1000) SELECT @List = COALESCE(@List + ', ', '') + accessory FROM frxrep2.dbo.usedaccessories WHERE regnumber = @regno return @List END
I was hoping that I could simply use this in the 'car' SELECT statement.
ie:
SELECT regNo, color, mileage, dob.getAccs(regno) as AccessoryList FROM tableBla etc
I'm not even sure if the function works - How can I test in SQL analyzer?
I know that we cannot have User Defined Functions in SQL 7.0, but is there a work around. I am trying to standardize the date according to the time zone using a function and use it as part of a select statement.
I cannot believe that is not possible in SQL 7.0, can somebody tell me what is the work around, I am running against time. I really appreciate any help on this one.
I am implementing an encrypted data system whereby captured data is encrypted using MS CAPICOM when written to DB and decrypted when displayed. It works well. However, each time you write the data back on update the encryption is different from the previous time.
I have a search screen that allows users to enter text data and submit it looking for matches. Of course, the user is entering unencrypted text and the DB data is encrypted.
This means that you can't encrypt the input data before you try to match because the encryption alogorithm used on the input data will not match that which was used to encrypt the DB data.
Are you with me so far?
So, you have to compare the uncencrypted input data with DECRYPTED DB data - in other words, decrypt the DB data on the fly within the where clause of your query.
I have accomplished this by writing a UDF that instantiates an instance of the CAPICOM encryption module and calling the UDF when applying the query eg where udf(columnname1) = 'inputtext' or udf(columnname1) = 'inputtext'.
It works, I get the results that I want.
But, alas, the performance has taken a search severe hit.
When I define a UDF in SQL 2000 I can't execute it without qualifiction. Here's the code: CREATE FUNCTION GetLastShipDate(@DO_No CHAR(10)) RETURNS CHAR(10) -- DROP FUNCTION GetLastShipDate BEGIN DECLARE @v_last_ship_date CHAR(10)
SELECT @v_last_ship_date = COALESCE(CONVERT(CHAR(10), MAX(Asn.Asn_Ship_DateTime), 110), '') FROM Asn,Asn_Do WHERE Asn_Do.Asn_Number=Asn.Asn_Number AND Asn_Do.DO_Number = @DO_No AND Asn.ASN_STATUS in ('SENT','RESENT')
Hi, Iam new to sql server. I want to create a user defined function to get date in a year(starting day of a week-i.e sunday date) when we give week number as argument. can any body help on this issue?
Is there a way to call a SQL user-defined function in a DTS, perhapsin an ActiveX transformation? I want the destination table to have avalue that was modified by a pre-defined function.-Noelle
Hi everyone, Today while using user defined functions, I noticed that we must write dbo. before the function name which I did not conceive why it is used like that. Why are there an exception for functions ? Why do we not have to use the same thing while using SP or not user defined functions ?
declare @statusID varchar(100) set @statusID = '1, 2'
--this works select id from SplitWords(@statusID, ',')
--this doesn't
declare @sql nvarchar(2000) set @sql = 'select * from Mast where ' + 'phmStatusID in ( select id from ' + 'SplitWords(@statusID, '', '')' + ') ' exec sp_executesql @sql
is what I'm trying to do not allowed? if so, whats the right way to do this?
Dear all, I was given a project to transfer our database into sql server database.
In our previous database we used the datatype int4 for some columns to create some views and in some queries that we used to build our datawindows. In SQLServer 2000 i created a user defined function named int4. I can execute it with the line select dbo.int4(poso) from employee .
Unfortrunately this way make me to rebuild all my datawindows and replace int4( with dbo.int4( . Is there any way to execute queries using user defined function but omitting the first part name dbo. I mean to manage execute the command select int4(poso) from employee \let int4 be a user definded function.
If i can€™t solve this, i thing it will decided than is impossible to move to sqlserver Database. Has anyone any suggestions?
I am getting some trial by fire here as I need to update some user defined functions in an application a co-worker built. He has since left and I've been asked to take over this project since I had a VB 6.0 and regular ASP class 6 years ago ... obviously quite a transition! I have started to figure out a bit but I can't find much on creating my own User Defined Functions and/or the best ways to test ones that I need to edit. My first one came back with this after I added it to SQL Server 2005 through Enterprise Manager... Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.fn_User_Data'.Thanks for any tips,Andrew
I have 3 fields in my table say (F1, F2, F3). I want to get the max value out of the three fields for each row. I can create a user-defined function which accepts 3 arguments and then return the max value if i am using SQL Server 2000. But now i am using only SQL Server 7.0 (it does not support user-defined functions :confused: )
So any one could kindly let me know how could i do it in SQL Server 7.0
I want to simulate a table, using a Multi-statement Table-Value User-Defined Function, but I need the function build the SQL statement from scratch each time so I can dynamically define values like the table it references. The only way I know how to run the query after it has been defined in this manner is to run an EXEC command. However I'm getting an error basically saying that the EXEC command is off limits in a User Defined Function.
The Exsact Error is: >[Error] Script lines: 1-108 ------------------------ Invalid use of side-effecting or time-dependent operator in 'EXECUTE STRING' within a function.
Is there some way to get around this limitation of User Defined Functions. Or perhaps a way to simulate the functionality of Multi-statement Table-Value User-Defined Functions in a Store Procedure, specifically the ability to run where statements, or transform the data on the fly without re-writing the Stored Procedure every time.
The code I’m trying to run is below.
(Note: The code works as a stored procedure, so I'm sure that the core of the statment is correct)
CREATE FUNCTION [dbo].[TrendLine] ( @Summary as smallint, @Start as datetime, @End as datetime, @Table as varchar(100), @X as varchar(100), @Count as varchar(100), @Duration as varchar(100) ) RETURNS @TrendLineTable table ( DATE_DAY datetime , EQ_REGION varchar(25) , EQ_MARKET_CLUSTER varchar(30) , Y float , X int , DURATION float , FORMULA varchar(100) , a float , b float , EX int , EY float , EX2 int , EXY float , N int ) AS BEGIN
DECLARE @SQL as varchar(3000) , @CountText as varchar(150) , @StartText as varchar(50) , @EndText as varchar(50)
SET @StartText = 'cast( ' + char(39) + cast( @Start as varchar(20) ) + char(39) + ' as datetime ) ' SET @EndText ='cast( ' + char(39) + cast( @End as varchar(20) ) + char(39) + ' as datetime ) ' IF @Summary = 1 BEGIN SET @CountText = 'sum' END ELSE BEGIN SET @CountText = 'count' END
SET @SQL = 'INSERT INTO @TrendLineTable DECLARE TrendlineC cursor for SELECT a.DATE_DAY , s2.EQ_REGION , s2.EQ_MARKET_CLUSTER , ( ( EY - ( b * EX ) ) / N ) + ( b * X ) AS Y , X , Y AS DURATION , cast( b as varchar(100) ) + ' + char(39) + 'x + ' + char(39) + ' + cast( ( EY - ( b * EX ) ) / N as varchar(100) ) AS FORMULA , ( EY - ( b * EX ) ) / N AS a , b , EX , EY , EX2 , EXY , N FROM ( SELECT EQ_REGION , EQ_MARKET_CLUSTER , sum( X ) AS EX , sum( Y ) AS EY , sum( X2 ) AS EX2 , sum( XY ) AS EXY , count( X ) AS N , ( ( count( X ) * sum( XY ) ) - ( sum( X ) * sum( Y ) ) ) / ( ( count( X ) * sum( X2 ) ) - POWER( sum( X ), 2 ) ) AS b FROM ( SELECT ' + @X + ' AS DATE_DAY , EQ_REGION , EQ_MARKET_CLUSTER , row_number() over (partition by EQ_MARKET_CLUSTER order by ' + @X + ' ) AS X , cast( sum( ' + @Duration + ' ) as float ) / ' + @CountText + '( ' + @Count + ' ) AS Y , POWER( row_number() over (partition by EQ_MARKET_CLUSTER order by ' + @X + ' ), 2) X2 , row_number() over (partition by EQ_MARKET_CLUSTER order by ' + @X + ' ) * cast( sum( ' + @Duration + ' ) as float ) / ' + @CountText + ' ( ' + @Count + ' ) AS XY FROM ' + @Table + ' WHERE ' + @X + ' >= ' + @StartText + ' AND ' + @X + ' < ' + @EndText + ' GROUP BY ' + @X + ' , EQ_REGION , EQ_MARKET_CLUSTER ) s1 GROUP BY EQ_REGION , EQ_MARKET_CLUSTER ) s2 INNER JOIN ( SELECT ' + @X + ' AS DATE_DAY , EQ_MARKET_CLUSTER , row_number() over (partition by EQ_MARKET_CLUSTER order by ' + @X + ' ) AS X , cast( sum( ' + @Duration + ' ) as float ) / ' + @CountText + '( ' + @Count + ' ) AS Y FROM ' + @Table + ' WHERE ' + @X + ' >= ' + @StartText + ' AND ' + @X + ' < ' + @EndText + ' GROUP BY ' + @X + ' , EQ_REGION , EQ_MARKET_CLUSTER ) a ON s2.EQ_MARKET_CLUSTER=a.EQ_MARKET_CLUSTER'
Hi all!!Does anybody know how I can create a function in SQL 7.0?? I have tocreate functions that return a value that can be used in a selectstatement. I think SQL Server version 7.0 doesn't support CREATEFUNCTION, does it?Ex:Select MyFunction(Parameter)From MyTableThanks a lot,
I have a number of databases that require a set of common functions. I'd like to place all those functions in a central DB. I'm having trouble calling them using the syntax FunctionDB.GetParamLength() for example, which works within the FunctionDB database.
Any ideas/suggestions? I really don't want to maintain seperate copies of the functions across 5+ databases.
Running into a brain problem here. I remeber reading an article a while back (2002?) on either Visual Studio Magazine or MSDN Magazine where there was a way to generate Stored Procedures from User Defined Functions. I need this information in order to do my job as it is also a way to cut down on time for this project I am trying to finish. Does anyone have the code or remeber what I am talking about. I just finished Kathleen Dollards article again on using XSLT to generate code but would really like to use the User Defined Functions.
I searched for the article on line but came up dry. Searched through all my magazines but could not find the article. Any help would be greatly appreciated. Bit of topic I guess but still relevant to the board.
I would like to offer you the following string functions Transact-SQL
GETWORDCOUNT() Counts the words in a string GETWORDNUM() Returns a specified word from a string AT() Returns the beginning numeric position of the first occurrence of a character expression within another character expression, counting from the leftmost character RAT() Returns the numeric position of the last (rightmost) occurrence of a character string within another character string OCCURS() Returns the number of times a character expression occurs within another character expression PADL() Returns a string from an expression, padded with spaces or characters to a specified length on the left side PADR() Returns a string from an expression, padded with spaces or characters to a specified length on the right side PADC() Returns a string from an expression, padded with spaces or characters to a specified length on the both sides PROPER() Returns from a character expression a string capitalized as appropriate for proper names RCHARINDEX() Is similar to a built-in function Transact-SQL charindex but the search of which is on the right ARABTOROMAN() Returns the character Roman number equivalent of a specified numeric expression ROMANTOARAB() Returns the number equivalent of a specified character Roman number expression ...
More than 2000 people have already downloaded my functions. I hope you will find it useful as well.
For more information about string UDFs Transact-SQL please visit the http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,54,33,27115
Please, download the file http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,2,27115
I am pleased to offer, free of charge, the following string functions Transact-SQL:
AT(): Returns the beginning numeric position of the nth occurrence of a character expression within another character expression, counting from the leftmost character. RAT(): Returns the numeric position of the last (rightmost) occurrence of a character string within another character string. OCCURS(): Returns the number of times a character expression occurs within another character expression (including overlaps). OCCURS2(): Returns the number of times a character expression occurs within another character expression (excluding overlaps). PADL(): Returns a string from an expression, padded with spaces or characters to a specified length on the left side. PADR(): Returns a string from an expression, padded with spaces or characters to a specified length on the right side. PADC(): Returns a string from an expression, padded with spaces or characters to a specified length on the both sides. CHRTRAN(): Replaces each character in a character expression that matches a character in a second character expression with the corresponding character in a third character expression. STRTRAN(): Searches a character expression for occurrences of a second character expression, and then replaces each occurrence with a third character expression. Unlike a built-in function Replace, STRTRAN has three additional parameters. STRFILTER(): Removes all characters from a string except those specified. GETWORDCOUNT(): Counts the words in a string. GETWORDNUM(): Returns a specified word from a string. GETALLWORDS(): Inserts the words from a string into the table. PROPER(): Returns from a character expression a string capitalized as appropriate for proper names. RCHARINDEX(): Similar to the Transact-SQL function Charindex, with a Right search. ARABTOROMAN(): Returns the character Roman numeral equivalent of a specified numeric expression (from 1 to 3999). ROMANTOARAB(): Returns the number equivalent of a specified character Roman numeral expression (from I to MMMCMXCIX).
AT, PADL, PADR, CHRTRAN, PROPER: Similar to the Oracle functions PL/SQL INSTR, LPAD, RPAD, TRANSLATE, INITCAP.
Plus, there are CHM files in English, French, Spanish, German and Russian.
More than 6000 people have already downloaded my functions. I hope you will find them useful as well.
For more information about string UDFs Transact-SQL please visit the http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,54,33,27115
Please, download the file http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,2,27115
Following the horrendous performance of Scalar UDFs demonstrated in this thread URL....(Scalar UDF 10x slower than writing the code, long hand, in the SELECT) I now have the worry that their widespread usage in my code needs to be refactored. I guess pretty much any single-line non-table-valued scalar-function would do
CREATE FUNCTION dbo.FNSafeString ( @strValuevarchar(8000),-- STRING Value to convert to SAFE string @intModeint = 0-- 0=NULL as '[NULL]', 1=NULL as '' ) RETURNS varchar(8000) WITH SCHEMABINDING AS BEGIN RETURN COALESCE(@strValue, CASE WHEN @intMode = 0 THEN '[NULL]' ELSE '' END ) END
Its a little bit too big to really want to have to write it in each place where I need to use it, and its just big enough that it is worth centralising, and it might just be that I could code it more efficiently / different / handle more "edge cases" in the future.I do have even more straightforward UDFs - just to avoid typing something "Lengthy"
CREATE FUNCTION dbo.FNDateMidnight ( @dtDateTimedatetime-- Date/Time Value to adjust ) RETURNS datetime WITH SCHEMABINDING AS BEGIN RETURNDATEADD(Day, DATEDIFF(Day, 0, @dtDateTime)+1, 0) END
Perhaps I should consider changing them to inline table valued functions, or CROSS APPLY them? but I can't think of a way to centralised them and re-use the code WITHOUT a function, can I?
I would like to offer you the following string functions Transact-SQL
GETWORDCOUNT() Counts the words in a string GETWORDNUM() Returns a specified word from a string AT() Returns the beginning numeric position of the first occurrence of a character expression within another character expression, counting from the leftmost character RAT() Returns the numeric position of the last (rightmost) occurrence of a character string within another character string CHRTRAN() Replaces each character in a character expression that matches a character in a second character expression with the corresponding character in a third character expression STRFILTER() Removes all characters from a string except those specified OCCURS() Returns the number of times a character expression occurs within another character expression (include overlaps) PADL() Returns a string from an expression, padded with spaces or characters to a specified length on the left side PADR() Returns a string from an expression, padded with spaces or characters to a specified length on the right side PADC() Returns a string from an expression, padded with spaces or characters to a specified length on the both sides PROPER() Returns from a character expression a string capitalized as appropriate for proper names RCHARINDEX() Is similar to a built-in function Transact-SQL charindex but the search of which is on the right ARABTOROMAN() Returns the character Roman number equivalent of a specified numeric expression (from 1 to 3999) ROMANTOARAB() Returns the number equivalent of a specified character Roman number expression (from I to MMMCMXCIX)
AT, PADL, PADR, CHRTRAN, PROPER are similar to functions Oracle PL/SQL INSTR, LPAD, RPAD, TRANSLATE, INITCAP
More than 2000 people have already downloaded my functions. I hope you will find it useful as well.
For more information about string UDFs Transact-SQL please visit the http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,54,33,27115 Please, download the file http://www.universalthread.com/wconnect/wc.dll?LevelExtreme~2,2,27115
I would like to get some clarification about what these two concepts are.
This is what I think: lets say that you want the user to choose two columns to add together and then that produces a calculated result. This would go in a computed field???
And user-defined functions are functions whereby users have for example to which which two columns they were going to allow to be processed for the calculation.
Hi,I am trying to call a user defined function(UDF) from a stored proc,using a default parameter in the called UDF (e.g. @bid_price_type int= 0 ). However the calling stored proc complains that the UDF isexpecting a 2nd parameter when I only provide the @test parametervalue. Are default parameter values supported in UDF's?I wld really appreciate anybody's help. Thankyou in advance.UDF code:CREATE FUNCTION get_bid_price (@test int, @bid_price_type int = 0)RETURNS decimal(18, 4) ASBEGINdeclare @x decimal(18, 4)if (@bid_price_type = 0)beginselect @x = fieldNamefromtableNameendelsebeginselect @x = fieldName2fromtableName2endreturn @xEND' Calling Stored Proc codeCREATE PROCEDURE testASdeclare @x decimal(18, 4)set @x = dbo.get_bid_price(1)select @xGOthanks,Vic Y
http://www.csharphelp.com/archives2/archive342.htmlI am using the sample code from this link but I amunable to figure out how to retrieve the list ofthe User-Defined Functions. I am able to get thecount of the user defined functions correctly using:db.ListObjects(SQLDMO.SQLDMO_OBJECT_TYPE.SQLDMOObj _UserDefinedFunction,SQLDMO.SQLDMO_OBJSORT_TYPE.SQLDMOObjSort_Name).Cou ntbut I am unable to get to enumerate the function names.Then I tried to see if I can achieve what I want usingSQLObjectList but I was unsuccessful.Does someone know how I can do this using C#?Thank youThis is the full code I have:private void linkLabel5_LinkClicked(object sender,LinkLabelLinkClickedEventArgs e){this.Cursor = Cursors.WaitCursor;SQLDMO.SQLServer srv = new SQLDMO.SQLServerClass();srv.Connect(this.cboServers.SelectedItem.ToString( ), this.txtUser.Text,this.txtPassword.Text);for (int i = 0; i < srv.Databases.Count; i++){if (srv.Databases.Item(i + 1, "dbo").Name ==this.cboDatabase.SelectedItem.ToString()){SQLDMO._Database db = srv.Databases.Item(i + 1, "dbo");this.lstObjects.Items.Clear();SQLDMO.SQLObjectList sqludf;sqludf =db.ListObjects(SQLDMO.SQLDMO_OBJECT_TYPE.SQLDMOObj _UserDefinedFunction,SQLDMO.SQLDMO_OBJSORT_TYPE.SQLDMOObjSort_Name);for (int j = 0; j < sqludf.Count; j++){//this.lstObjects.Items.Add(db.ListObjects(SQLDMO.SQ LDMO_OBJECT_TYPE.SQLDMOObj_UserDefinedFunction,SQLDMO.SQLDMO_OBJSORT_TYPE.SQLDMOObjSort_Name).Ite m(j + 1, "dbo").Name);}this.Cursor = Cursors.Default;return;}}this.Cursor = Cursors.Default;}
One advantage that I can see withh UDFs is that they are a bit a Views with parameters. You can perform joins on UDF columns (which you cannot do with a Stored Proc). You can do the same with Views but UDFs have the advantage that you restrict the number of rows with a parameterised WHERE (or HAVING) clause.
I've got a couple guys on my team who seem to think user defined functions are a "risky" feature in SQL 2000. I've been using them for years without problems. Yeah, this one of those loaded prove me right or flame me questions ... whatever. I promise not to consider posts on MSDN forums authoritative answers to this practice question. I'm just trying to see where people stand. What I'm interested in knowing is:
Do you consider UDF's in SQL advanced, hard to figure out, hard to get right or risky?
Any cases where they've caused you more problems than other MS SQL features?
Random hints on best-practice for UDF's - where do they spead things up, slow things down?
Reasons that they are better than sliced bread / cheese spread?