Try-Catch in User Defined Function?
Apparently you can't use TRY-CATCH in a UDF.
According to this bug-reporting page for SQL Server:
Books Online documents this behaviour, in topic "CREATE FUNCTION (Transact-SQL)": "The following statements are valid in a function: [...] Control-of-Flow statements except TRY...CATCH statements. [...]"
But they were giving hope for the future back in 2006:
However, this is a severe limitation that should be removed in a future release. You should post a suggestion in this regard and I will wholeheartedly vote for it.
From MSDN:
A column or local variable of uniqueidentifier data type can be initialized to a value in the following ways:
By using the NEWID function.
By converting from a string constant in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, in which each x is a hexadecimal digit in the range 0-9 or a-f.
For example, 6F9619FF-8B86-D011-B42D-00C04FC964FF is a valid uniqueidentifier value.
You can use pattern matching to verify the string. Note that this won't work for specific encoding that reduces the size of the GUID:
declare @Project nvarchar(50)
declare @ProjectID uniqueidentifier
declare @HexPattern nvarchar(268)
set @HexPattern =
'[A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9]' +
'[A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9]' +
'[A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9]' +
'[A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9][A-F0-9]'
/* Take into account GUID can have curly-brackets or be missing dashes */
/* Note: this will not work for GUIDs that have been specially encoded */
set @Project = '{' + CAST(NEWID() AS VARCHAR(36)) + '}'
select @Project
set @Project = REPLACE(REPLACE(REPLACE(@Project,'{',''),'}',''),'-','')
/* Cast as uniqueid if pattern matches, otherwise return null */
if @Project LIKE @HexPattern
select @ProjectID = CAST(
SUBSTRING(@Project,1,8) + '-' +
SUBSTRING(@Project,9,4) + '-' +
SUBSTRING(@Project,13,4) + '-' +
SUBSTRING(@Project,17,4) + '-' +
SUBSTRING(@Project,21,LEN(@Project)-20)
AS uniqueidentifier)
select @ProjectID
I know I can't use Try-Catch in a Function, I guess a simplified questions would be, is there a way to do a cast that will just return NULL if the cast fails, instead of an error?
Starting from SQL Server 2012 you could use TRY_CAST/TRY_CONVERT functions:
Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
CREATE FUNCTION fn_user_GetProjectID(@Project nvarchar(50))
RETURNS uniqueidentifier
AS
BEGIN
declare @ProjectID uniqueidentifier = TRY_CAST(@Project as uniqueidentifier);
IF(@ProjectID is null)
BEGIN
select @ProjectID = ProjectID from Project where projectcode = @Project;
END
return @ProjectID;
END