Не недокументированный
любезность RowNumber Itzik Ben-Gan http://www.sqlmag.com/article/articleid/97675/sql_server_blog_97675.html
УСТАНАВЛИВАЕТ XACT_ABORT НА откате все на ошибке для транзакций
, весь _ SP полезен, просто просматривают книги онлайн
сочетания клавиш, которые я использую все время в студии управления, которую F6 - переключают между результатами и запрашивают Alt+X или F5-выполненный выделенный текст в запросе, если ничто не выбрано, работает, все окно Alt+T и Alt+D - приводит к тексту или сетке соответственно
throw;
повторно генерирует тот же объект исключения, который он поймал, а throw ex;
генерирует новое исключение. Это не имеет значения, кроме причин производительности создания нового объекта исключения. Если у вас есть иерархия исключений, в которой есть другие классы исключений, производные от класса MyException
, и при генерации исключения вы выполнили выброс throw DerivedClassException;
его можно поймать с помощью ловушки (MyException &)
. Теперь, если вы измените этот пойманный объект исключения и повторно выбросите его, используя throw;
, тип объекта исключения по-прежнему будет DerivedClassException
. Если вы выполните throw Ex;
, произойдет разрезание объекта, и новое исключение будет иметь тип MyException
.
[ C ++ FAQ Lite § 17.9 ] Что означает
;
(без объекта исключения после ключевого словаthrow
)? Где мне его использовать?Вы можете увидеть примерно такой код:
class MyException { общественность: ... void addInfo (const std :: string & info); ... }; void f () { пытаться { ... } catch (MyException & e) { e.addInfo ("f () не удалось"); бросить; } }
В этом примере оператор
throw;
означает «повторно выбросить текущее исключение». Здесь функция перехватила исключение (по неконстантной ссылке), изменила исключение (добавив к нему информацию), а затем повторно выбросила исключение. Эту идиому можно использовать для реализации простой формы трассировки стека, добавив соответствующие предложения catch в важные функции вашей программы.Другой идиомой повторного выброса является «диспетчер исключений»:
void handleException () { пытаться { бросить; } catch (MyException & e) { ... код для обработки MyException ... } catch (YourException & e) { ... код для обработки исключения YourException ... } } void f () { пытаться { ... что-то, что может бросить ... } улов (...) { handleException (); } }
Эта идиома позволяет повторно использовать одну функцию (
handleException ()
) для обработки исключений в ряде других функций.[ C ++ FAQ Lite § 17.11 ] Когда я выброшу этот объект, сколько раз он будет скопирован?
Зависит. Может быть «ноль».
Выбрасываемые объекты должны иметь общедоступный конструктор копирования. Компилятору разрешено генерировать код, который копирует брошенный объект любое количество раз, включая ноль. Однако даже если компилятор на самом деле никогда не копирует брошенный объект, он должен убедиться, что конструктор копирования класса исключения существует и доступен.
( отредактировано для большей ясности в том, что я считал очевидным ... )
catch (MyException & ex) {throw ex; }
может копировать ex
со всеми вытекающими из этого проблемами; catch (MyException & ex) {бросить; }
не может.
Вы можете использовать форму throw;
с catch (...)
(то есть это единственный способ перебросить, если вы поймали поймать (...)).
Есть большая разница. Я написал об этом в своем блоге по адресу: https://cpptalk.wordpress.com/2009/08/23/nuances-of-exception-rethrow/
Приглашаем вас взглянуть
throw ex
создаст еще одну копию и не рекомендуется использовать throw
только для выброса текущего объекта исключения.
throw может вызывать нестандартный тип исключения, которое было перехвачено catch (...) ( например, структурированное исключение)
Кроме того, поскольку это иногда вызывает путаницу, простой выброс ;
вне контекста обработки исключений прервет выполнение программы.
Если у вас есть иерархия исключений, throw ex
может вырезать ваше исключение, а throw
не будет. Например:
#include <iostream>
#include <string>
using namespace std;
struct base
{
virtual string who() {return "base";}
};
struct derived : public base
{
string who() {return "derived";}
};
int main() {
try {
try {
throw derived(); // throws a 'derived'
}
catch (base& ex)
{
throw ex; // slices 'derived' object to be a 'base' object
}
}
catch (base& ex)
{
cout<<ex.who()<<endl; // prints 'base'
}
}
Измените throw ex
на просто throw
, и вы получите результат , производный
, что вы, вероятно, ожидали получить.