November 22, 2008 at 4:41 pm
I'd like to make a function that works like coalesce in that it accepts an unlimited number of parameters of a single type and outputs an answer. In particular I would like to create a function that can determine the minimum from multiple columns. In the end I would like to use this function to make a computed column.
Yes, I realize that might be a sign of denormalized data structure, which in the scenario I'm apply this to is denormalized.
Let's do an example
Columns
OptOutDate datetime
InactiveDate datetime
UnsubscribeDate datetime
The UnsubscribeDate is a computed column that is the minimum of the two columns OptOutDate and InactiveDate.
Thanks in advance.
November 22, 2008 at 7:05 pm
In 2005, the options are a comma-delinited list or an xml document or similar. Messy, I know. In 2008 you can use a table-valued parameter.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
November 22, 2008 at 7:15 pm
Hi,
Why don't you use CASE statement? Maybe more explicit, but deffinitely faster.
create table t1
(
OptOutDate datetime,
InactiveDate datetime,
UnsubscribeDate as case when OptOutDate < InactiveDate then OptOutDate else InactiveDate end
)
go
insert into t1 (OptOutDate, InactiveDate) values (getdate(), dateadd(day, 1, getdate()))
insert into t1 (OptOutDate, InactiveDate) values (getdate(), dateadd(day, -1, getdate()))
select * from t1
go
drop table t1
Regards
Piotr
...and your only reply is slàinte mhath
November 22, 2008 at 11:07 pm
The limitation isn't a CLR limitation, it is a limitation in SQL in general. A function has a set of input parameters, and a set output payload, even if it is a TVF, you still have a set schema that it is going to output. I wouldn't even recommend CLR for what you are trying. A simple CASE statement for the computed column as Piotr demonstrated will do the job in TSQL natively just fine.
Jonathan Kehayias | Principal Consultant | MCM: SQL Server 2008
My Blog | Twitter | MVP Profile
Training | Consulting | Become a SQLskills Insider
Troubleshooting SQL Server: A Guide for Accidental DBAs[/url]
November 23, 2008 at 7:37 pm
Well you could write something like this, or its equivalent in CLR:
Create function dbo.fnMAX(
@p1 SQL_Variant
, @p2 SQL_Variant = NULL
, @p3 SQL_Variant = NULL
) Returns SQL_Variant
AS
Begin
Declare @val SQL_Variant
Set @val = @p1
IF @p2 IS NOT NULL
IF @p3 IS NOT NULL
Return @val
End
But it will never work like Coalesce. For one thing, User-defined functions (unlike built-in ones) cannot be invoked without specifying all of the parameters. You have to explicitly pass NULL for the ones that you want to skip.
[font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
Proactive Performance Solutions, Inc. [/font][font="Verdana"] "Performance is our middle name."[/font]
November 24, 2008 at 7:00 am
Thank you all for your input. I did implement it as a CASE statement originally (see below). I am looking for a non case statement solution to handle the problem where many columns are used. Since as the number of columns increase the complexity of the case statement gets unwieldy.
case
when OptOutDate IS NOT NULL AND InactiveDate IS NOT NULL then
case when OptOutDate<InactiveDate then OptOutDate
else InactiveDate end
when OptOutDate IS NULL AND InactiveDate IS NULL then NULL
when OptOutDate IS NOT NULL then OptOutDate
when InActiveDate IS NOT NULL then InactiveDate
end
Perhaps using ISNULL() could reduce this complexity.
November 24, 2008 at 8:15 am
What I laid out for you is how to do it.
If the optional parameters handling is a problem, just implement your case function as a two-parameter version that has null-handling and then use nesting when you invoke it:
, dbo.fnMAX(p1, dbo.fnMAX(p2, dbo.fnMAX(p3, p4))) as [MaxValue]
, ...
[font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
Proactive Performance Solutions, Inc. [/font][font="Verdana"] "Performance is our middle name."[/font]
November 24, 2008 at 8:57 am
Thanks Barry, I'll have to do some performance testing and see how goes if I ever need to apply this across multiple columns.
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply