SQL Server ПОПРОБУЕТ ЗАКЛЮЧИТЕЛЬНО

У меня есть сценарий, где мне нужно что-то похожее на .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

Ответы

Ответ 1

Вместо создания таблицы вы можете просто объявить переменную таблицы (которая автоматически исчезнет при завершении запроса).

BEGIN TRY
DECLARE @temp TABLE
(
    --columns
)
--do stuff
END TRY
BEGIN CATCH
--do other stuff
END CATCH

Ответ 2

В то время как не совсем то же, что и 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

Ответ 3

нет эквивалента FINALLY.
альтернативой могут быть переменные таблицы, но они не совсем одинаковы и должны оцениваться в каждом конкретном случае.
существует вопрос SO с подробными сведениями сделать осознанный выбор.
с переменными таблицы, которые вам не нужно очищать, как вы делаете с временными таблицами

Ответ 4

"FINALLY" часто, но не всегда, функционально идентичен тому, что "final" код следует за TRY/CATCH (без формального блока "FINALLY"). Иначе, это тот случай, когда что-то в блоках TRY/CATCH может привести к завершению выполнения, например, оператор return.

Например, шаблон, который я использовал, состоит в том, чтобы открыть курсор, а затем поместить код, использующий курсор, в блок TRY, а курсор закрыть/удалить после блока TRY/CATCH. Это прекрасно работает, если блоки не выходят из исполняемого кода. Однако, если блок TRY CATCH выполняет, например, RETURN (что звучит как плохая идея), если бы был блок FINALLY, он был бы выполнен, но с "окончательным" кодом, помещенным после TRY/CATCH, как T-SQL требует, чтобы в случае, если эти блоки кода приводят к завершению выполнения, окончательный код не будет вызываться, что может привести к несогласованному состоянию.

Так что, хотя очень часто вы можете просто поместить код после TRY/CATCH, это будет проблемой, если что-то в этих блоках может завершиться без перехода к коду очистки.

Ответ 5

Локальные временные таблицы (например, "#Temp") автоматически удаляются при завершении соединения SQL. В любом случае рекомендуется включать явную команду DROP, но если она не будет выполнена, таблица все равно будет удалена.

Если вы должны убедиться, что DROP выполняется как можно скорее, вам придется повторить команду DROP в предложении CATCH, так как нет FINALLY: - создайте временную таблицу; BEGIN TRY - использовать временную таблицу; - удалить временную таблицу; END TRY BEGIN CATCH - удалить временную таблицу; БРОСИТЬ; - сбросить ошибку END CATCH

Табличные переменные являются альтернативой: они удаляются, когда переменная выходит из области видимости. Однако табличные переменные не поддерживают статистику, поэтому, если табличная переменная велика и используется в нескольких запросах, она может работать не так хорошо, как временная таблица.