Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Многократный UPDATE одной строки в одном запросе  [new]
jnub
Member

Откуда:
Сообщений: 32
Есть апдейт с join'ом, который по ряду причин приводит
к появлению в наборе новых значений для обновляемой таблицы
нескольких значений для одной строки.

Выглядит это так:

SET NOCOUNT ON
BEGIN TRAN

-- Обновляемая строка
DECLARE @T TABLE  (id INT, v INT)
INSERT  @T VALUES (1, 10) 

SELECT  * FROM @t

-- Варианты значений для обновления
DECLARE @S TABLE (id INT, A INT)
INSERT  @S
SELECT  1, -999 UNION ALL 
SELECT  1, 100

SELECT  * 
FROM    @T T, 
        @S S
WHERE   S.id = T.id

-- Апдейт на основе предыдущего значения
UPDATE  @T 
SET     v = v + S.A
FROM    @T T, 
        @S S
WHERE   S.id = T.id

-- Результат
SELECT  * FROM @t

ROLLBACK
GO


id          v           
----------- ----------- 
1           10

id          v           id          A           
----------- ----------- ----------- ----------- 
1           10          1           -999     <<<<<<<<<<<<<<
1           10          1           100      <<<<<<<<<<<<<<

id          v           
----------- ----------- 
1           110                              <<<<<<<<<<<<<<


Как видно из результата, в апдейт пошло только второе значение (100) из двух возможных (100, -999).


|--Table Update(OBJECT:(@T), SET:(@T.[v]=[Expr1004]))
|--Compute Scalar(DEFINE:([Expr1004]=[T].[v]+[S].[A]))
|--Top(ROWCOUNT est 0)
|--Stream Aggregate(GROUP BY:([Bmk1000]) DEFINE:([T].[v]=ANY([T].[v]), [S].[A]=ANY([S].[A])))
|--Nested Loops(Inner Join, WHERE:([T].[id]=[S].[id]))
|--Table Scan(OBJECT:(@T AS [T]))
|--Table Scan(OBJECT:(@S AS [S]))

Вопрос в чем - я правильно понимаю, что ANY возвращает любое (непредсказуемое) значение?

Microsoft SQL Server 2000 - 8.00.2066 (Intel X86)
12 мар 13, 12:36    [14039592]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
Гость333
Member

Откуда:
Сообщений: 3683
jnub,

Вы правильно понимаете.
BOL 2000, UPDATE
The results of an UPDATE statement are undefined if the statement includes a FROM clause that is not specified in such a way that only one value is available for each column occurrence that is updated (in other words, if the UPDATE statement is not deterministic). For example, given the UPDATE statement in the following script, both rows in table s meet the qualifications of the FROM clause in the UPDATE statement, but it is undefined which row from s is used to update the row in table t.

Ну и в старших версиях — то же самое.
Кстати, в версиях 2005 и 2008R2 ваш скрипт вернул -989. Вот она, непредсказуемость в действии.
12 мар 13, 12:47    [14039668]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
Кстати в 2008 - MERGE которым лучше воспользоваться в этом случае (имхо).
Вернёт ошибку.
12 мар 13, 12:55    [14039736]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32173
jnub
Вопрос в чем - я правильно понимаю, что ANY возвращает любое (непредсказуемое) значение?
Да, как указано в запросе.
12 мар 13, 13:15    [14039866]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32173
EvAlex
Кстати в 2008 - MERGE которым лучше воспользоваться в этом случае (имхо).
Вернёт ошибку.
Чем же MERGE лучше, если он вернёт ошибку :-)

Нужно использовать такой запрос, который нужен для бизнес-логики. В данном случае - "обновить любым значением".
12 мар 13, 13:17    [14039880]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47197
alexeyvg
EvAlex
Кстати в 2008 - MERGE которым лучше воспользоваться в этом случае (имхо).
Вернёт ошибку.
Чем же MERGE лучше, если он вернёт ошибку :-)

Нужно использовать такой запрос, который нужен для бизнес-логики. В данном случае - "обновить любым значением".
Тому, кто "обновляет любым значением", никакой SQL, никакой сервер не нужен.
Ибо он не собирается хранить и обрабатывать данные. А только мусор.
12 мар 13, 13:21    [14039907]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
jnub
Member

Откуда:
Сообщений: 32
iap
alexeyvg
пропущено...
Чем же MERGE лучше, если он вернёт ошибку :-)

Нужно использовать такой запрос, который нужен для бизнес-логики. В данном случае - "обновить любым значением".
Тому, кто "обновляет любым значением", никакой SQL, никакой сервер не нужен.
Ибо он не собирается хранить и обрабатывать данные. А только мусор.

В целом согласен. Вот, налетели на такую проблему (по семантике предполагалось, что некий запрос будет возвращать однозначный набор, и никаких проверок на этот счет не было).
Наверное, было бы здорово, если бы сервер как-то индицировал такие ситуации, предупреждая криворукость,
а не записывал "что попало" :)
С другой стороны, как бы это теоретически сказалось на производительности - это вопрос
12 мар 13, 16:31    [14041355]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
Вот имено этим и лучше - пусть будет ошибка и реакция\исправление, чем неизвестное значение, которое пойди пойми откуда появилось.
12 мар 13, 17:52    [14041836]     Ответить | Цитировать Сообщить модератору
 Re: Многократный UPDATE одной строки в одном запросе  [new]
=)8-)
Guest
А всего-то хотелось аналога
select @text += field from table
ятд:))
13 мар 13, 09:19    [14043450]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить