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

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

Задача:
При закрытии документа оприходования товара (таблица Receipt, шапка документа, статус закрытого документа "9") определенного типа ("21" или "22") необходимо обновлять данные в связанных документы на отгрузку, связь осуществляется по полю "PoKey". Обновить нужно отгружаемое количество штук для каждого товара, на принятое количество (таблица строк документа отгрузки OrderDetail), в завершении требуется обновить суммарное количество (сумма количества принятого товара) в шапке документа (таблица Orders).
По факту товар в документе оприходования всегда присутствует в документе отгрузки.


Create trigger dbo.EditDocDetails
       on dbo.Receipt
       after update
as
begin
     if exists ( 
                   select 1
                   from inserted
                   where Status = '9'         -- Статус закрытия документа
                         and Type in ( '21'
                                     , '22'
                                     )
                         and PoKey <> ''      -- номер документа закупки
               )
     begin
          -- обновление строк документа
          Update docdet
                 set OpenQty = newset.QtyReceived
          from dbo.Orders as doc
               inner join dbo.OrderDetail as docdet
                       on doc.StorerKey = docdet.StorerKey
                          and doc.OrderKey = docdet.OrderKey
               inner join ( 
                              select recdet.StorerKey
                                   , recdet.Sku
                                   , recdoc.Pokey
                                   , Sum( recdet.QtyReceived) as QtyReceived
                              from inserted as recdoc 
                                   inner join dbo.ReceiptDetail as recdet ( nolock )
                                           on recdoc.StorerKey = recdet.StorerKey
                                              and recdoc.ReceiptKey = recdet.ReceiptKey
                              where recdoc.Status = '9'         -- Статус закрытия документа
                                    and recdoc.Type in ( '21'   -- тип документа
                                                       , '22'   -- тип документа
                                                       )
                                    and recdoc.PoKey <> ''      -- номер документа закупки
                              group by recdet.StorerKey
                                     , recdet.Sku
                                     , recdoc.Pokey
                           ) as newset
                             on doc.PoKey = newset.PoKey
                                and docdet.StorerKey = newset.StorerKey
                                and docdet.Sku = newset.Sku
          -- обновление документа
          Update doc
                 set OpenQty = newset.QtyReceived
          from dbo.Orders as doc
               inner join ( 
                              select recdet.StorerKey
                                   , recdoc.Pokey
                                   , Sum( recdet.QtyReceived) as QtyReceived
                              from inserted as recdoc 
                                   inner join dbo.ReceiptDetail as recdet ( nolock )
                                           on recdoc.StorerKey = recdet.StorerKey
                                              and recdoc.ReceiptKey = recdet.ReceiptKey
                              where recdoc.Status = '9'         -- Статус закрытия документа
                                    and recdoc.Type in ( '21'   
                                                       , '22'   
                                                       )
                                    and recdoc.PoKey <> ''      -- номер документа закупки
                              group by recdet.StorerKey
                                     , recdoc.Pokey
                           ) as newset
                             on doc.PoKey = newset.PoKey
                                and doc.StorerKey = newset.StorerKey
     end
end


Какие проблемы могут возникнуть с использованием триггеров? Заранее всем спасибо!
26 апр 18, 11:04    [21370281]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
aleks222
Member

Откуда:
Сообщений: 847
Дык, с правильным триггером никаких проблем не возникнет.

А тебе следует, таки, привить себе отвращение к лишним группировкам.
26 апр 18, 11:25    [21370334]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
IDVT
Member

Откуда:
Сообщений: 309
Да вот, не хотелось бы создавать вьюшку и обновлять данные в одном Update, тогда мог бы получить результат обоих агрегатов (по товарам и общий) за одно обращение к таблице inserted
26 апр 18, 11:40    [21370386]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 53633
а если существующее закрытое ПО корректирует те же таблицы?
26 апр 18, 11:51    [21370419]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
IDVT
Member

Откуда:
Сообщений: 309
andreymx
а если существующее закрытое ПО корректирует те же таблицы?
Нет, этого в ней не происходит, документы живут отдельной жизнью друг от друга.
26 апр 18, 11:55    [21370437]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3436
IDVT
andreymx
а если существующее закрытое ПО корректирует те же таблицы?
Нет, этого в ней не происходит, документы живут отдельной жизнью друг от друга.


Как-то ....

Триггер апдейтит все подходящие записи в таблицах, не глядя на то, какие были изменны в данном коннекте.
Если два и более приложений будут работать с документом этот триггер сработает для каждого изменения.
26 апр 18, 12:19    [21370532]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
IDVT
Member

Откуда:
Сообщений: 309
Ролг Хупин
IDVT
пропущено...
Нет, этого в ней не происходит, документы живут отдельной жизнью друг от друга.


Как-то ....

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


Ситуация такова, после закрытия документа оприходования (Статус "9"), ПО не позволяет редактировать документ. Триггер как раз выполнит обновление, в случае наличия статуса закрытия. Проверять именно Статус на его изменение нет смысла, т.е. сравнивать таблицы inserted и deleted.
26 апр 18, 12:42    [21370584]     Ответить | Цитировать Сообщить модератору
 Re: Первый тригер  [new]
ЛиП
Member

Откуда:
Сообщений: 348
Я бы написал if not exist then return 0
26 апр 18, 13:12    [21370678]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить