Поделиться через


UPDATE (Transact-SQL)

Изменяет существующие данные в одном или нескольких столбцах таблицы или представления SQL Server 2008.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

[ WITH common_table_expression [...n] ]
UPDATE 
    [ TOP (expression) [ PERCENT ] ] 
    { { table_alias | <object> | rowset_function_limited

        [ WITH (table_hint_limited [ ...n ] ) ]
      }
      | @table_variable
    }
    SET
        { column_name= { expression | DEFAULT | NULL }
          | { udt_column_name.{ { property_name=expression
                                | field_name=expression }
                                | method_name(argument [ ,...n ] )
                              }
          }
          | column_name { .WRITE (expression,@Offset,@Length) }
          | @variable=expression
          | @variable=column=expression
          | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable=column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
        } [ ,...n ] 

    [ OUTPUT clause ]
    [ FROM { table_source } [ ,...n ] ] 
    [ WHERE { search_condition

            | { [ CURRENT OF 
                  { { [ GLOBAL ] cursor_name } 
                      | cursor_variable_name

                  } 
                ]
              }
            } 
    ] 
    [ OPTION (query_hint [ ,...n ] ) ]
[ ; ]

<object> ::=
{ 
    [ server_name .database_name.schema_name.

    | database_name .[ schema_name ] .

    | schema_name.
    ]
    table_or_view_name
}

