我正在学习这个例子而我不是
merge into employeegrades eg
using (select id, name from temp_emp) emp
on (eg.id = emp.id)
when matched and eg.grades > 150 then
delete
when matched
update set eg.grades = eg.grades+25
when not matched then
insert (id,grades)
values (emp.id, 25);
计划的输出是:
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else {
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try {
puts("in try");
__try {
puts("in try");
*p = 13; // causes an access violation exception;
}
__finally {
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}
__except (filter(GetExceptionCode(), GetExceptionInformation())) {
puts("in except");
}
puts("world");
}
我很困惑为什么它首先过滤然后最后过滤然后打印“in except”。 如果它转到__则不是真的,那么它应该完成执行。
答案 0 :(得分:1)
这些不是标准的C ++异常,而是微软自己的语言扩展。
如果您从找到该示例的页面继续阅读the documentation for try-finally
,您会发现:
如果找到处理程序,则执行任何和所有__finally块,并在处理程序中继续执行。
这并不奇怪 - 在具有这些结构的语言中,finally
块总是被执行(这就是它的目的)。
通常情况下,程序员没有运行时控制异常被捕获的位置,因此您不能像处理filter
那样中断处理以查看幕后。
答案 1 :(得分:0)
在micorosoft网站上写下如下声明:
使用longjmp运行时函数退出try-finally语句被视为异常终止。跳入__try语句是违法的,但跳出一个是合法的。必须运行在出发点(__try块的正常终止)和目标(处理异常的__except块)之间有效的所有__finally语句。这称为本地展开。
它清楚地提到第一个try块然后执行_except然后在退出try块之前最后执行finally块。