T-SQL标量函数中的错误处理

时间:2010-05-27 15:59:33

标签: sql-server-2005 function error-handling sql-server-2000 type-conversion

这个问题可以很容易地采用多条路径,因此我将首先尝试更具体的路径。在使用SQL Server 2005时,我正在尝试创建一个标量函数,它充当从varchar到int的'TryCast'。我遇到问题的地方是我在函数中添加一个TRY块;

CREATE FUNCTION u_TryCastInt
(
   @Value as VARCHAR(MAX)
)
RETURNS Int
AS
BEGIN
   DECLARE @Output AS Int

   BEGIN TRY
      SET @Output = CONVERT(Int, @Value)
   END TRY
   BEGIN CATCH
      SET @Output = 0
   END CATCH

   RETURN @Output
END

这个陈述的各种错误包括“在函数中'开始尝试'中无效使用副作用或时间相关运算符”和“无效使用副作用或时间相关运算符” 'END TRY'在一个函数中“。我似乎无法找到在标量函数中使用try语句的任何示例,这让我想到,函数中的错误处理是否可行?

此处的目标是创建一个强大的Convert或Cast函数版本,以允许SELECT语句执行depsite转换错误。例如,请执行以下操作;

    CREATE TABLE tblTest
    (
        f1 VARCHAR(50)
    )
    GO

    INSERT INTO tblTest(f1) VALUES('1')
    INSERT INTO tblTest(f1) VALUES('2')
    INSERT INTO tblTest(f1) VALUES('3')
    INSERT INTO tblTest(f1) VALUES('f')
    INSERT INTO tblTest(f1) VALUES('5')
    INSERT INTO tblTest(f1) VALUES('1.1')

    SELECT CONVERT(int,f1) AS f1_num FROM tblTest

    DROP TABLE tblTest

它永远不会达到丢弃表的目的,因为尝试将'f'转换为整数时执行挂起。我希望能够做到这样的事情;

SELECT u_TryCastInt(f1) AS f1_num FROM tblTest

fi_num
__________
1
2
3
0
5
0

对此有何想法?有什么存在可以解决这个问题吗?另外,我想尝试扩展对话以支持SQL Server 2000,因为在这种情况下Try块不是一个选项。

3 个答案:

答案 0 :(得分:5)

检查你是否可以先转换为int,在这里查看IsInteger函数:IsNumeric, IsInt, IsNumber它将在2000及以后工作

答案 1 :(得分:2)

并且,回答一般:不,你不能在函数中使用try-catch逻辑。我可以理解为什么 - 或者至少它显然更好地避免它,因为它会带来巨大的性能损失。

然而,我觉得奇怪的是,一个人也不能在函数中引发错误......这是内置函数已经做到的。我想通过返回NULL必须得到。

答案 2 :(得分:0)

TRY ... CATCH构造不能在SQL 2012中的用户定义函数中使用!

看到这个: http://msdn.microsoft.com/en-us/library/ms175976.aspx

当我尝试使用此脚本时:

CREATE FUNCTION u_TryCastInt
(
   @Value as VARCHAR(MAX)
)
RETURNS Int
AS
BEGIN
   DECLARE @Output AS Int

   BEGIN TRY
      SET @Output = CONVERT(Int, @Value)
   END TRY
   BEGIN CATCH
      SET @Output = 0
   END CATCH

   RETURN @Output
END

我收到了错误:

  

Msg 443,Level 16,State 14,Procedure u_TryCastInt,Line 10
  无效使用副作用操作符' BEGIN TRY'在一个功能内。
  Msg 443,Level 16,State 14,Procedure u_TryCastInt,Line 12
  无效使用副作用运算符' END TRY'在一个功能内。
  Msg 443,Level 16,State 14,Procedure u_TryCastInt,Line 13
  无效使用副作用操作符' BEGIN CATCH'在一个功能内。
  Msg 443,Level 16,State 14,Procedure u_TryCastInt,Line 15
  无效使用副作用运算符' END CATCH'在一个函数内。