Аргументы

  • WITH common_table_expression
    Задает временный именованный результирующий набор или представление, которые называются обобщенным табличным выражением (CTE), определяемым в пределах области действия инструкции UPDATE. Результирующий набор наследуется от инструкции SELECT и используется в инструкции UPDATE. Дополнительные сведения см. в разделе WITH обобщенное_табличное_выражение (Transact-SQL).

  • TOP ( expression) [ PERCENT ]
    Указывает количество или процент строк, которые будут обновлены. expression может быть либо числом, либо процентной долей строк. Строки, на которые ссылается выражение TOP, используемое с инструкцией INSERT, UPDATE, MERGE или DELETE, не располагаются в каком-либо определенном порядке.

    В инструкциях INSERT, UPDATE и DELETE необходимы скобки, в которые заключается expression. Дополнительные сведения см. в разделе TOP (Transact-SQL).

  • table_alias
    Псевдоним, указанный в предложении FROM и представляющий таблицу или представление, строки которого будут обновлены.

  • server_name
    Имя связанного сервера, на котором расположена таблица или индексированное представление. Аргумент server_name можно задавать в виде имени связанного сервера или с помощью функции OPENDATASOURCE.

    Если аргумент server_name задается в виде связанного сервера, то необходимы аргументы database_name и schema_name. Если аргумент server_name задается с помощью функции OPENDATASOURCE, то аргументы database_name и schema_name могут применяться не ко всем источникам данных, в зависимости от возможностей поставщика OLE DB, который обращается к удаленному объекту. Дополнительные сведения см. в разделе Распределенные запросы.

  • database_name
    Имя базы данных.

  • schema_name
    Имя схемы, которой принадлежит таблица или представление.

  • table_or view_name
    Имя таблицы или представления, из которых должны обновляться строки.

    Представление, указываемое параметром table_or_view_name, должно быть обновляемым и ссылаться на только одну базовую таблицу из предложения FROM в определении представления. Дополнительные сведения об обновляемых представлениях см. в разделе CREATE VIEW (Transact-SQL).

  • rowset_function_limited
    Либо функция OPENQUERY, либо функция OPENROWSET. Использование этих функций зависит от возможностей поставщика OLE DB, который обращается к удаленному объекту. Дополнительные сведения см. в разделе Распределенные запросы.

  • WITH (table_hint_limited)
    Указывает одну или несколько табличных подсказок, допустимых для целевой таблицы. Табличные подсказки переопределяют стандартное поведение оптимизатора запросов для длительности инструкции UPDATE. Использование аргументов NOLOCK и READUNCOMMITTED запрещено. Сведения о табличных подсказках см. в разделе Табличные подсказки (Transact-SQL).

  • @table\_variable
    Задает переменную table в качестве табличного источника.

  • SET
    Указывает список столбцов или имена переменных, которые нужно обновить.

  • column_name
    Столбец, содержащий обновляемые данные. Столбец с именем column_name должен существовать в table_or view_name. Столбцы идентификаторов обновлять нельзя.

  • expression
    Переменная, литеральное значение, выражение или вложенный запрос выборки (заключенный в скобки), которые возвращают единственное значение. Значение, возвращаемое expression, заменяет существующее значение в column_name или @variable.

    ПримечаниеПримечание

    При ссылке на типы данных символов Юникода nchar, nvarchar и ntext «выражение» должно начинаться с заглавной буквы «N». Если префикс «N» не указан, SQL Server выполнит преобразование строки в кодовую страницу, соответствующую параметрам сортировки базы данных или столбца, действующим по умолчанию. Любые символы, не входящие в эту кодовую страницу, будут утрачены. Дополнительные сведения см. в разделе Использование данных в Юникоде.

  • DEFAULT
    Указывает, что существующее в столбце значение будет заменено значением по умолчанию, определенным для данного столбца. Данный аргумент можно также использовать для изменения значения столбца на NULL, если для него не определено значение по умолчанию и разрешены нулевые значения.

  • { += | -= | *= | /= | %= | &= | ^= | |= }
    Составной оператор, который служит для выполнения операции и установки исходного значения в результат операции.

    +=    Сложить и присвоить

    -=    Вычесть и присвоить

    *=    Умножить и присвоить

    /=    Разделить и присвоить

    %=    Получить остаток от деления и присвоить

    &=    Выполнить битовое И и присвоить

    ^=    Выполнить битовое исключающее ИЛИ и присвоить

    |=    Выполнить битовое ИЛИ и присвоить

    Дополнительные сведения см. в разделе Составные операторы (Transact-SQL).

  • udt_column_name
    Столбец определяемого пользователем типа.

  • property_name | field_name
    Общедоступное свойство или общедоступный элемент данных определяемого пользователем типа. Выражение, предоставляющее значение, должно допускать неявное преобразование в тип свойства.

    Для изменения различных свойств одного и того же столбца определяемого пользователем типа нужно выполнить несколько инструкций UPDATE или использовать метод мутатора соответствующего типа.

  • method_name( argument [ ,... n] )
    Нестатический общий метод мутатора udt_column_name, принимающий один или несколько аргументов. SQL Server возвращает ошибку, если метод мутатора вызывается со значением Transact-SQL, равным NULL, либо если новое значение, возвращенное методом мутатора, равно null.

  • .WRITE (expression,@Offset, @Length)
    Указывает, что должен быть изменен раздел значения column_name. expression заменяет в column_name@Length элементы, начиная с позиции @Offset. С этим предложением можно указывать только столбцы типа varchar(max), nvarchar(max) или varbinary(max). column_name не может иметь значения NULL и не может дополняться именем таблицы или псевдонимом таблицы.

    expression — значение, которое копируется в столбец column_name. Аргумент expression должен иметь результат типа column_name или неявно приводиться к этому типу. Если для expression установлено значение NULL, аргумент @Length не учитывается, а значение в column_name усекается с позиции, на которую указывает аргумент @Offset.

    Аргумент @Offset — начальная точка в значении column_name, в которую записывается значение expression. Аргумент @Offset — отсчитываемая от нуля порядковая позиция с типом данных bigint и не может быть отрицательным числом. Если аргумент @Offset имеет значение NULL, операция обновления добавляет значение expression в конец существующего значения аргумента column_name, а аргумент @Length пропускается. Если значение аргумента @Offset больше, чем длина значения аргумента column_name, компонент Database Engine возвращает ошибку. Если сумма значений @Offset и @Length превышают длину базового значения столбца, удаление выполняется до последнего символа этого значения. Если сумма значений @Offset и LEN(expression) больше чем базовый объявленный размер, возникает ошибка.

    @Length — это длина раздела в столбце, начиная с @Offset, который заменяется expression. @Length имеет тип данных bigint и не может принимать отрицательных значений. Если аргумент @Length имеет значение NULL, операция обновления удаляет все данные, со значения @Offset до конца значения column_name.

    Дополнительные сведения см. в разделе «Обновление типов данных большого объема».

  • @variable
    Объявленная переменная, которой присваивается значение, возвращенное expression.

    SET @variable = column = expression присваивает переменной то же значение, что и столбцу. Это отличается от предложения SET @variable = column, column = expression, присваивающего переменной значение столбца до обновления.

  • OUTPUT_clause
    Возвращает обновленные данные или основанные на них выражения в рамках выполнения операции UPDATE. Предложение OUTPUT не поддерживается инструкциями DML, выполняемыми для локальных секционированных представлений, распределенных секционированных представлений, удаленных таблиц или представлений. Дополнительные сведения см. в разделе Предложение OUTPUT (Transact-SQL).

  • FROM table_source
    Определяет, что в качестве источника для определения критериев операции обновления используется таблица, представление или производная таблица. Дополнительные сведения см. в разделе Предложение FROM (Transact-SQL).

    Если обновляемый объект тот же самый, что и объект в предложении FROM, и в предложении FROM имеется только одна ссылка на этот объект, псевдоним объекта указывать необязательно. Если обновляемый объект встречается в предложении FROM несколько раз, одна и только одна ссылка на этот объект не должна указывать псевдоним таблицы. Все остальные ссылки на объект в предложении FROM должны включать псевдоним объекта.

  • WHERE
    Указывает условия ограничения обновляемых строк. Существует два вида обновлений, в зависимости от используемой формы предложения WHERE.

    • В поисковых обновлениях задается условие поиска строк, предназначенных к удалению.

    • В позиционных обновлениях используется предложение CURRENT OF для указания курсора. Операция обновления выполняется в текущем положении курсора. Позиционированное обновление с использованием предложения WHERE CURRENT OF обновляет единственную строку в текущем положении курсора. Такое обновление может быть более точным, чем поисковое обновление, в котором для выбора строк используется предложение WHERE <search_condition>. Если условие поиска не определяет однозначно единственную строку, поисковое обновление изменяет несколько строк.

  • search_condition
    Указывает условия, которым должны соответствовать строки для обновления. Условие поиска может также представлять собой условие, на котором основано соединение. Количество предикатов, которое может содержать условие поиска, не ограничено. Дополнительные сведения о предикатах и условиях поиска см. в разделе Условие поиска (Transact-SQL).

  • CURRENT OF
    Определяет, что обновление выполняется в текущей позиции указанного курсора.

  • GLOBAL
    Указывает, что аргумент cursor_name ссылается на глобальный курсор.

  • cursor_name
    Имя открытого курсора, из которого должна быть произведена выборка. Если существует как глобальный, так и локальный курсор с именем cursor_name, то, когда указывается GLOBAL, этот аргумент указывает на глобальный курсор, в противном случае на локальный курсор. Курсор должен позволять производить обновления.

  • cursor_variable_name
    Имя переменной курсора. Аргумент cursor_variable_name должен ссылаться на курсор, разрешающий обновления.

  • OPTION (query_hint [ ,... n ] )
    Определяет, что для настройки способа, которым компонент Database Engine обрабатывает инструкцию, используются подсказки оптимизатора. Дополнительные сведения см. в разделе Подсказки в запросах (Transact-SQL).

Рекомендации

В инструкции UPDATE можно использовать имена переменных для показа старых и новых значений, но только в том случае, если инструкция UPDATE обрабатывает одну запись. Если инструкция UPDATE затрагивает несколько записей, то для возврата старого и нового значений для каждой из записей пользуйтесь предложением OUTPUT.

Проявляйте осторожность, указывая предложение FROM при задании критериев для операции обновления. Результаты инструкции UPDATE не определены, если инструкция включает предложение FROM, в котором для каждого вхождения обновляемого столбца не задано единственное значение, то есть если инструкция UPDATE не является детерминированной. Это может привести к непредвиденным результатам. Например, в инструкции UPDATE в следующем скрипте обе строки таблицы Table1 удовлетворяют условиям предложения FROM. Поэтому неясно, какая строка таблицы Table1 должна использоваться для обновления строки таблицы Table2.

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1 
    (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2 
    (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10.0), (1, 20.0);
INSERT INTO dbo.Table2 VALUES (1, 0.0);
;
GO

UPDATE dbo.Table2 
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2 
    INNER JOIN dbo.Table1 
    ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB 
FROM dbo.Table2;

То же самое может произойти при сочетании предложений FROM и WHERE CURRENT OF. В следующем примере обе строки таблицы Table2 удовлетворяют условиям предложения FROM в инструкции UPDATE. Не определено, какая строка из Table2 должна использоваться для обновления строки в Table1.

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
    (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
    (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20), (2, 30);
GO

DECLARE abc CURSOR LOCAL FOR
    SELECT c1, c2 
    FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1 
SET c2 = c2 + d2 
FROM dbo.Table2 
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO

Типы данных

Все столбцы типов char и nchar дополняются справа до заданной длины.

Если ANSI_PADDING имеет значение OFF, все конечные пробелы удаляются из данных, вставленных в столбцы varchar и nvarchar, за исключением строк, содержащих только пробелы. Эти строки усекаются до пустых строк. Если ANSI_PADDING имеет значение ON, вставляются конечные пробелы. Драйвер ODBC для Microsoft SQL Server и поставщик OLE DB для SQL Server автоматически устанавливают ANSI_PADDING ON для каждого соединения. Этот параметр можно настроить в источниках данных ODBC или устанавливая атрибуты или свойства соединений. Дополнительные сведения см. в разделе SET ANSI_PADDING (Transact-SQL).

Обновление типов данных большого объема

Для частичного или полного обновления типов данных varchar(max), nvarchar(max) и varbinary(max) используется предложение .WRITE (expression, @Offset,@Length). Например, частичное обновление столбца с типом varchar(max) может удалить или изменить только первые 200 символов, тогда как полное обновление удалит или изменит все данные в столбце.

В целях увеличения производительности рекомендуется вставлять или обновлять данные фрагментами, кратными 8040 байтам.

Компонент Database Engine преобразует частичное обновление в полное, если инструкция UPDATE приводит к одному из следующих действий.

  • Изменению ключевого столбца секционированного представления или таблицы.

  • Изменению более чем одной строки, а также к обновлению ключа неуникального кластеризованного индекса на непостоянное значение.

Нельзя использовать предложение . WRITE для обновления столбца NULL или для присваивания аргументу column_name значения NULL.

Параметры @Offset и @Length указываются в байтах для типов данных varbinary и varchar и в символах для типа данных nvarchar. Соответствующие смещения вычисляются для параметров сортировки в двухбайтовых кодировках (DBCS).

Если на столбец, изменяемый предложением .WRITE, ссылается предложение OUTPUT, то указанному столбцу в табличной переменной возвращается полное значение данного столбца в первоначальном образе deleted.column_name или в последующем образе inserted.column_name.

Чтобы добиться функциональности предложения .WRITE при обработке других символьных или двоичных типов данных, используется STUFF (Transact-SQL).

Обновление данных FILESTREAM

Инструкция UPDATE позволяет обновить поля FILESTREAM значением NULL, пустым значением или встроенными данными относительно небольшого размера. Однако при работе с большими объемами данных более эффективно передавать поток в файл с использованием интерфейсов Win32. При обновлении поля FILESTREAM происходит изменение базовых данных BLOB в файловой системе. Если в поле FILESTREAM содержится значение NULL, данные BLOB, связанные с этим полем, удаляются. Для частичного обновления данных потока FILESTREAM недопустимо использовать метод .WRITE(). Дополнительные сведения см. в разделе Общие сведения о FILESTREAM.

Обновление столбцов типа text, ntext и image

Изменение столбцов типа text, ntext или image с помощью инструкции UPDATE инициализирует столбец, присваивает ему допустимый текстовый указатель и выделяет по крайней мере одну страницу данных, если столбец не обновляется значением NULL. Если инструкция UPDATE могла обновить несколько строк при обновлении как кластеризованного ключа, так и одного или нескольких столбцов типа text, ntext или image, частичное обновление этих столбцов выполняется как полная замена значений.

Чтобы заменить или изменить большие блоки данных типов text, ntext или image, вместо UPDATE используется инструкция WRITETEXT или UPDATETEXT.

Важное примечаниеВажно!

Типы данных ntext, text и image будут удалены в следующей версии MicrosoftSQL Server. Следует избегать использования этих типов данных при новой разработке и запланировать изменение приложений, использующих их в настоящий момент. Вместо них следует использовать типы данных nvarchar(max), varchar(max) и varbinary(max). Дополнительные сведения см. в разделе Использование типов данных больших значений.

Обработка ошибок

Для инструкции UPDATE можно реализовать обработку ошибок, заключив ее в конструкцию TRY…CATCH. Дополнительные сведения см. в разделе Использование конструкции TRY...CATCH в языке Transact-SQL.

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

Если инструкция UPDATE при вычислении выражения встречает арифметическую ошибку (переполнение, деление на ноль или ошибку домена), обновление не выполняется. Остальная часть пакета не выполняется и возвращается сообщение об ошибке.

Если обновление столбца или столбцов, участвующих в кластеризованном индексе, приводит к тому, что размер кластеризованного индекса и строки превышает 8 060 байт, то обновление заканчивается неудачей и возвращается сообщение об ошибке.

Совместимость

Инструкции UPDATE разрешается использовать в теле определяемых пользователем функций только в том случае, если изменяемая таблица является табличной переменной.

Если для операций UPDATE по отношению к таблице определен триггер INSTEAD OF, вместо инструкции UPDATE запускается этот триггер. Ранние версии SQL Server поддерживали для UPDATE и других инструкций изменения данных только определение триггеров AFTER.

Ограничения

В инструкции UPDATE, которая прямо или косвенно ссылается на представление с определенным для него триггером INSTEAD OF, не может быть указано предложение FROM. Дополнительные подробности о триггерах INSTEAD OF см. в разделе CREATE TRIGGER (Transact-SQL).

Значение параметра SET ROWCOUNT не учитывается инструкциями UPDATE для удаленных таблиц и для локальных и удаленных секционированных представлений. Параметр SET ROWCOUNT не будет оказывать влияние на инструкции UPDATE в следующей версии SQL Server. В новых разработках следует избегать совместного использования инструкций SET ROWCOUNT и UPDATE. Также необходимо изменить существующие приложения и использовать синтаксис TOP.

Если обобщенное табличное выражение указывается в качестве объекта инструкции UPDATE, должны совпадать все ссылки на это выражение в инструкции. Например, если для обобщенного табличного выражения в предложении FROM назначается псевдоним, то этот псевдоним должен использоваться для всех остальных ссылок на обобщенное табличное выражение. Однозначные ссылки на обобщенное табличное выражение необходимы в силу того, что обобщенное табличное выражение не имеет идентификатора объекта, который используется SQL Server для обнаружения неявной связи между объектом и псевдонимом. В отсутствие такой связи план запроса может непредвиденным образом построить работу с соединениями, что приведет к нежелательным результатам запроса. В следующих примерах показаны верные и неверные методы задания обобщенного табличного выражения, когда оно является целевым объектом операции обновления.

USE tempdb;
GO
-- UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE x -- cte is referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO

Ниже приводится результирующий набор.

ID     Value

------ -----

1      100

2      200

(2 row(s) affected)

-- UPDATE statement with CTE references that are incorrectly matched.
USE tempdb;
GO
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE cte   -- cte is not referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID; 
SELECT * FROM @x; 
GO

Ниже приводится результирующий набор.

ID     Value

------ -----

1      100

2      100

(2 row(s) affected)

Режим ведения журнала

Инструкция UPDATE протоколируется полностью, однако обновления с помощью метода .WRITE, вставляющие или присоединяющие новые данные, протоколируются на минимальном уровне, если установлена простая модель восстановления базы данных или модель восстановления с неполным протоколированием. Протоколирование не сокращается до минимума, если при помощи метода .WRITE обновляются существующие значения. Дополнительные сведения см. в разделе Операции, для которых возможно минимальное протоколирование.

Безопасность

Разрешения

Требуются разрешения на выполнение UPDATE в целевой таблице. Также требуются разрешения на выполнение SELECT для обновляемой таблицы, если инструкция UPDATE содержит предложение WHERE или если аргумент expression в предложении SET использует столбец в этой таблице.

Разрешения UPDATE по умолчанию предоставляются членам предопределенной роли сервера sysadmin, членам предопределенных ролей баз данных db_owner и db_datawriter, а также владельцу таблицы. Члены ролей sysadmin, db_owner и db_securityadmin, а также владелец таблицы могут передавать разрешения другим пользователям.

Примеры

Категория

Используемые элементы синтаксиса

Базовый синтаксис

UPDATE

Ограничение обновляемых строк

WHERE • TOP • WITH обобщенное табличное выражение • WHERE CURRENT OF

Установка значений столбцов

вычисляемые значения • составные операторы • значения по умолчанию • вложенные запросы

Указание целевых объектов, не являющихся стандартными таблицами

представления • табличные переменные • псевдонимы таблиц

Обновление данных на основе данных из других таблиц

FROM

Обновление строк в удаленной таблице

связанный сервер • OPENQUERY • OPENDATASOURCE

Обновление типов данных больших объектов

.WRITE • OPENROWSET

Обновление определяемых пользователем типов данных

определяемые пользователем типы

Переопределение стандартных действий, выполняемых оптимизатором запросов, с помощью подсказок

табличные подсказки • подсказки в запросах

Сбор результатов инструкции UPDATE

OUTPUT, предложение

Использование инструкции UPDATE в других инструкциях

хранимые процедуры • TRY…CATCH

Базовый синтаксис

В примерах из этого раздела показаны основные функции инструкции UPDATE и используется минимально необходимый синтаксис.

А. Использование простой инструкции UPDATE

В следующем примере обновляется статистика для одного столбца во всех строках таблицы Person.Address.

USE AdventureWorks;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();

Б. Обновление нескольких столбцов

В следующем примере выполняется обновление значений в столбцах Bonus, CommissionPct и SalesQuota для всех строк в таблице SalesPerson.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO

Ограничение обновляемых строк

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

А. Применение предложения WHERE

В следующем примере предложение WHERE используется для указания строк, которые необходимо обновить. Инструкция обновляет значение в столбце Color таблицы Production.Product для всех строк, где в столбце Color существует значение «Red» и имеются значения столбца Name, начинающиеся с «Road-250».

USE AdventureWorks;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO

Б. Использование предложения TOP

В следующих примерах предложение TOP служит для ограничения числа строк, изменяемых в процессе выполнения инструкции UPDATE. Если в инструкции UPDATE указано предложение TOP (n), то операция обновления будет выполнена над произвольным подмножеством в n строк. В следующем примере столбец VacationHours в таблице Employee обновляется на 25 % для 10 произвольных строк.

USE AdventureWorks;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO

Если необходимо применить изменения с предложением TOP в определенной последовательности, укажите во вложенном запросе SELECT предложение ORDER BY. В следующем примере изменяется длительность отпуска для 10 сотрудников, имеющих наибольший стаж работы.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 EmployeeID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.EmployeeID = th.EmployeeID;
GO

В. Использование предложения WITH обобщенное_табличное_выражение

В следующем примере обновляется на 25 процентов значение VacationHours для всех работников, прямо или косвенно подчиняющихся ManagerID12. Обобщенное табличное выражение возвращает иерархический список работников, подчиняющихся непосредственно ManagerID12, а также работников, подчиняющихся этим работниками и т. д. Модифицируются только строки, возвращенные обобщенным табличным выражением. Дополнительные сведения о рекурсивных обобщенных табличных выражениях см. в разделе Рекурсивные запросы, использующие обобщенные табличные выражения.

USE AdventureWorks;
GO
WITH DirectReports(EmployeeID, NewVacationHours, EmployeeLevel)
AS
(SELECT e.EmployeeID, e.VacationHours, 1
  FROM HumanResources.Employee AS e
  WHERE e.ManagerID = 12
  UNION ALL
  SELECT e.EmployeeID, e.VacationHours, EmployeeLevel + 1
  FROM HumanResources.Employee as e
  JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
UPDATE HumanResources.Employee
SET VacationHours = VacationHours * 1.25
FROM HumanResources.Employee AS e
JOIN DirectReports AS d ON e.EmployeeID = d.EmployeeID;
GO

Г. Использование предложения WHERE CURRENT OF.

В следующем примере предложение WHERE CURRENT OF служит для обновления только одной строки, на которой позиционирован курсор. Если курсор основан на соединении, изменяется только table_name, указанное в инструкции UPDATE. Другие таблицы, участвующие в курсоре, не затрагиваются.

USE AdventureWorks;
GO
DECLARE complex_cursor CURSOR FOR
    SELECT a.EmployeeID
    FROM HumanResources.EmployeePayHistory AS a
    WHERE RateChangeDate <> 
         (SELECT MAX(RateChangeDate)
          FROM HumanResources.EmployeePayHistory AS b
          WHERE a.EmployeeID = b.EmployeeID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2 
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO

Установка значений столбцов

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

А. Указание вычисляемого значения

В следующем примере используются вычисляемые значения в инструкции UPDATE. В следующем примере удваивается значение столбца ListPrice для всех строк в таблице Product.

USE AdventureWorks ;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO

Б. Указание составных операторов

В следующем примере демонстрируется использование переменной @NewPrice для увеличения цены красных велосипедов прибавлением 10 к текущей цене.

USE AdventureWorks;
GO
DECLARE @NewPrice int = 10;
UPDATE Production.Product
SET ListPrice += @NewPrice
WHERE Color = N'Red';
GO

В следующем примере составной оператор += добавляет данные ' - tool malfunction' к значению столбца Name в тех строках, где значение ScrapReasonID находится в диапазоне от 10 до 12.

USE AdventureWorks;
GO
UPDATE Production.ScrapReason 
SET Name += ' - tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;

В. Указание вложенного запроса в предложении SET

В следующем примере вложенный запрос в предложении SET определяет значение, используемое для обновления столбца. Вложенный запрос должен возвращать скалярное значение (одно значение на строку). В следующем примере изменяется столбец SalesYTD в таблице SalesPerson, отражая последние данные о продажах, зарегистрированные в таблице SalesOrderHeader. Вложенные запросы собирают сведения о продажах по всем менеджерам в инструкции UPDATE.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = 
                                 so.SalesPersonID)
     AND Sales.SalesPerson.SalesPersonID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

Г. Обновление строк значениями по умолчанию

В следующем примере столбец CostRate устанавливается в значение по умолчанию (0,00) для всех строк, в которых значение CostRate превышает 20.00.

USE AdventureWorks;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;

Указание целевых объектов, не являющихся стандартными таблицами

В примерах из этого раздела показаны способы обновления строк указанием представления, псевдонима таблицы или табличной переменной.

А. Указание представления в качестве целевого объекта

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

USE AdventureWorks;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';

Б. Указание псевдонима таблицы в качестве целевого объекта

В следующем примере производится обновление строк в таблице Production.ScrapReason. Псевдоним таблицы, присвоенный в ScrapReason в предложении FROM, указан как целевой объект в предложении UPDATE.

USE AdventureWorks;
GO
UPDATE sr
SET sr.Name += ' - tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo 
     ON sr.ScrapReasonID = wo.ScrapReasonID
     AND wo.ScrappedQty > 300;

В. Указание табличной переменной в качестве целевого объекта

В следующем примере производится обновление строк в табличной переменной.

USE AdventureWorks;
GO
-- Create the table variable.
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    NewVacationHours int,
    ModifiedDate datetime);

-- Populate the table variable with employee ID values from HumanResources.Employee.
INSERT INTO @MyTableVar (EmpID)
    SELECT EmployeeID FROM HumanResources.Employee;

-- Update columns in the table variable.
UPDATE @MyTableVar
SET NewVacationHours = e.VacationHours + 20,
    ModifiedDate = GETDATE()
FROM HumanResources.Employee AS e 
WHERE e.EmployeeID = EmpID;

-- Display the results of the UPDATE statement.
SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar
ORDER BY EmpID;
GO

Обновление данных на основе данных из других таблиц

Примеры в этом разделе показывают способы обновления строк из одной таблицы на основе данных из другой таблицы.

А. Использование инструкции UPDATE с данными из другой таблицы

В следующем примере изменяется столбец SalesYTD в таблице SalesPerson для отображения самой последней информации о продажах, зафиксированной в таблице SalesOrderHeader.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
    ON sp.SalesPersonID = so.SalesPersonID
    AND so.OrderDate = (SELECT MAX(OrderDate)
                        FROM Sales.SalesOrderHeader 
                        WHERE SalesPersonID = 
                              sp.SalesPersonID);
GO

В предыдущем примере подразумевается, что на конкретного менеджера по продажам на каждую конкретную дату записана только одна продажа и что выполнены все текущие обновления. Если в один и тот же день для указанного менеджера может быть записано более одной продажи, приведенный пример будет работать неправильно. Пример выполняется без ошибок, но каждое из значений SalesYTD обновляется только для одной из продаж, вне зависимости от действительного количества продаж в этот день. Это происходит потому, что инструкция UPDATE при простом обновлении никогда не обновляет одну и ту же строку дважды.

В ситуации, когда у данного менеджера по продажам имеется несколько продаж в день, все продажи для каждого из менеджеров по продажам должны быть собраны вместе инструкцией UPDATE, как показано в следующем примере.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = 
                                 so.SalesPersonID)
     AND Sales.SalesPerson.SalesPersonID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

Обновление строк в удаленной таблице

В примерах из этого раздела показано, как обновлять строки в удаленной целевой таблице с помощью связанного сервера или функции набора строк, ссылающихся на удаленную таблицу.

А. Обновление данных в удаленной таблице с помощью связанного сервера

В следующем примере производится обновление таблицы на удаленном сервере. Сначала в примере создается ссылка на удаленный источник данных с помощью процедуры sp_addlinkedserver. Затем имя связанного сервера MyLinkServer указывается в четырехкомпонентном имени объекта в следующем формате: сервер.каталог.схема.объект. Обратите внимание, что для @datasrc необходимо указать действующее имя сервера.

USE master;
GO
-- Create a link to the remote data source. 
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.

EXEC sp_addlinkedserver @server = N'MyLinkServer',
    @srvproduct = N' ',
    @provider = N'SQLNCLI10', 
    @datasrc = N'<server name>',
    @catalog = N'AdventureWorks';
GO
USE AdventureWorks;
GO
-- Specify the remote data source using a four-part name 
-- in the form linked_server.catalog.schema.object.

UPDATE MyLinkServer.AdventureWorks.HumanResources.Department
SET GroupName = N'Public Relations'
WHERE DepartmentID = 4;

Б. Обновление данных в удаленной таблице с помощью функции OPENQUERY

В следующем примере обновляется строка в удаленной таблице путем указания функции набора строк OPENQUERY. В этом примере используется имя связанного сервера, созданного в предыдущем примере.

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

Г. Обновление данных в удаленной таблице с помощью функции OPENDATASOURCE

В следующем примере вставляется строка в удаленную таблицу путем указания функции набора строк OPENDATASOURCE. Укажите действительное имя сервера для источника данных в формате имя_сервера или имя_сервера\имя_экземпляра. Может потребоваться настройка параметра Ad Hoc Distributed Queries на экземпляре SQL Server. Дополнительные сведения см. в разделе Параметр ad hoc distributed queries.

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

Обновление типов данных больших объектов

Примеры в этом разделе показывают способы обновления значений в столбцах, имеющих тип данных больших объектов (LOB).

А. Использование инструкции UPDATE с предложением .WRITE для изменения данных в столбце nvarchar(max)

В следующем примере предложение .WRITE используется для обновления частичного значения столбца DocumentSummary типа nvarchar(max) в таблице Production.Document . Слово components заменяется словом features путем указания слова для замены, начального положения (смещения) заменяемого слова в существующих данных и количества заменяемых символов (длины). В этом примере также используется предложение OUTPUT, возвращающее изображения до и после выполнения операции в столбце DocumentSummary в табличную переменную @MyTableVar.

USE AdventureWorks;
GO
DECLARE @MyTableVar table (
    DocumentID int NOT NULL,
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT inserted.DocumentID,
       deleted.DocumentSummary, 
       inserted.DocumentSummary 
    INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

Г. Использование UPDATE с предложением .WRITE для добавления и удаления данных в столбце типа nvarchar(max)

В следующем примере данные добавляются в столбец nvarchar(max), имеющий текущее значение NULL, или и удаляются из него. Поскольку предложение .WRITE не может использоваться для изменения столбца со значением NULL, этот столбец сначала заполняется временными данными. Затем они заменяются правильными данными с помощью предложения .WRITE. В дополнительных примерах данные добавляются в конец значения столбца, удаляются из столбца (усекаются) и, наконец, удаляются частичные данные из столбца. Инструкции SELECT выводят на экран изменения данных, создаваемые каждой из инструкций UPDATE.

USE AdventureWorks;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE DocumentID = 1;
GO

SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Replacing temporary data with the correct data. Setting @Length to NULL 
-- truncates all existing data from the @Offset position.
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL)
WHERE DocumentID = 1;
GO

SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

-- Appending additional data to the end of the column by setting 
-- @Offset to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0)
WHERE DocumentID = 1;
GO

SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

-- Removing all data from @Offset to the end of the existing value by 
-- setting expression to NULL. 
UPDATE Production.Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE DocumentID = 1;
GO

SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE DocumentID = 1;
GO

SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

В. Использование инструкции UPDATE с функцией OPENROWSET для изменения столбца типа varbinary(max)

В следующем примере существующее изображение в столбце varbinary(max) заменяется новым изображением. Функция OPENROWSET используется с параметром BULK для загрузки изображения в столбец. В этом примере предполагается, что по заданному пути существует файл с именем Tires.jpg.

USE AdventureWorks;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
    SELECT *
    FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO

Г. Использование инструкции UPDATE для обновления данных FILESTREAM

В следующем примере инструкция UPDATE используется для изменения данных в файле, находящемся в файловой системе. Не рекомендуется пользоваться этим методом для выгрузки в файл больших наборов данных. Пользуйтесь соответствующими интерфейсами Win32. В следующем примере любой текст в записи файла заменяется текстом Xray 1. Дополнительные сведения см. в разделе Общие сведения о FILESTREAM.

UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;

Обновление определяемых пользователем типов данных

В следующем примере производится изменение значений в столбцах определяемого пользователем типа данных CLR. Показаны три метода. Дополнительные сведения об определяемых пользователем столбцах см. в разделе Определяемые пользователем типы данных CLR.

А. Использование системного типа данных

Можно обновить определяемый пользователем тип передачей значения в системном типе данных SQL Server, если определяемый пользователем тип поддерживает для него явное или неявное преобразование. Следующий пример демонстрирует, как обновить значение в столбце определяемого пользователем типа Point путем явного преобразования строки.

UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';

Б. Вызов метода

Для обновления определяемого пользователем типа можно вызвать метод этого типа, помеченный как мутатор. Следующий пример вызывает метод мутатора типа Point с именем SetXY. Это обновляет состояние экземпляра типа.

UPDATE dbo.Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';

В. Изменение значения свойства или элемента данных

Для обновления определяемого пользователем типа можно изменить значение зарегистрированного свойства или общедоступного элемента данных этого типа. Выражение, предоставляющее значение, должно допускать неявное преобразование в тип свойства. В следующем примере изменяется значение свойства X определяемого пользователем типа Point.

UPDATE dbo.Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';

Переопределение стандартных действий, выполняемых оптимизатором запросов, с помощью подсказок

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

ПредупреждениеВнимание!

Поскольку оптимизатор запросов SQL Server обычно выбирает наилучший план выполнения запроса, подсказки рекомендуется использовать только опытным разработчикам и администраторам баз данных в качестве последнего средства.

А. Указание табличной подсказки

