Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
Sql процедура обновления принимает множество параметров, все из которых могут быть равны null, кроме Id. Нужно обновить только те поля в таблице, параметры для которых не равны null.

Можно ли как-то упростить процесс проверки на null?
22 авг 11, 15:36    [11157828]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 8933
Update sometable
  set Field1 = isnull(@Field1, Field1),
       Field2 = isnull(@Field2, Field2)
...
where ID = @ID
22 авг 11, 15:43    [11157886]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
Кот Матроскин,

спасибо, что надо!
22 авг 11, 15:43    [11157889]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
не работает
ALTER PROC [dbo].[ppp]
    (
      @Id UNIQUEIDENTIFIER,
      @Name NVARCHAR(20) = NULL,
      @FullName NVARCHAR(200) = NULL,
      @Status INT = NULL
    )
AS 
    UPDATE  [dbo].[Customers]
    SET     [Name] = ISNULL(@Name, [Name]),
              [FullName] = ISNULL(@FullName, FullName),
              [Status] = ISNULL(@Status, [Status])

 IF @@ROWCOUNT = 0 
        INSERT  INTO [dbo].[Customers]
        VALUES  (
                        @Id,
                        @Name,
                        @FullName,
                        @Status
                )

Вызов

exec [dbo].[ppp] 
@Id='3030234E-312A-477C-8516-02F25B4CF34A',

@Name=N'new value dfsfdsfd',
@FullName=N'fdsfdsf sfdsfds fdsf dsfd',
@Status=0

Значения остаются прежними
29 авг 11, 17:52    [11196870]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Darooma,

по-Вашему, что должно обновиться UPDATEом без WHERE?
Я тут уже как-то говорил, что у нас на старой работе за это выводили во двор и расстреливали.
29 авг 11, 17:56    [11196921]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

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

там есть WHERE

WHERE   Id = @Id
29 авг 11, 17:59    [11196950]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
кстати запись

SET [Name] = ISNULL(@Name, [Name])

не означает что запись не будет обновлена
автор
Нужно обновить только те поля в таблице, параметры для которых не равны null

это ж update на такое же значение которое было?

или скл понимает что обновлять на само себя значение не надо )
29 авг 11, 18:00    [11196958]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
Darooma
там есть WHERE


В процедуре ppp НЕТ WHERE, проверьте контрол+Ф в браузере.

J.d
не означает что запись не будет обновлена


ЛОГИЧЕСКИ не будет. То что она физически обновится впустую/вхолостую... ну, не криминал, скажем так.

J.d
или скл понимает что обновлять на само себя значение не надо


Да конечно! Оптимизатор запросов в MSSQL силен, не спорю, не по детски, но что б такое... А если у вас в ячейке varchr(MAX) книга на Гиг впихнута? А вы новую редакцию туда отличающуюся одной буквой? Сопоставить два гиговых массива байт-в-байт?
Кроме того - элементарно не выгодно даже для int-ов. "Обновить без проверок" много лучше чем "сгонять-проверить+все-равно по итогу обновить". Надо или не надо обновлять пусть программер решает, ему для этого WHERE даден.
29 авг 11, 18:26    [11197116]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
SamMan
J.d
не означает что запись не будет обновлена


ЛОГИЧЕСКИ не будет. То что она физически обновится впустую/вхолостую... ну, не криминал, скажем так.


а мне всё же кажется всё таки это нездоровая тема и не решает поставленного вопроса "правильно".
если можно так выразиться
29 авг 11, 18:28    [11197132]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Vyacheslav Scherbak
Member

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

пишите динамику, если не устраивает подход Кот Матроскин
29 авг 11, 18:55    [11197274]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
а я бы еще и isnull заменил на coalesce
29 авг 11, 19:02    [11197312]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
оригами триггерами
Guest
Darooma
не работает
    UPDATE  [dbo].[Customers]

IF @@ROWCOUNT = 0 
        INSERT  INTO [dbo].[Customers]


чо там с триггерами на customers?
29 авг 11, 19:25    [11197423]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
SamMan

J.d
не означает что запись не будет обновлена


ЛОГИЧЕСКИ не будет. То что она физически обновится впустую/вхолостую... ну, не криминал, скажем так.


Скажем так, все прямо таки с точностью до наоборот. Логически запись обновится, т.е. будет вызвана внутренняя процедура update, будет вызван триггер, @@ROWCOUNT > 0 и т.д. А вот физически как раз никакого обновления не будет.

SamMan

J.d
или скл понимает что обновлять на само себя значение не надо


Да конечно! Оптимизатор запросов в MSSQL силен, не спорю, не по детски, но что б такое... А если у вас в ячейке varchr(MAX) книга на Гиг впихнута? А вы новую редакцию туда отличающуюся одной буквой? Сопоставить два гиговых массива байт-в-байт?
Кроме того - элементарно не выгодно даже для int-ов. "Обновить без проверок" много лучше чем "сгонять-проверить+все-равно по итогу обновить". Надо или не надо обновлять пусть программер решает, ему для этого WHERE даден.


Вы что правда считаете что можно сохранить новое значение не вычитав перед этим старое? особенно учитывая то, что все операции чтения-записи выполняются постранично, а не на уровне строки. Сервер физически не может переписать часть страницы (одну строку) не вычитав предварительно всю эту страницу, потому что информация о смещениях хранится там же. Да и к тому же, нужно знать реальные размеры для всех типов переменной длинны, потому как новое значение может просто не влезть в выделенное место, а это в свою очередь приведет к page split.

