SQL JOIN未指定列别名时TRY CATCH无法捕获歧义列错误原因求解
SQL Server TRY CATCH未捕获列名二义性错误的原因
核心逻辑是:SQL Server 的TRY CATCH块仅能捕获运行时产生的错误,无法捕获编译阶段触发的、导致整个批处理无法执行的错误,两个场景的差异本质是错误发生的阶段不同。
- 场景1的
String or binary data would be truncated属于运行时错误:代码在编译阶段可以正常通过校验,只有执行INSERT语句、实际写入数据时才会触发字段长度校验失败的错误,此时TRY块已经处于执行状态,错误可以被CATCH块正常捕获。 - 场景2的
Ambiguous column name 'name'属于编译阶段的语义校验错误:SQL Server在解析整段批处理代码、生成执行计划的阶段,就会检测到SELECT语句中的name列同时存在于两个关联表、未指定所属表别名的问题,校验失败后整个批处理会直接终止,根本不会进入TRY块的执行流程,因此CATCH块不会被触发。
如果需要捕获这类编译相关的错误,可以将存在编译风险的语句放入动态SQL中执行,动态SQL的编译动作是在运行时触发的,对应的错误就可以被正常捕获,参考写法:
BEGIN TRY IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp CREATE TABLE #temp (name varchar(1)) IF OBJECT_ID('tempdb..#temp01') IS NOT NULL DROP TABLE #temp01 CREATE TABLE #temp01 (name varchar(1)) INSERT INTO #temp VALUES ('A') INSERT INTO #temp01 VALUES ('A') -- 把有歧义的查询放到动态SQL中执行 EXEC('select name from #temp a join #temp01 b on a.name = b.name') END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage; END CATCH
内容的提问来源于stack exchange,提问作者Sergio Tagliaferri
相关产品推荐
相关产品推荐

