SQL Server - 将 VARCHAR 转换为 INT; TRY_CAST 还是 TRY/CATCH 更好?

问题描述 投票:0回答:1

我正在查看一些 T-SQL 代码(在 SQL Server 2019 环境中),其中存储过程中的参数是“重载”的 VARCHAR (15) 参数,稍后将转换为 INT。我思考这会如何出错——它实际上可能不是一个数字字符串,或者它可能代表一个太大而无法放入 INT 变量的数字。我想要一些高效的东西,我开始考虑使用 TRY_CAST 而不仅仅是 CAST,或者使用 TRY/CATCH 块,在成功时进行转换,或者在失败时允许“一条出路”。为了简化...

-- given these...
declare @AParamter varchar (15) = '214748364700'; -- 100x bigger than max INT
declare @AVariable int;

-- ...approach 1...
set @AVariable = try_cast( @AParamter as int );

if (@AVariable is null) begin
    print 'ERROR: invalid parameter';
end

-- ...approach 2...
begin try
    set @AVariable = cast( @AParamter as int );
end try
begin catch
    print 'ERROR: invalid parameter';
end catch

两者都有效,但我想知道哪个更“高效”,即需要更少的资源(并且不可否认,与其他正在发生的事情相比,任何一个都可能是最小的),或者其中任何一个有任何隐藏的“陷阱”。

我正在使用 sys.dm_exec_*_stats 视图来收集我正在测试的存储过程的指标,并且我假设 Total_Worker_Time 和 Total_Elapsed_Time 指标是最相关的,但它们可能变化很大(在proc)很难看出哪种方法可能会产生更大(或任何)效果,无论是好是坏。所以,我问这个主要是出于好奇,想知道哪种方法是更好的做法,或者还有什么可能更好。

我尝试在网络和 StackOverflow 上搜索任何信息,但我似乎找不到任何涉及性能比较的结果。

注意:我的偏好是不要重载此参数;我个人的感觉是,它应该是多个参数,每个参数都是正确的类型,并且一次只有一个参数不为空,并进行特定检查以确保我们填写了一个且只有一个,但是......这并不是真的由我决定。

sql-server t-sql casting try-catch
1个回答
0
投票

TRY_CAST
速度更快, 也更清晰。

以下脚本将向您展示:

declare @v varchar(10)='hello';
declare @i int = 1;
declare @x int;
declare @dt datetime2 = sysdatetime();

while @i < 10000
begin
    set @x = try_cast(@v as int);
    set @i += 1;
end;
select datediff(mcs, @dt, sysdatetime());

set @i = 1;

while @i < 10000
begin
    begin try
        set @x = cast(@v as int);
    end try
    begin catch
    end catch;
    set @i += 1;
end;
select datediff(mcs, @dt, sysdatetime());

db<>小提琴

如果您正在捕捉,

10k 循环大约需要 1 秒,而

TRY_CAST
大约需要 30 毫秒。

原因可能很简单:

BEGIN CATCH
涉及很多带有异常处理的gubbins,例如遍历堆栈和展开。而
TRY_CAST
只能返回 null。

© www.soinside.com 2019 - 2024. All rights reserved.