FistOfFury
FistOfFury

Reputation: 7155

SQL CLR Aggregate function Error Handling

I have a user defined CLR aggregate function that can potentially throw an error. I would like to know how to handle an error if one occurs in my query.

The function is performing an IRR calculation similar to that which Excel does, ie. an iterative root-finding calculation. If no root is found, an error is thrown. This is the error I need to handle.

The query is part of a larger stored procedure and it looks something like:

select 
MyID, 
Excel_XIRR(col1) 
from @t
group by MyID

and the error i get is something like this:

A .NET Framework error occurred during execution of user-defined routine or aggregate "Excel_Xirr": 
System.ArgumentException: Not found an interval comprising the root after 60 tries, last tried was (-172638549748481000000000.000000, 280537643341281000000000.000000)
System.ArgumentException: 
   at System.Numeric.Common.rfindBounds@59(FastFunc`2 f, Double minBound, Double maxBound, Double precision, Double low, Double up, Int32 tries)
   at System.Numeric.Common.findBounds(FastFunc`2 f, Double guess, Double minBound, Double maxBound, Double precision)
   at System.Numeric.Common.findRoot(FastFunc`2 f, Double guess)
   at Excel_Xirr.Terminate()

My problem is that not all the rows cause this error. There are some legitimate results from the query that I want to capture and use later in my stored procedure. Will this error stop me from getting the results of the query? If so, is there a way to figure out which rows throw the error (dynamically) and then rerun the query for the rest of the rows?

Upvotes: 0

Views: 570

Answers (1)

user3177013
user3177013

Reputation:

Not sure how well you have coded the XIRR function itself, looking at your function prototypes in Error messages it would seem you are using a Bi-section method of finding roots which is not most suitable to algorithms to use when it comes to finding rates. You will be locking yourself within a lower and upper bound no matter how large this bound is it is not going to help for all cases

As for solving your immediate problem with handling the error, you can change your .net code and replace the Throw...Exception statement with a return value of Math.Pow(-1, 0.5)

This will return a NAN to the calling program which you can then check with an IF statement to confirm whether your XIRR value is a number (when IRR is found) or a NAN value (when IRR is not found)

Upvotes: 1

Related Questions