Оператор UPDATE перенесся в, ЕСЛИ СУЩЕСТВУЕТ блок

Я пытаюсь записать сценарий DML, который обновляет столбец, но я хотел удостовериться, что столбец существовал сначала, таким образом, я перенес его в, ЕСЛИ СУЩЕСТВУЕТ блок

IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='Client' AND COLUMN_NAME='IsClarityEnabled') 
BEGIN
    UPDATE Client SET IsClarityEnabled = 1 WHERE ClientID = 21
END

Таким образом, странность - то, что это пытается выполнить обновление, даже если это приводит условие к сбою. Таким образом, столбец не существует и выполнения оператора UPDATE, и я получаю ошибку. Почему?

Еще более странный то, что это действительно работает:

IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='Client' AND COLUMN_NAME='IsClarityEnabled') 
BEGIN
    EXEC('UPDATE Client SET IsClarityEnabled = 1 WHERE ClientID = 21')
END

Действительно ли там что-то является особенным о команде UPDATE, которая заставляет это вести себя этот путь?

5
задан gbn 2 May 2010 в 11:14
поделиться

2 ответа

Проблема в том, что сценарий будет скомпилирован / проанализирован, и если столбец не существует, вы получите ошибку компиляции / синтаксического анализа.

Недопустимое имя столбца 'IsClarityEnabled'.

6
ответ дан 14 December 2019 в 04:34
поделиться

он пытается выполнить обновление, даже если условие не выполняется

Вы уверены? Я подозреваю, что на самом деле происходит то, что SQL Server пытается разобрать UPDATE, независимо от значения условия. Поскольку разбор происходит до выполнения, во время разбора SQL Server не может "знать", что вы защитили этот UPDATE проверкой - разборщик знает только, что в IsClarityEnabled нет столбца Client, и поэтому он жалуется.

Причина, по которой EXEC работает так, как вы хотите, заключается прежде всего в том, что строковый литерал не обрабатывается парсером. Это стандартный способ создания сценариев, которые должны работать со схемой, неизвестной до момента выполнения.

2
ответ дан 14 December 2019 в 04:34
поделиться