В следующем примере задается табличная подсказка TABLOCK. Эта подсказка указывает, что на таблицу Production.Product накладывается совмещаемая блокировка, которая удерживается до завершения выполнения инструкции UPDATE.

USE AdventureWorks;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

Б. Указание подсказки в запросе

В следующем примере задается подсказка в запросеOPTIMIZE FOR (@variable) в инструкции UPDATE. Эта подсказка указывает оптимизатору запросов, что при компиляции и оптимизации запроса нужно использовать конкретное значение для локальной переменной. Значение используется только в процессе оптимизации запроса, но не в процессе выполнения.

USE AdventureWorks;
GO
CREATE PROCEDURE Production.uspProductUpdate
@Product nvarchar(25)
AS
SET NOCOUNT ON;
UPDATE Production.Product
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE @Product
OPTION (OPTIMIZE FOR (@Product = 'BK-%') );
GO
-- Execute the stored procedure 
EXEC Production.uspProductUpdate 'BK-%';

Сбор результатов инструкции UPDATE

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

А. Использование инструкции UPDATE с предложением OUTPUT

В следующем примере значения в столбце VacationHours в первых 10 строках таблицы Employee уменьшаются до 25 % от исходных значений, а в столбец ModifiedDate устанавливается текущая дата. Предложение OUTPUT возвращает значение VacationHours, существующее до применения инструкции UPDATE в столбце deleted.VacationHours, и обновленное значение в столбце inserted.VacationHours к табличной переменной @MyTableVar.

Две следующие инструкции SELECT возвращают значения в табличную переменную @MyTableVar, а результаты операции обновления — в таблицу Employee. Дополнительные примеры использования предложения OUTPUT см. в разделе Предложение OUTPUT (Transact-SQL).

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
    ModifiedDate = GETDATE() 
OUTPUT inserted.EmployeeID,
       deleted.VacationHours,
       inserted.VacationHours,
       inserted.ModifiedDate
INTO @MyTableVar;

--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO

--Display the result set of the table.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

Использование инструкции UPDATE в других инструкциях

Примеры в этом разделе показывают, как использовать инструкцию UPDATE в других инструкциях.

А. Использование UPDATE в хранимой процедуре

В следующем примере инструкция UPDATE используется в хранимой процедуре. Процедура принимает один входной параметр @NewHours и один выходной параметр @RowCount. Значение параметра @NewHours используется в инструкции UPDATE для обновления столбца VacationHours в таблице HumanResources.Employee. Выходной параметр @RowCount служит для возврата в локальную переменную числа обработанных строк. Выражение CASE используется в предложении SET для условного определения значения, которое задано для столбца VacationHours. Если для сотрудника применяется почасовая ставка оплаты (SalariedFlag = 0), то в столбце VacationHours устанавливается текущее количество часов плюс значение, заданное в @NewHours. В противном случае в столбце VacationHours указывается значение, заданное в @NewHours.

USE AdventureWorks;
GO
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours smallint,
@RowCount int OUTPUT
AS 
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours = 
    ( CASE
         WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
         ELSE @NewHours
       END
    )
WHERE CurrentFlag = 1;
SET @RowCount = @@ROWCOUNT;
GO

-- Execute the stored procedure and return the number of rows updated to the variable @RowCount
DECLARE @RowCount int;
EXECUTE HumanResources.Update_VacationHours 40, @RowCount OUTPUT;
SELECT @RowCount AS RowCount;

Б. Использование инструкции UPDATE в блоке TRY…CATCH

В следующем примере инструкция UPDATE используется в блоке TRY…CATCH для обработки ошибок выполнения, которые могут возникнуть во время операции обновления. Дополнительные сведения см. в разделе Использование конструкции TRY...CATCH в языке Transact-SQL.

USE AdventureWorks;
GO
BEGIN TRANSACTION;

BEGIN TRY
    -- Intentionally generate a constraint violation error.
    UPDATE HumanResources.Department
    SET Name = N'MyNewName'
    WHERE DepartmentID BETWEEN 1 AND 2;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

Журнал изменений

Обновленное содержимое

В синтаксис добавлен параметр table_alias для указания целевой таблицы для обновления.

В раздел «Ограничения» добавлены сведения об использовании обобщенных табличных выражений в качестве цели для инструкции UPDATE.