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

Откуда:
Сообщений: 9
Microsoft SQL Server Enterprise (64-bit)
12.0.5207.0
Прошу помощи в написание Триггера! Суть такова: Имеем таблицу [dbo].[tblProducts] с полями te1, te2, te3, te4 и StatusW.
Нужно заставить срабатывать триггер только в случае изменения в поле StatusW, и если вообще такое возможно, то только в случае, если поле StatusW будет изменено на "в работе".

Моя версия:
CREATE TRIGGER [Products]
ON [dbo].[tblProducts] AFTER UPDATE AS
IF ( UPDATE ([StatusW]))
BEGIN
INSERT INTO ......

END

Но это работает не правильно.. помогите разобраться, как заставить работать триггер только в случае изменения в поле
[StatusW] = 'в работе'. При любом другом статусе триггер не должен срабатывать..
11 июн 21, 09:44    [22334182]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3041
stsg,

CREATE TRIGGER [Products]
ON [dbo].[tblProducts] AFTER UPDATE AS
IF ( UPDATE ([StatusW]))
BEGIN

--определяем записи, которые получили статус "в работе"
--можно запихать во временную таблицу и потом сделать необходиммые дествия
select  что-то from inserted i
where i.[StatusW] = 'в работе' 
except 
select  что-то from deleted d
END
?

Сообщение было отредактировано: 11 июн 21, 09:52
11 июн 21, 09:57    [22334189]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
stsg
Member

Откуда:
Сообщений: 9
HandKot
stsg,

CREATE TRIGGER [Products]
ON [dbo].[tblProducts] AFTER UPDATE AS
IF ( UPDATE ([StatusW]))
BEGIN

--определяем записи, которые получили статус "в работе"
--можно запихать во временную таблицу и потом сделать необходиммые дествия
select  что-то from inserted i
where i.[StatusW] = 'в работе' 
except 
select  что-то from deleted d
END
?


да, использовать временную таблицу inserted, это конечно вариант.. но записей со статусом: i.[StatusW] = 'в работе' может оказаться несколько, а мне нужно, что бы была отмечена только та, в которой изменили статус с "новый" на "в работе"..
Может как то ожно использовать сразу в выражении:
IF ( UPDATE ([StatusW])) = 'в работе' ???
BEGIN
11 июн 21, 10:32    [22334211]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
iap
Member

Откуда: Москва
Сообщений: 47101
Триггер на UPDATE сработает в случае UPDATE таблицы всегда, независимо от каких-то там полей.
И это изменить нельзя.
Функцию UPDATE() в триггере использовать абсолютно бессмысленно.

Приведите пример реальных действий триггера - проще будет отвечать.
11 июн 21, 10:37    [22334217]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
msLex
Member

Откуда:
Сообщений: 9058
stsg
временную таблицу inserted


Это не временная таблица, это "псеводо"-таблица, содержащая все затронутые строки изменяемой таблицы после изменений, deleted - тоже, но до изменений.

вам нужно связать эти таблицы по ключу, и наложить требуемые условия


select ...
from inserted i
inner join deleted d on i. ... = d. ...
where
    i.StatusW = ...
    and d.StatusW  = ...
11 июн 21, 10:37    [22334218]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
iap
Member

Откуда: Москва
Сообщений: 47101
stsg
HandKot
stsg,

CREATE TRIGGER [Products]
ON [dbo].[tblProducts] AFTER UPDATE AS
IF ( UPDATE ([StatusW]))
BEGIN

--определяем записи, которые получили статус "в работе"
--можно запихать во временную таблицу и потом сделать необходиммые дествия
select  что-то from inserted i
where i.[StatusW] = 'в работе' 
except 
select  что-то from deleted d
END

?


да, использовать временную таблицу inserted, это конечно вариант.. но записей со статусом: i.[StatusW] = 'в работе' может оказаться несколько, а мне нужно, что бы была отмечена только та, в которой изменили статус с "новый" на "в работе"..
Может как то ожно использовать сразу в выражении:
IF ( UPDATE ([StatusW])) = 'в работе' ???
BEGIN


...FROM deleted d JOIN inserted i ON d.id=i.id
WHERE i.StatusW='в работе' AND NOT EXISTS(SELECT d.StatusW INTERSECT SELECT i.StatusW)
Здесь id - первичный ключ (у вас чего-то непонятно, что является первичным ключом).
11 июн 21, 10:47    [22334232]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
stsg
Member

Откуда:
Сообщений: 9
msLex
stsg
временную таблицу inserted


Это не временная таблица, это "псеводо"-таблица, содержащая все затронутые строки изменяемой таблицы после изменений, deleted - тоже, но до изменений.

вам нужно связать эти таблицы по ключу, и наложить требуемые условия


select ...
from inserted i
inner join deleted d on i. ... = d. ...
where
    i.StatusW = ...
    and d.StatusW  = ...


Точно, похоже вы правы.. я использовал только inserted без связки с deleted и по этому срабатывал триггер на все записи с StatusW = 'в работе'..
11 июн 21, 10:48    [22334233]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
stsg
Member

Откуда:
Сообщений: 9
Суть задачи такова: есть бд к которой подключены продажи с интернет магазина и с Озона.. так вот, нужно реализовать автоматическое списание (продажу) товара так как управляют продажами из разных мест (например с личного кабинета Озона или с программы на ПК или с сайта компани). Для этого есть единственное связующие звено - это бд. на ms sql. По этому откуда бы не меняли статус заказа, он автоматом меняется в БД..
Вариант с триггером пока подходит лучше всего.
Задача триггера - при изменении статуса в заказе - автоматом создать расходную накладную и списать н.. кол-во заказанного товара для своевременной синхронизации со всеми базами..

Сейчас, вроде задачу решил с добавлением таблицы deleted, вот сам триггер:

CREATE TRIGGER ProductsOzon
ON [dbo].[tblProductsOzon] AFTER UPDATE AS
IF ( UPDATE ([StatusW]))
BEGIN

SELECT * FROM inserted i inner join deleted d ON i.ID = d.ID where i.[StatusW] = 'awaiting_deliver' AND d.StatusW = 'awaiting_packaging';

INSERT INTO [qdfSales] (OperationType, DocumentNumber, DocumentDate, SaleAmount, ClientID, StoreID, UserName)
SELECT 'Продажа с Ozona', (SELECT MAX(DocumentNumber) + 1 FROM qdfSales), GETDATE(), 0, 24, 1, 'auto'
FROM inserted i inner join deleted d ON i.ID = d.ID where i.[StatusW] = 'awaiting_deliver' AND d.StatusW = 'awaiting_packaging';

INSERT INTO [qdfSalesProducts] (Ordinal, ProductID, ProductCode, Product, Quantity, SalePrice, SaleID)
SELECT 1, (SELECT ID FROM tblMain WHERE ProductCode = i.productsoffer_id), i.productsoffer_id, i.productsname,
i.productsquantity, i.productsprice,
(SELECT MAX(ID) FROM qdfSales)
FROM inserted i inner join deleted d ON i.ID = d.ID where i.[StatusW] = 'awaiting_deliver' AND d.StatusW = 'awaiting_packaging';


END
11 июн 21, 11:19    [22334259]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3041
stsg,

мне кажется, что есть ошибка в логике (возможно Вы не всё написали)

INSERT INTO [qdfSales] (OperationType, DocumentNumber, DocumentDate, SaleAmount, ClientID, StoreID, UserName)
SELECT 'Продажа с Ozona', (SELECT MAX(DocumentNumber) + 1 FROM qdfSales), GETDATE(), 0, 24, 1, 'auto'
FROM inserted i inner join deleted d ON i.ID = d.ID where i.[StatusW] = 'awaiting_deliver' AND d.StatusW = 'awaiting_packaging';


т.е Вы вставите одинаковых записей в таблицу, сколько записей было изменено, бес всякой привязке к изменяемой записи
11 июн 21, 12:22    [22334310]     Ответить | Цитировать Сообщить модератору
 Re: Триггер на изменение одного поля в таблице.  [new]
stsg
Member

Откуда:
Сообщений: 9
HandKot
stsg,

мне кажется, что есть ошибка в логике (возможно Вы не всё написали)

INSERT INTO [qdfSales] (OperationType, DocumentNumber, DocumentDate, SaleAmount, ClientID, StoreID, UserName)
SELECT 'Продажа с Ozona', (SELECT MAX(DocumentNumber) + 1 FROM qdfSales), GETDATE(), 0, 24, 1, 'auto'
FROM inserted i inner join deleted d ON i.ID = d.ID where i.[StatusW] = 'awaiting_deliver' AND d.StatusW = 'awaiting_packaging';


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


Проверил - все работает! и вроде все правильно!
>>>(SELECT MAX(DocumentNumber) + 1 FROM qdfSales)<<< - этот запрос просто берет максимальную запись номера документа из таблицы продажи, добавляет 1 (тут просто не может быть несколько результатов)..
11 июн 21, 12:49    [22334336]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить