Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
 Аватар для VladSharikov
25 / 25 / 7
Регистрация: 02.12.2010
Сообщений: 824

Тригер, проверяющ. есть ли такой ID и если есть обновляющий его, если нет - добавляющий

02.06.2013, 02:34. Показов 1751. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сабж.
В MSSQL нуб.

Есть ситуация. Добавляю товар из каталога поставщика в каталог магазина.
Может быть такое, что мы заказываем один и тот же товар второй раз. Нужно написать триггер учитывающий этот момент.
Задачи триггера:
1. Добавление/изменение записи.
2. Обновления количества в таблице каталога поставщика.

Я понимаю, что триггер должен быть по событию INSERT. Как я понял понятия "перед" или "после" нету, есть только после -AFTER. В других БД есть ON DUPLICATE KEY, как я понял, здесь такого нету. будем пробовать биться без этой фишки.

Вот что я наискал, надумал и т.п. Код не мой, я в нем разбирался, изменял. По нему будут вопросы.
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
CREATE TRIGGER insert_trigger
ON OrdersGoodsSup FOR INSERT
AS
DECLARE @count INT, @id INT
IF @@ROWCOUNT=1
--в таблицу Сделка добавляется запись 
--о поставке товара
BEGIN
--если записи о товаре еще нет,
--добавляется соответствующая запись
--в таблицу OrdersGoodsSup
  IF NOT EXISTS ( SELECT * FROM inserted i, SuppliersGoods S WHERE S.ID=i.GoodID )
      INSERT INTO OrdersGoodsSup(GoodID, Count) values (-- что тут писать?--)
  ELSE
--если запись о товаре уже была в таблице 
--OrdersGoodsSup, то определяется код и количество 
--товара из добавленной в таблицу OrdersGoodsSup записи
  BEGIN
    SELECT @id=i.GoodID, @count=i.Count
    FROM SuppliersGoods S, inserted i
    WHERE S.ID=i.GoodID
--и производится изменения количества товара в
--таблице OrdersGoodsSup
    UPDATE OrdersGoodsSup
    SET Count=Count+@count
    WHERE OrdersGoodsSup.GoodID=@id
  END
 
  UPDATE SuppliersGoods set Count = Count - @count where SuppliersGoods.ID = @id
END
- Какой смысл в переменной inserted?
Дальше по строкам:
5. @@ROWCOUNT=1. Сама глобальная переменная - считает количество записей в таблице.
а) Хочу уточнить. Количество записей во всей таблице или именно с этим ID?
б) Еще момент. =1 почему? потому что у нас триггер срабатывает после и у нас уже добавлена запись получается?
13. Не очень понимаю, что нужно писать в values. В других бд видел что-то вроде "new.xxxx", где xxx название поля - это и было значением добавленным. нужно вставить что-то из inserted?
18-27 правильно ли тут поступаю? сюда попали по неуд условию, значит здесь записи есть и мы их обновляем. так сделал?
29. правильно ли обновляю количество товара у поставщика.

может вопросы и тупые, но проверить этого не могу из-за того, что не знаю что писать в values в 13 строке.

есть желающие выручить?)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.06.2013, 02:34
Ответы с готовыми решениями:

триггеры на проверку если запись есть то пропустить если нет то добавить...
есть триггер но он работает только при добавлении одной записи.... мне нужно что бы он просматривал все....заранее благодарен)))) Alter ...

Обработка символьных данных. Yes, если есть символ в строке и NO если его нет
Здравствуйте! Помогите решить задачу: Если в данный текст входит любая из букв слова key, напечатать да, если не входит то нет. #include...

Если есть форма и есть событие, а процедуры, его обрабатывающей нет в исходниках, то как это событие обрабатывается?
Друзья! Изучаю синтаксис дельфи. Ну то есть к примеру такой код: procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char); ...

9
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
02.06.2013, 14:33
1. inserted - временная таблица с вставляемыми записями
2. @@ROWCOUNT=1 - триггер для групповой вставки работать не будет, а только для вставки по одной записи
3. value - список вставляемых значений - констант и выражений. inserted пользоваться можно как обычной таблицей
заменил бы на INSERT INTO OrdersGoodsSup(GoodID, Count) SELECT i.GoodID,i.Count FROM inserted i
4. Count - неудачное название поля из ключевых слов T-SQL
5. Значение @count не определено в при вставке, поэтому в последнем UPDATE будут проблемы
0
 Аватар для VladSharikov
25 / 25 / 7
Регистрация: 02.12.2010
Сообщений: 824
02.06.2013, 21:02  [ТС]
Цитата Сообщение от Аватар Посмотреть сообщение
@@ROWCOUNT=1 - триггер для групповой вставки работать не будет, а только для вставки по одной записи
как понять групповой? я и буду вставлять по одной записи.

в любом случае - не получается пока. давайте с другово бока.

пока что уберем update количества в SuppliersGoods
у меня есть таблица SuppliersGoods, есть таблица OrdersGoodsSup. Из первой во вторую добавляются товары. Вторая это корзина.
SuppliersGoods - ID, Name, Count, Price
OrdersGoodsSup - ID, GoodID, Count, Price, OrderID (связь с номером заказа)
Вторая связана с первой по GoodID.

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

Например:
SuppliersGoods
+----+------+------+------+
| ID |Name | Count| Price |
+----+------+------+------+
| 5 |Good1| 50 | 500 |
+----+------+------+------+
| 6 |Good2| 80 | 500 |
+----+------+------+------+

OrdersGoodsSup
+----+-------+------+------+
| ID |GoodID | Count| Price |
+----+-------+------+------+
| | | | |
+----+-------+------+------+

это состояние в первый момент.

первое добавление:
T-SQL
1
insert into OrdersGoodsSup (GoodID, Count, Price) values (5, 10, 500)
SuppleirsGoods - не меняется
OrdersGoodsSup
+----+-------+------+------+
| ID |GoodID | Count| Price |
+----+-------+------+------+
| 1 | 5 | 10 | 500 |
+----+-------+------+------+

T-SQL
1
insert into OrdersGoodsSup (GoodID, Count, Price) values (5, 20, 500)
SuppleirsGoods - не меняется
OrdersGoodsSup
+----+-------+------+------+
| ID |GoodID | Count| Price |
+----+-------+------+------+
| 1 | 5 | 30 | 500 |
+----+-------+------+------+
ТАК ДОЛЖНО БЫТЬ.

У меня работает триггер неправильно. У меня после двух таких запросов содержимое таблицы OrdersGoodsSup будет таким.
+----+-------+------+------+
| ID |GoodID | Count| Price |
+----+-------+------+------+
| 1 | 5 | 10 | 500 |
+----+-------+------+------+
| 2 | 5 | 30 | 500 |
+----+-------+------+------+
Это неправильно. Должно обновиться.
Мало того, если в таблице OrdersGoodsSup были такие же товары, заканные несколькими заказами ранее - они обновятся. То есть для них триггер срабатывает. Я думаю это изза того, что мы не учитываем OrderID.

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ALTER TRIGGER [dbo].[insert_trigger]
ON [dbo].[OrdersGoodsSup] FOR INSERT
AS
DECLARE @count INT, @id INT
SELECT @id=i.GoodID, @count=i.Count
FROM SuppliersGoods S, inserted i
WHERE S.ID=i.GoodID
IF @@ROWCOUNT=1
--в таблицу Сделка добавляется запись 
--о поставке товар
BEGIN
--если записи о товаре еще нет,
--добавляется соответствующая запись
--в таблицу OrdersGoodsSup
  IF NOT EXISTS ( SELECT * FROM inserted i, SuppliersGoods S, SuppliersOrders O WHERE S.ID=i.GoodID and i.OrderID = O.ID)
      INSERT INTO OrdersGoodsSup(OrderID, GoodID, Count) SELECT i.OrderID, i.GoodID,i.Count FROM inserted i
  ELSE
--если запись о товаре уже была в таблице 
--OrdersGoodsSup, то определяется код и количество 
--товара из добавленной в таблицу OrdersGoodsSup записи
  BEGIN
--и производится изменения количества товара в
--таблице OrdersGoodsSup
    UPDATE OrdersGoodsSup
    SET Count=Count+@count
    WHERE OrdersGoodsSup.GoodID=@id
  END
END
что я делаю не так?
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
03.06.2013, 00:08
Цитата Сообщение от VladSharikov Посмотреть сообщение
что я делаю не так?
Если кратко - все.
Начнем с того, что триггер for (after) insert срабатывает после соответствующей инструкции. Т.е., при попытке добавить в корзину позицию, которая там уже есть, вы получите в лучшем случае, если у вас хотя-бы нужные ограничения есть на таблице, соответствующую ошибку, в худшем, - бардак в таблице.
Триггер должен быть instead of insert и в нем использовать инструкцию merge, если версия сервера позволяет.
0
 Аватар для VladSharikov
25 / 25 / 7
Регистрация: 02.12.2010
Сообщений: 824
03.06.2013, 00:40  [ТС]
invm, о, о, о)) намного ближе к теме. очень похоже на ON DUPLICATE KEY

