这个问题可以很容易地采用多条路径,因此我将首先尝试更具体的路径。在使用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块不是一个选项。
答案 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'在一个函数内。