В итоге, на фоне всей этой работы сделать проверку old_value <> new_value, поверьте, не так уж трудозатратно. Особенно если в результате этого получится избежать физических операций, которые реально дорогие.

И кстати, оптимизатор запросов здесь совсем ни при чем. Ему то как раз фиолетово, он даже и не знает, поменялись там данные или нет, план выполнения все равно будет одинаковый и UPDATE там будет. Вся логика по вычитке, сверке и записи идет на более низких уровнях. А вообще, почитайте SQL Internals что-ли, чтобы не делать таких опрометчивых предположений.
29 авг 11, 22:27    [11197981]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
Кто предложит решение?
29 авг 11, 22:58    [11198073]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Darooma
Кто предложит решение?


Вам ведь уже предложили решение.
29 авг 11, 23:47    [11198227]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
Mind
Darooma
Кто предложит решение?


Вам ведь уже предложили решение.

Оно не работает, я же говорю.
30 авг 11, 09:09    [11198845]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Darooma
Mind
пропущено...


Вам ведь уже предложили решение.

Оно не работает, я же говорю.
А почему в INSERTе у таблицы поля не перечислены?
Версию назовёте?
Если она >=90, то для отладки попробуйте UPDATE и INSERT с OUTPUT
Посмотрите, что вернётся.
30 авг 11, 09:15    [11198862]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 8933
Darooma,

Не вижу скрипта создания/заполнения таблицы, поэтому судить, что и почему у Вас не обновляется, довольно сложно.
У меня этот подход в разных системах работает 10+ лет.
30 авг 11, 10:40    [11199203]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
iljy
Member

Откуда:
Сообщений: 8711
Darooma
Mind
пропущено...


Вам ведь уже предложили решение.

Оно не работает, я же говорю.

Иногда все-таки лучше жевать. Приведите серверное сообщение об ошибке.
30 авг 11, 11:04    [11199363]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
Mind
Вы что правда считаете что можно сохранить новое значение не вычитав перед этим старое?


Ну пока Вы не покажете мне обратное - таки да, считаю. Зачем считывать старое значение если через несколько микросекунд оно будет затерто? Вы, прежде чем заменить файл фильма тем же фильмом в лучшем разрешении старую версию просматриваете в плеере? (разумеется, очень натянутое сравнение, но все же...)

Mind
особенно учитывая то, что все операции чтения-записи выполняются постранично

Mind
не вычитав предварительно всю эту страницу


Если страница УЖЕ в памяти(буфере) - зачем сервер будет ее считывать повторно?

Mind
потому что информация о смещениях хранится там же

инфа о смещениях var-значений данной строки хранится в хидере той же самой строки, чтением коего можно и ограничится

Mind
потому как новое значение может просто не влезть в выделенное место, а это в свою очередь приведет к page split


если строка из-за Update будет перенесена на новую страницу, то это уже будет не Update, а delete+insert (ессесно, движок сам обо всем позаботится, мы всегда пишем UPDATE); тут рассуждения о "как сэкономить на избыточных апдейтах некоторых колонок" просто не актуальны

Mind
В итоге, на фоне всей этой работы сделать проверку old_value <> new_value, поверьте, не так уж трудозатратно.

Так в итоге - такое сравнение - делается? Или нет, все же?

Mind
почитайте SQL Internals что-ли, чтобы не делать таких опрометчивых предположений


Надеюсь вы сей мануал изучили и с легкостью укажете номера страниц электронной версии кои и положат конец нашему академическому спору. Кстати, практической пользы от выяснения "кто прав", не будет по любому - UPDATE на физическом уровне осуществляется так как он запрограмлен для данной версии движка, повлиять мы все едино не можем. Но для "общего развития" - интересно.
30 авг 11, 13:34    [11200595]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
ChA
Member

Откуда: Москва
Сообщений: 11314
На 2000 наблюдалось такое поведение, на более поздних версиях не проверял. Для полей типа BLOB-ов сравнения, насколько помню, не происходило.
30 авг 11, 14:33    [11201086]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
iljy
Darooma
пропущено...

Оно не работает, я же говорю.

Иногда все-таки лучше жевать. Приведите серверное сообщение об ошибке.

Ты забыл сказать "Пожалуйста".
30 авг 11, 14:49    [11201217]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Darooma
Ты забыл сказать "Пожалуйста".
Вы еще забыли потребовать, чтобы участники дискуссии извинились, что за неделю так и не смогли решить все ваши проблемы. И в знак признания своей вины сгоняли бы вам за пивком.
30 авг 11, 14:53    [11201248]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Darooma
Member

Откуда:
Сообщений: 758
Юмор из вас пьявками сосать надо.
30 авг 11, 15:48    [11201694]     Ответить | Цитировать Сообщить модератору
 Re: Sql процедура - обновить только те поля, параметры для которых не равны null  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Darooma
Юмор из вас пьявками сосать надо.
Это не юмор. Это нетонкий намек на то, как надо себя вести, чтобы получить хоть какой-нибудь ответ на свои вопросы.
30 авг 11, 15:58    [11201770]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить