尝试捕获用户定义函数?

Moo*_*ose 5 t-sql user-defined-functions

我正在尝试编写UDF以将字符串或与该guid相关联的项目代码转换为guid:

CREATE FUNCTION fn_user_GetProjectID 
(
    @Project nvarchar(50)
)
RETURNS uniqueidentifier
AS
BEGIN

    declare @ProjectID uniqueidentifier

    BEGIN TRY
        set @ProjectID = cast(@Project as uniqueidentifier)
    END TRY
    BEGIN CATCH
        set @ProjectID = null
    END CATCH

    if(@ProjectID is null)
    BEGIN
        select  @ProjectID = ProjectID from Project where projectcode = @Project
    END

    return @ProjectID

END
Run Code Online (Sandbox Code Playgroud)

如果上面的代码已嵌入到我的存储过程中,则可以正常工作,但是我想从中创建一个函数,以便我遵循DRY。

当我尝试创建函数时,出现如下错误:

Msg 443, Level 16, State 14, Procedure fn_user_GetProjectID, Line 16
Invalid use of side-effecting or time-dependent operator in 'BEGIN TRY' within a function.
Run Code Online (Sandbox Code Playgroud)

有谁知道我如何解决这个错误?

编辑:我知道我不能在函数中使用Try-Catch,我想这是一个简化的问题,有没有一种方法可以进行转换,如果转换失败,它只会返回NULL而不是错误?

DOK*_*DOK 5

显然你不能在 UDF 中使用 TRY-CATCH。

根据SQL Server 的这个错误报告页面

联机丛书在“CREATE FUNCTION (Transact-SQL)”主题中记录了这种行为:“以下语句在函数中有效:[...] 除 TRY...CATCH 语句外的 Control-of-Flow 语句。[.. .]”

但早在 2006 年,他们就给未来带来了希望:

但是,这是一个严重的限制,应该在未来的版本中删除。你应该在这方面提出建议,我会全心全意地投赞成票。


8kb*_*8kb 3

来自MSDN

uniqueidentifier 数据类型的列或局部变量可以通过以下方式初始化为值:

通过使用NEWID函数。

通过从 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 形式的字符串常量进行转换,其中每个 x 是 0-9 或 af 范围内的十六进制数字。

例如,6F9619FF-8B86-D011-B42D-00C04FC964FF 是有效的唯一标识符值。

您可以使用模式匹配来验证字符串。请注意,这不适用于减少 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
Run Code Online (Sandbox Code Playgroud)