如何区分运行时错误和其他错误?

J. *_*ini 1 sql-server t-sql errors

请考虑以下错误消息。

消息 207 级别 16 状态 1 第 7 行

列名“FOO”无效。

由于我触发它的方式,我碰巧知道这是一个解析/编译时错误。

假设我正在运行一个不属于过程的长脚本,并且我收到了相同的错误消息。此错误消息中的内容告诉我错误是在解析/编译时而不是运行时发生的?


CREATE TABLE Department_History
(
    DepartmentNumber INT
);
GO

ALTER TABLE Department_History ADD FOO INT;

-- This is fine and shows FOO.
SELECT * FROM Department_History;

-- When uncommented, this fails at parse time.
INSERT Department_History (DepartmentNumber, FOO) VALUES (4, 5), (6, 7), (8, 9);
Run Code Online (Sandbox Code Playgroud)

Zik*_*ato 7

该错误没有在解析时发生。如果您对代码选择运行解析 (Ctrl + F5),它将成功。

相反,问题出在“绑定”步骤中。

我将从 Paul White 的博客文章《查询优化器深入探究 - 第 1 部分》中借用此图

在此输入图像描述

至于这个问题,我不相信SQL服务器(很容易)发现错误发生在哪一步。

我已经使用扩展事件捕获了错误的调用堆栈,然后使用SQLCallStackResolver来转换该错误

value   count
00 sqllang!XeSqlPkg::error_reported::Publish
01 sqllang!ErrorReportedAutoPublish::Publish
02 sqllang!CErrorReportingManager::CwchFormatAndPrint
03 sqllang!ex_vcallprint_no_dump
04 sqllang!SQLCompileHandler
05 SqlDK!CallExceptionHandler
06 SqlDK!ex_raise2
07 SqlDK!ex_raise_va_list
08 sqllang!alg_ex_raise
09 sqllang!CScaOp_Identifier::BindSelf
0a sqllang!CScaOpArg::BindScalarTree
0b sqllang!CScaOpArg::BindTree
0c sqllang!COptExpr::BindTree
0d sqllang!CRelOp_DML::BindColumnList
0e sqllang!CRelOp_Insert::GetLhsTypesForUnion
0f sqllang!CRelOp_Insert::BindTree
10 sqllang!COptExpr::BindTree
11 sqllang!CRelOp_DMLQuery::BindTree
12 sqllang!COptExpr::BindTree
13 sqllang!CRelOp_Query::FAlgebrizeQuery
14 sqllang!CProchdr::FNormQuery
15 sqllang!CProchdr::FNormalizeStep
16 sqllang!CSQLSource::FCompile
17 sqllang!CSQLSource::FCompWrapper
18 sqllang!CSQLSource::Transform
19 sqllang!CSQLSource::Compile
1a sqllang!CStmtPrepQuery::Init
1b sqllang!CCompPlan::FCompileStep
1c sqllang!CSQLSource::FCompile
Run Code Online (Sandbox Code Playgroud)

您可以看到,就在异常发生之前,它尝试了BindTree