Ответ 1
Вместо создания таблицы вы можете просто объявить переменную таблицы (которая автоматически исчезнет при завершении запроса).
BEGIN TRY
DECLARE @temp TABLE
(
--columns
)
--do stuff
END TRY
BEGIN CATCH
--do other stuff
END CATCH
У меня есть сценарий, где мне нужно что-то похожее на .NET try-catch-finally block.
На моей попытке, я CREATE a #temp table
, INSERT
в него данные и процессе других наборов данных на основе #temp
.
На CATCH
затем RAISERROR
. Возможно ли иметь FINALLY
блок для DROP #temp
? Ниже псевдокод:
BEGIN TRY
CREATE TABLE #temp
(
--columns
)
--Process data with other data sets
END TRY
BEGIN CATCH
EXECUTE usp_getErrorMessage
END CATCH
BEGIN FINALLY
DROP TABLE #temp
END FINALLY
Вместо создания таблицы вы можете просто объявить переменную таблицы (которая автоматически исчезнет при завершении запроса).
BEGIN TRY
DECLARE @temp TABLE
(
--columns
)
--do stuff
END TRY
BEGIN CATCH
--do other stuff
END CATCH
В то время как не совсем то же, что и FINALLY, версия Try-Catch T-SQL позволяет этот код, который нуждается в выполнении после того, как блоки Try и Catch могут появиться после завершения инструкции END CATCH. Использование кода вопроса в качестве примера:
BEGIN TRY
CREATE TABLE #temp
(
--columns
)
--Process data with other data sets
END TRY
BEGIN CATCH
EXECUTE usp_getErrorMessage
END CATCH;
IF OBJECT_ID('tempdb..#temp') IS NOT NULL -- Check for table existence
DROP TABLE #temp;
Команда DROP TABLE будет выполнять выполнение Try или Catch. Смотрите: BOL Try... Catch
нет эквивалента FINALLY
.
альтернативой могут быть переменные таблицы, но они не совсем одинаковы и должны оцениваться в каждом конкретном случае.
существует вопрос SO с подробными сведениями сделать осознанный выбор.
с переменными таблицы, которые вам не нужно очищать, как вы делаете с временными таблицами
"FINALLY" часто, но не всегда, функционально идентичен тому, что "final" код следует за TRY/CATCH (без формального блока "FINALLY"). Иначе, это тот случай, когда что-то в блоках TRY/CATCH может привести к завершению выполнения, например, оператор return.
Например, шаблон, который я использовал, состоит в том, чтобы открыть курсор, а затем поместить код, использующий курсор, в блок TRY, а курсор закрыть/удалить после блока TRY/CATCH. Это прекрасно работает, если блоки не выходят из исполняемого кода. Однако, если блок TRY CATCH выполняет, например, RETURN (что звучит как плохая идея), если бы был блок FINALLY, он был бы выполнен, но с "окончательным" кодом, помещенным после TRY/CATCH, как T-SQL требует, чтобы в случае, если эти блоки кода приводят к завершению выполнения, окончательный код не будет вызываться, что может привести к несогласованному состоянию.
Так что, хотя очень часто вы можете просто поместить код после TRY/CATCH, это будет проблемой, если что-то в этих блоках может завершиться без перехода к коду очистки.
Локальные временные таблицы (например, "#Temp") автоматически удаляются при завершении соединения SQL. В любом случае рекомендуется включать явную команду DROP, но если она не будет выполнена, таблица все равно будет удалена.
Если вы должны убедиться, что DROP выполняется как можно скорее, вам придется повторить команду DROP в предложении CATCH, так как нет FINALLY: - создайте временную таблицу; BEGIN TRY - использовать временную таблицу; - удалить временную таблицу; END TRY BEGIN CATCH - удалить временную таблицу; БРОСИТЬ; - сбросить ошибку END CATCH
Табличные переменные являются альтернативой: они удаляются, когда переменная выходит из области видимости. Однако табличные переменные не поддерживают статистику, поэтому, если табличная переменная велика и используется в нескольких запросах, она может работать не так хорошо, как временная таблица.