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)
该错误没有在解析时发生。如果您对代码选择运行解析 (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。