T-SQL
1
2
3
4
5
6
7
8
    MERGE OrdersGoodsSup AS ogs 
    USING inserted AS i 
    ON ogs.GoodID = i.GoodID
    WHEN MATCHED THEN
    --UPDATE SET column1 = value1 [, column2 = value2 ...]
 
    WHEN NOT MATCHED THEN
    --INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...
первое. ругается на 3 строчку. говорит, что условие не является логическим (короче не true/false). почему?
второе. я правильно подобрал table_target - OrdersGoodsSup и table_source - inserted?

по идее я сравниваю то, что мы пытаемся вставить с тем, что уже вставлено. и если есть соответствие по этим полям, то MATCHED, если нет, то NOT. почему не работает?
SQL Server 2012.
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
03.06.2013, 09:27
VladSharikov, покажите полностью оригинальный текст триггера.
0
 Аватар для VladSharikov
25 / 25 / 7
Регистрация: 02.12.2010
Сообщений: 824
03.06.2013, 18:17  [ТС]
invm, вы сказали использовать merge, я начал делать заново. это не чей-то скрипт. это я сам уже делаю и походу спрашиваю у вас.
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
ALTER TRIGGER [dbo].[insert_trigger]
ON [dbo].[OrdersGoodsSup] 
INSTEAD OF INSERT
AS
MERGE OrdersGoodsSup AS ogs 
USING inserted AS i 
ON ogs.GoodID = i.GoodID
WHEN MATCHED THEN
--UPDATE SET column1 = value1 [, column2 = value2 ...]
 
WHEN NOT MATCHED THEN
--INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
03.06.2013, 18:24
Ну так зачем вы merge комментариями покорежили? Напишите ее полностью, согласно синтаксису.
0
 Аватар для VladSharikov
25 / 25 / 7
Регистрация: 02.12.2010
Сообщений: 824
03.06.2013, 18:52  [ТС]
invm, ой красота вообще))) спасибо вам огромное)))

не думал, что из-за этого будут проблемы! не встречал такого никогда. все заработало!

Вот правильный триггер:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
ALTER TRIGGER [dbo].[insert_trigger]
ON [dbo].[OrdersGoodsSup] 
INSTEAD OF INSERT
AS
MERGE OrdersGoodsSup AS ogs 
USING inserted AS i 
ON ogs.GoodID = i.GoodID and ogs.OrderID = i.OrderID
WHEN MATCHED THEN
UPDATE SET ogs.Count = ogs.Count + i.Count
WHEN NOT MATCHED THEN
INSERT (GoodID, Count, OrderID) VALUES (i.GoodID, i.Count, i.OrderID);
GO
0
0 / 0 / 0
Регистрация: 06.10.2014
Сообщений: 24
12.11.2015, 08:44
VladSharikov,
Доброго Вам дня..
Вижу Вы сами разбирались с "лексикой" SQL. Я тоже только начинаю изучать. Подскажите - как правильно задать событие, чтобы триггер сработал? При чём на одной базе он работал, а на созданной вновь не хочет. Понимаю, что какая-то ошибка, только не могу найти где.. Select-ы для баз работают.. А триггер должен удалять записи об авторах, книг которых не осталось в библиотеке. Вот он сам:
T-SQL
1
2
3
4
5
6
7
8
create TRIGGER Del_trig 
 ON dbo.Books
 instead of DELETE
 AS 
 delete from dbo.Books_Authors where Book_Kod in(select kod from deleted)
 delete from dbo.Books_Readers where Book_Kod in(select kod from deleted)
 delete from dbo.books where Kod in(select kod from deleted)
 delete from dbo.Authors where Kod not in(select Author_Kod from dbo.Books_Authors)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.11.2015, 08:44
Помогаю со студенческими работами здесь

Машина Тьюринга: Удалить из слова Р его второй символ, если такой есть
Машина Тьюринга 1. А={a,b}. Удалить из слова Р его второй символ, если такой есть. 2. A={a,b,c}. Приписать слева к слову P символ b...

Машина Тьюринга. Удалить из слова P его третий символ, если такой есть
A={a,b}. Удалить из слова P его третий символ, если такой есть.

Дан массив X(N). Найти наибольший элемент и поменять его местами с первым положительным элементом, если такой есть
Дан массив X(N). Найти наибольший элемент и поменять его местами с первым положительным элементом, если такой есть. Вроде как понял,...

Если в диапазоне есть время больше указанного,то 500,если нет - 0
Вопрос связан с расчетом зарплаты. Есть отдельно табель учета времени прихода/ухода, на сколько опоздал и тд. Нужно, чтобы если человек...

Создание системной переменной если её нет и удаление если есть (setenv)
Нужен своеобразный переключатель определенной системной переменной с помощью утилиты setenv. Суть его работы: Если переменная VAR...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru