UPDATE (Transact-SQL)

Изменяет существующие данные в таблице или представлении в SQL Server 2012. Примеры см. в разделе Примеры.

Значок ссылки на раздел Синтаксические обозначения 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 { += | -= | *= | /= | %= | &= | ^= | |= } 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. Результирующий набор CTE, на который ссылается инструкция UPDATE, является производным простого запроса.

    Обобщенные табличные выражения могут также использоваться с инструкциями SELECT, INSERT, DELETE и CREATE VIEW. Дополнительные сведения см. в разделе WITH обобщенное_табличное_выражение (Transact-SQL).

  • TOP (expression) [ PERCENT ]
    Задает число или процент обновляемых строк. expression может быть либо числом, либо процентом от числа строк.

    Строки, на которые ссылается выражение TOP, используемое с инструкциями INSERT, UPDATE и DELETE, не упорядочиваются.

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

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

  • server_name
    Имя сервера (с использованием имени связанного сервера или функции OPENDATASOURCE в качестве имени сервера), на котором расположена таблица или представление. Если указан аргумент server_name, также необходимо указать аргументы database_name и schema_name.

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

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

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

  • rowset_function_limited
    Функция OPENQUERY или OPENROWSET, в зависимости от возможностей поставщика.

  • WITH ( <Table_Hint_Limited> )
    Задает одно или несколько табличных указаний, разрешенных для целевой таблицы. Необходимо использовать ключевое слово WITH и круглые скобки. Использование аргументов 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, если столбец не имеет значений по умолчанию и может принимать значения NULL.

  • { += | -= | *= | /= | %= | &= | ^= | |= }
    Составной оператор присваивания:

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

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

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

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

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

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

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

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

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

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

  • method_name ( argument [ ,... n] )
    Не статичный метод общего мутатора udt_column_name, принимающий один или несколько аргументов.

  • .WRITE (expression,@Offset,@Length**)**
    Указывает, что часть значения column_name будет изменена. Параметр expression заменяет @Length единиц начиная со смещения @Offset строки column_name. В этом предложении могут быть указаны только столбцы типа 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 задает последовательную позицию начиная с 0, имеет тип 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 <источник_таблицы>
    Определяет, что для определения критериев операции обновления используется таблица, представление или производная таблица. Дополнительные сведения см. в разделе Предложение FROM (Transact-SQL).

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

    Представление с триггером INSTEAD OF UPDATE не может быть целью инструкции UPDATE с предложением FROM.

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

    Любой вызов функции OPENDATASOURCE, OPENQUERY или OPENROWSET в предложении FROM вычисляется отдельно и независимо от любого вызова этих функций, используемого как назначение при обновлении, даже если в двух таких вызовах будут заданы идентичные аргументы. В частности, условия фильтра или соединения, применяемые к результатам одного из таких вызовов, никак не влияют на результаты другого.

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

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

    • В позиционных обновлениях используется предложение CURRENT OF для указания курсора. Операция обновления выполняется в текущем положении курсора.

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

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

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

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

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

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

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

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

Для возврата в клиентское приложение количества вставленных строк используйте функцию @@ROWCOUNT. Дополнительные сведения см. в разделе @@ROWCOUNT (Transact-SQL).

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

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

USE AdventureWorks2012;
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 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 AdventureWorks2012;
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

Поддержка совместимости

Поддержка использования подсказок READUNCOMMITTED и NOLOCK в предложении FROM, применяемом к целевой таблице инструкции UPDATE или DELETE, будет удалена в следующей версии SQL Server. Следует избегать использования этих подсказок в таком контексте в новой разработке и запланировать изменение приложений, использующих их в настоящий момент.

Типы данных

Все столбцы, имеющие тип данных 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).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Обновление столбцов определяемого пользователем типа

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

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

    UPDATE Cities
    SET Location = CONVERT(Point, '12.3:46.2')
    WHERE Name = 'Anchorage';
    
  • Вызов метода, помеченного в качестве мутатора определенного пользователем типа для осуществления обновления. Следующий пример вызывает метод мутатора типа Point с именем SetXY. Это обновляет состояние экземпляра типа.

    UPDATE Cities
    SET Location.SetXY(23.5, 23.5)
    WHERE Name = 'Anchorage';
    
    ПримечаниеПримечание

    SQL Server возвращает ошибку, если метод мутатора возвращает значение NULL языка Transact-SQL либо если новое значение, порожденное методом мутатора, соответствует значению NULL.

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

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

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

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

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

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

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

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

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

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

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

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

Ограничения

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

Если обобщенное табличное выражение указывается в качестве цели инструкции 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 всегда получает монопольную блокировку (X) на таблицу, которую она изменяет, и держит блокировку до тех пор, пока транзакция не завершится. При наличии монопольной блокировки другие транзакции не могут изменять данные. Можно переопределить поведение оптимизатора запросов по умолчанию с помощью табличных подсказок на время выполнения инструкции UPDATE указанием другого способа блокировки, но использовать подсказки рекомендуется только опытным разработчикам и администраторам баз данных и только при крайней необходимости. Дополнительные сведения см. в разделе Табличные указания (Transact-SQL).

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

Инструкция UPDATE записывается в журнал, однако частичные обновления типов данных большого объема с использованием предложения **.**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 AdventureWorks2012;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();

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

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

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

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

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

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

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

USE AdventureWorks2012;
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 AdventureWorks2012;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO

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

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

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

В следующем примере обновляется значение PerAssemnblyQty для всех частей и компонентов, прямо или косвенно используемых для создания ProductAssemblyID 800. Обобщенное табличное выражение возвращает иерархический список частей, которые непосредственно используются для сборки ProductAssemblyID 800, и частей, которые используются для сборки этих компонентов, и т. д. Изменяются только строки, возвращаемые обобщенным табличным выражением.

USE AdventureWorks2012;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom 
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0; 

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

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

USE AdventureWorks2012;
GO
DECLARE complex_cursor CURSOR FOR
    SELECT a.BusinessEntityID
    FROM HumanResources.EmployeePayHistory AS a
    WHERE RateChangeDate <> 
         (SELECT MAX(RateChangeDate)
          FROM HumanResources.EmployeePayHistory AS b
          WHERE a.BusinessEntityID = b.BusinessEntityID) ;
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

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

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

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

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

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

Б.Задание составного оператора

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

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

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

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

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

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

USE AdventureWorks2012;
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.BusinessEntityID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

Г.Обновление строк с использованием значений DEFAULT

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

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

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

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

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

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

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

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

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

USE AdventureWorks2012;
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 AdventureWorks2012;
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 BusinessEntityID 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.BusinessEntityID = EmpID;

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

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

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

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

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

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

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

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

USE AdventureWorks2012;
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.BusinessEntityID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

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

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

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

В следующем примере обновляется таблица на удаленном сервере. Этот пример начинается с создания ссылки на удаленный источник данных с помощью хранимой процедуры sp_addlinkedserver. Затем имя связанного сервера MyLinkServer указывается в качестве одного из четырех компонентов имени объекта в формате server.catalog.schema.object. Обратите внимание, что необходимо указать действительное имя сервера для @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'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
-- Specify the remote data source using a four-part name 
-- in the form linked_server.catalog.schema.object.

UPDATE MyLinkServer.AdventureWorks2012.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, возвращающей набор строк. Укажите допустимое имя сервера для источника данных в формате server_name или server_name\instance_name. Возможно, потребуется настроить у экземпляра SQL Server параметр Ad Hoc Distributed Queries. Дополнительные сведения см. в разделе Параметр конфигурации сервера «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 AdventureWorks2012;
GO
DECLARE @MyTableVar table (
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT deleted.DocumentSummary, 
       inserted.DocumentSummary 
    INTO @MyTableVar
WHERE Title = N'Front Reflector Bracket Installation';
SELECT SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

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

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

USE AdventureWorks2012;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO

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

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

USE AdventureWorks2012;
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 (SQL Server).

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 AdventureWorks2012;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

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

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

USE AdventureWorks2012;
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 AdventureWorks2012;
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.BusinessEntityID,
       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) BusinessEntityID, 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 AdventureWorks2012;
GO
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours smallint
AS 
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours = 
    ( CASE
         WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
         ELSE @NewHours
       END
    )
WHERE CurrentFlag = 1;
GO

EXEC HumanResources.Update_VacationHours 40;

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

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

USE AdventureWorks2012;
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

См. также

Справочник

Инструкция CREATE TABLE (Transact-SQL)

CREATE TRIGGER (Transact-SQL)

Курсоры (Transact-SQL)

DELETE (Transact-SQL)

Инструкция INSERT (Transact-SQL)

Функции для работы с типами данных text и image (Transact-SQL)

WITH обобщенное_табличное_выражение (Transact-SQL)

Основные понятия

FILESTREAM (SQL Server)