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

Откуда: СПб
Сообщений: 270
Добрый день!

Может кто подскажет, как можно сделать не прибегая к курсору, чтобы обновлялись только те поля что не NULL.

Поясню:

есть табличный тип данных

CREATE TYPE dbo.Type1 AS TABLE (
Id int IDENTITY,
NEW_VALUE1 varchar(5) NULL,
NEW_VALUE2 varchar(255) NULL,
NEW_VALUE3 int NULL


так вот если данные попали сюда, значит их все надо обновлять, но не факт что все поля в строке имеют значения для обновления.

конечно можно написать для каждого поля свой UPDATE и проверять, например
UPDATE Table1
SET VALUE1 = NEW_VALUE1
FROM Table1 AS tb
JOIN type1 AS tp
  ON tb.id = tp.id
WHERE tp.VALUE1 IS NOT NULL

UPDATE Table1
SET VALUE2 = NEW_VALUE2
FROM Table1 AS tb
JOIN type1 AS tp
  ON tb.id = tp.id
WHERE tp.VALUE2 IS NOT NULL


и так еще много раз...

P.S. mssql server 2008 R2
22 апр 14, 13:02    [15915474]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

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

проверять на NULL в CASE при присваивании в SET.
Апдейтить все поля в одном UPDATE, разумеется
22 апр 14, 13:08    [15915520]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

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

проверять на NULL в CASE при присваивании в SET.
Апдейтить все поля в одном UPDATE, разумеется
Имею в виду, что в THEN - новое значение, а в ELSE - текущее, что позволит оставить его неизменным.
22 апр 14, 13:10    [15915537]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
dma_caviar
Member

Откуда: https://itproduct.ru
Сообщений: 2361
проверять на NULL через isnull
22 апр 14, 13:11    [15915545]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
Т.к. при таком решении, если поле Null приходиться обновлять данные тем же содержимым, может кто подскажет как проверить в триггере на обновление что таблица INSERTED и DELETED не одинаковы?
23 апр 14, 21:57    [15925686]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Веткин Сергей
если поле Null приходиться обновлять данные тем же содержимым
И что? Как будто от этого сервер медленнее работает. Всё равно строка меняется полностью, и в логи записывается полностью.
Не зная как работает внутрях не надо надумывать. Или вы другое имели ввиду? Писать неудобно?

Две строки не одинаковы:
WHERE NOT Exists(SELECT I.* INTERSECT SELECT D.*)
Где I и D алиасы таблиц.
24 апр 14, 01:41    [15926365]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
Mnior спасибо, просто у меня Express => логирование методами сервера - нет

Просто не хочется в логах находить строки, которые не нужны, т.к. обновление происходило само на себя
24 апр 14, 11:46    [15927776]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
Glory
Member

Откуда:
Сообщений: 104751
Веткин Сергей
Просто не хочется в логах находить строки, которые не нужны, т.к. обновление происходило само на себя

разве не интересно узнать, кто/что впустую использует ресуры ?
24 апр 14, 11:48    [15927796]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Веткин Сергей
Mnior спасибо, просто у меня Express => логирование методами сервера - нет

Просто не хочется в логах находить строки, которые не нужны, т.к. обновление происходило само на себя
Непонятно.
1. При чём тут Express?
2. "Обновление происходило само на себя" - что не устраивает в WHERE Mniorа?
3. "Логирование методами сервера - нет" - а чьими методами надо?
24 апр 14, 11:51    [15927839]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
Ок, у меня организовано логирование своими методами. У меня есть специальная схема для таблиц с логами, в которую имеется возможность писать только от имени dbo, чтобы никто не мог "случайно" подправить логи.

Примерно такого вида:

CREATE TRIGGER trSystem_AU99 ON dbo.[System]
AFTER UPDATE AS
  DECLARE @Tid    INTEGER

  IF system_user <> N'sa'
  BEGIN

    EXECUTE AS USER = 'dbo';
    INSERT INTO log.SystemInfo(Operation, NameTable)
    VALUES ('U', 'log.SystemInfo');

    SET @Tid = ident_current('log.SystemInfo');

    INSERT INTO log.Systems(ID_SYSTEM, NAME, [DESCRIPTION], Ref_SysInfo)
    SELECT i.ID_SYSTEM, CASE
            WHEN i.NAME <> d.NAME THEN
              i.NAME
            ELSE
              NULL
          END, CASE
            WHEN i.[DESCRIPTION] <> d.[DESCRIPTION] THEN
              i.[DESCRIPTION]
            ELSE
              NULL
          END, @Tid
    FROM INSERTED i
        INNER JOIN DELETED d
                  ON i.ID_SYSTEM = d.ID_SYSTEM;


    REVERT;
    
  END


так вот когда происходит обновление само на себя, в логе будут получаться строки со всеми значениями Null, а мне это не нужно.

А так как у меня Express, я не могу возложить логирование на сервер.
24 апр 14, 12:03    [15927947]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Веткин Сергей
Ок, у меня организовано логирование своими методами. У меня есть специальная схема для таблиц с логами, в которую имеется возможность писать только от имени dbo, чтобы никто не мог "случайно" подправить логи.

Примерно такого вида:

CREATE TRIGGER trSystem_AU99 ON dbo.[System]
AFTER UPDATE AS
  DECLARE @Tid    INTEGER

  IF system_user <> N'sa'
  BEGIN

    EXECUTE AS USER = 'dbo';
    INSERT INTO log.SystemInfo(Operation, NameTable)
    VALUES ('U', 'log.SystemInfo');

    SET @Tid = ident_current('log.SystemInfo');

    INSERT INTO log.Systems(ID_SYSTEM, NAME, [DESCRIPTION], Ref_SysInfo)
    SELECT i.ID_SYSTEM, CASE
            WHEN i.NAME <> d.NAME THEN
              i.NAME
            ELSE
              NULL
          END, CASE
            WHEN i.[DESCRIPTION] <> d.[DESCRIPTION] THEN
              i.[DESCRIPTION]
            ELSE
              NULL
          END, @Tid
    FROM INSERTED i
        INNER JOIN DELETED d
                  ON i.ID_SYSTEM = d.ID_SYSTEM;


    REVERT;
    
  END



так вот когда происходит обновление само на себя, в логе будут получаться строки со всеми значениями Null, а мне это не нужно.

А так как у меня Express, я не могу возложить логирование на сервер.
Ужас какой-то!
А если я проапдейчу 10 строк одним UPDATEом?
А если часть полей поменяли значения с NULL на что-то конкретное? [DESCRIPTION], например?
24 апр 14, 12:06    [15927986]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Как только вижу триггер, начинающийся с объявления скалярных переменных,
сразу понимаю: скорее всего говнокод!
24 апр 14, 12:08    [15928007]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
IDENT_CURRENT вот ещё тоже шедевр.
24 апр 14, 12:09    [15928025]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
iap
Ужас какой-то!
А если я проапдейчу 10 строк одним UPDATEом?


на сколько я знаю, триггер вызовится все равно 1 раз, просто в таблицах INSERTED и DELETED будет 10 строк, они и занисуться в log.System. Каждая со своим набором пустых и не пустых полей

iap
А если часть полей поменяли значения с NULL на что-то конкретное? [DESCRIPTION], например?


CASE
            WHEN i.[DESCRIPTION] <> d.[DESCRIPTION] THEN
              i.[DESCRIPTION]
            ELSE
              NULL


вставится значение, на которое обновляется нулевое поле. Нет?
24 апр 14, 12:14    [15928074]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Веткин Сергей
на сколько я знаю, триггер вызовится все равно 1 раз, просто в таблицах INSERTED и DELETED будет 10 строк, они и занисуться в log.System. Каждая со своим набором пустых и не пустых полей
Да. Я был невнимателен.
Веткин Сергей
вставится значение, на которое обновляется нулевое поле. Нет?
Вы не умеете сравнивать со значением NULL?
Есть специальный оператор - IS [NOT] NULL
24 апр 14, 12:19    [15928131]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
iap, спасибо за то что обратили внимание про NULL.

Сейчас проверил и вправду не сработало бы

сделал так

CASE
              WHEN i.[TASK_NAME_SYS] <> d.[TASK_NAME_SYS] OR d.[TASK_NAME_SYS] IS NULL THEN
                i.[TASK_NAME_SYS]
              ELSE
                NULL END
24 апр 14, 13:26    [15928768]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Веткин Сергей,
CASE WHEN NOT EXISTS(SELECT i.[TASK_NAME_SYS] INTERSECT SELECT d.[TASK_NAME_SYS]) THEN i.[TASK_NAME_SYS] END
Вам же уже Mnior написал!
24 апр 14, 14:29    [15929306]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
Веткин Сергей,
CASE WHEN NOT EXISTS(SELECT i.[TASK_NAME_SYS] INTERSECT SELECT d.[TASK_NAME_SYS]) THEN i.[TASK_NAME_SYS] END

Вам же уже Mnior написал!
Только я думаю, что в лог надо сбрасывать из deleted.
Потому что inserted и так в самой таблице лежит
24 апр 14, 15:11    [15929692]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
iap, я использовал INTERSECT в начале триггера для определения нужно ли вообще логировать, а вот что можно так еще использовать не допер, спасибо за еще одну подсказку.
24 апр 14, 22:35    [15932384]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
iap
Только я думаю, что в лог надо сбрасывать из deleted.
Потому что inserted и так в самой таблице лежит


Если так рассматривать, то вставку вообще не надо логировать, а только удаление и обновление. Но как тогда узнать когда и кем были вставлены данные?
25 апр 14, 15:17    [15936182]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Веткин Сергей
iap
Только я думаю, что в лог надо сбрасывать из deleted.
Потому что inserted и так в самой таблице лежит


Если так рассматривать, то вставку вообще не надо логировать, а только удаление и обновление. Но как тогда узнать когда и кем были вставлены данные?
Завести соответсвующие поля в самой таблице
25 апр 14, 15:22    [15936228]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
iap
Веткин Сергей,
CASE WHEN NOT EXISTS(SELECT i.[TASK_NAME_SYS] INTERSECT SELECT d.[TASK_NAME_SYS]) THEN i.[TASK_NAME_SYS] END
Вам же уже Mnior написал!
NULLIF(i.[TASK_NAME_SYS],d.[TASK_NAME_SYS])
25 апр 14, 16:04    [15936631]     Ответить | Цитировать Сообщить модератору
 Re: Запрос на обновление с переменным кол-вом полей  [new]
vso
Member

Откуда: СПб
Сообщений: 270
Cygapb-007, спасибо конечно, но дело не только в проверке на NULL, но еще и на неравенство
25 апр 14, 16:58    [15937071]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить