powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проверка записи на существование в триггере
22 сообщений из 22, страница 1 из 1
Проверка записи на существование в триггере
    #38723442
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в тригере пытаюсь проверить, существует ли уже запись в таблице.
триггер AFTER INSERT


Код: sql
1.
2.
DECLARE cnt int(10) DEFAULT 0;
SELECT count(*) INTO @cnt FROM news WHERE MsgID = @MsgID;



переменная @cnt всегда 0.
записи в таблице присутствуют
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723448
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Переменные cnt и @cnt - это разные переменные.
2) А что и откуда в этот момент в переменной @MsgID?
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723471
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. уяснил.

будет ли правильно вот так:
Код: sql
1.
2.
DECLARE @cnt int(10) DEFAULT 0;
SELECT count(*) INTO @cnt FROM news WHERE MsgID = @MsgID;




переменная @MsgID извлекается ранее

Код: sql
1.
set @MsgID := ExtractValue(NEW.xmlData,'//Ident');



это идентификатор новости. он уникальный.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723473
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinnyв тригере пытаюсь проверить, существует ли уже запись в таблице.
триггер AFTER INSERT


Код: sql
1.
2.
DECLARE cnt int(10) DEFAULT 0;
SELECT count(*) INTO @cnt FROM news WHERE MsgID = @MsgID;



переменная @cnt всегда 0.
записи в таблице присутствуют

интересный текст тригера... вроде как NEW.msgid

select ....;
row_count() - число найденых записей при последнем селектеж
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723477
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

ошибочка вышла
FOUND_ROWS()
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723523
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
попробовал как указали раннее:

Код: sql
1.
2.
SELECT * FROM news WHERE MsgID = @MsgID;
SELECT FOUND_ROWS() INTO @cnt;



при обновлении тригера выдает ошибку
Not allowed to return a result set from a trigger
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723528
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinny,

Прежде, чем метаться по разным вариантам синтаксиса, опишите толком задачу.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723602
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinnyпопробовал как указали раннее:

Код: sql
1.
2.
SELECT * FROM news WHERE MsgID = @MsgID;
SELECT FOUND_ROWS() INTO @cnt;



при обновлении тригера выдает ошибку
Not allowed to return a result set from a trigger

круто...я не сталкивался с таким ограничением на тригере, что нельзя селект делать...тогда только как ты - селект инту вар
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723645
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Прошу прощения за нечеткую формулировку задачи. показалось что полностью алгоритм описывать - избыточно.

ниже более подробное описание.

из внешней системы в таблицу синхронизации (replicate_table) приезжают данные в формате xml.

Код: sql
1.
insert into replicate_table (xmlData) Values ('<Root><Type>Message</Type><Action>delete</Action><Ident>55363</Ident><Deleted>0</Deleted><Mm_Sender_Id>782</Mm_Sender_Id><Mm_Sender_Name>mobus</Mm_Sender_Name><Mm_Date>2014-08-18T16:08:02</Mm_Date><Mm_Subject>1116</Mm_Subject><Msg_Text>1116</Msg_Text><Mm_Importance>N</Mm_Importance></Root>');



В этом xml содержится информация о том, что необходимо сделать, какие данные вставить/обновить/удалить.

на эту таблицу (replicate_table) навешен триггер AFTER INSERT
который и разбирает данные.

одно из условий внутри триггера, проверить, существует ли уже запись в системе по переданному идентификатору (<Ident>55363</Ident>). Идентификатор является внешним, и только по нему невозможно полностью удалить сообщение из системы, тк информация о сообщении хранится в нескольких таблицах, под внутренним идентификтором ElementID, который отличается от <Ident></Ident>


в данном случае, в xml содержится информация о удалении сообщения.

сначала необходимо проверить, существует ли данное сообщение в системе, если нет, то создать новое, если есть, то проверить , есть ли инструкции на удаление, и если они есть, то удалить.


Обработка тега <Action> убрана, тк insert и update практически идентичны.

вообщем то загвоздка в проверке существования записей в системе, поскольку селект возвращает всегда 0
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723648
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinnymiksoft,

Прошу прощения за нечеткую формулировку задачи. показалось что полностью алгоритм описывать - избыточно.

ниже более подробное описание.

из внешней системы в таблицу синхронизации (replicate_table) приезжают данные в формате xml.

Код: sql
1.
insert into replicate_table (xmlData) Values ('<Root><Type>Message</Type><Action>delete</Action><Ident>55363</Ident><Deleted>0</Deleted><Mm_Sender_Id>782</Mm_Sender_Id><Mm_Sender_Name>mobus</Mm_Sender_Name><Mm_Date>2014-08-18T16:08:02</Mm_Date><Mm_Subject>1116</Mm_Subject><Msg_Text>1116</Msg_Text><Mm_Importance>N</Mm_Importance></Root>');



В этом xml содержится информация о том, что необходимо сделать, какие данные вставить/обновить/удалить.

на эту таблицу (replicate_table) навешен триггер AFTER INSERT
который и разбирает данные.

одно из условий внутри триггера, проверить, существует ли уже запись в системе по переданному идентификатору (<Ident>55363</Ident>). Идентификатор является внешним, и только по нему невозможно полностью удалить сообщение из системы, тк информация о сообщении хранится в нескольких таблицах, под внутренним идентификтором ElementID, который отличается от <Ident></Ident>


в данном случае, в xml содержится информация о удалении сообщения.

сначала необходимо проверить, существует ли данное сообщение в системе, если нет, то создать новое, если есть, то проверить , есть ли инструкции на удаление, и если они есть, то удалить.


Обработка тега <Action> убрана, тк insert и update практически идентичны.

вообщем то загвоздка в проверке существования записей в системе, поскольку селект возвращает всегда 0

нащот того что селект ноль вернул, тебе написали var и @var Это вде разные переменные

ту что в дикларе описал, не надо с собакой пользовать.

а ваще архитектура вцелом странная. я так полагаю это то, что скрываеться за понтовым словом рест.

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

или ты думаешь твой код поиска записи и анализа результата быстрее отработает чем родной скомпиленый мускла?
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723664
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453,

видимо переделаю алгоритм триггера.

поскольку на один хмл инструкции вставки, необходимо добавлять по одной записи в три разных таблицы, и только две из них содержат внешний ключ MsgID, который берется из <Ident>, а третью таблицу не могу денормализовать, поскольку она системная, и это изменение архитектуры, то буду менять логику самого тригера.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723667
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinny , у Вас совершенно кривой подход. И весьма чреватый, надо сказать - размахать с ним данные в лапшу раз плюнуть...

Напишите хранимую процедуру, которая примет эту XML-строку, распарсит её, выполнить необходимые проверки, и по их итогам аккуратно сделает ровно то, что нужно.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723675
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

эм. хорошо, помогите пожалуйста тогда исправить ошибки.

Код: 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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
BEGIN
DECLARE randName varchar(20);
DECLARE ShortName varchar(50);
DECLARE ElementPath varchar(100);
DECLARE ElementScript varchar(100);
DECLARE ElementName varchar(250);
DECLARE lastID varchar(10);
DECLARE ParentID varchar(10);
DECLARE is_virtual varchar(2);
DECLARE ItemID varchar(10);
DECLARE ItemName varchar(30);
DECLARE TypeItem varchar(50);
DECLARE SQLAction varchar(50);
SET @lastID := 0;
SET @TypeItem := ExtractValue(NEW.xmlData,'//Type');
SET @randName := ROUND(RAND()*(10000-1000)+1000,0);
set @ShortName :=  CONCAT(DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),'-',@randName);
CASE @TypeItem
	WHEN 'message'
	THEN
		BEGIN
			DECLARE MsgID varchar(20);
			DECLARE isDeleted int(2);
			set @MsgID := ExtractValue(NEW.xmlData,'//Ident');
			set @SQLAction := ExtractValue(NEW.xmlData,'//Action');
			
			set @ElementPath := CONCAT('/news/',@ShortName,'.html');
			set @ItemID := '12';
			set @is_virtual := '2';
			set @ParentID := '38';
			set @ItemName := 'wr_item_news';
			set @ElementScript := 'news/item';
			SET @ElementName := ExtractValue(NEW.xmlData,'//Mm_Subject');
			SET @isDeleted := ExtractValue(NEW.xmlData,'//Deleted');
			
		
			SELECT Count(MsgID) INTO @MsgCount FROM wr_item_news WHERE MsgID = @MsgID;
			IF(@MsgCount = 0)
			THEN
				INSERT INTO wr_main (
					ParentID,
					ElementName, 
					ItemID, 
					ItemName,
					isNode, 
					ElementOrder, 
					ElementPath, 
					ElementScript, 
					ShortName, 
					is_virtual, 
					HostName) 
		
				VALUES( 
					@ParentID, 
					@ElementName, 
					@ItemID,  
					@ItemName, 
					'2', 
					'0',  
					@ElementPath, 
					@ElementScript, 
					@ShortName, 
					@is_virtual,
					'*'
				);

				SET @lastID := LAST_INSERT_ID();
				INSERT INTO wr_item_news (
					ElementID,
					ParentID,
					ElementName,
					created,
					modified,
					dat,
					Sender,
					descr,
					Importance,
					`hash`,
					MsgID
				) 
				VALUES( 
					@lastID,
					@ParentID,
					@ElementName,
					UNIX_TIMESTAMP(),
					UNIX_TIMESTAMP(),
					UNIX_TIMESTAMP(STR_TO_DATE(ExtractValue(NEW.xmlData,'//Mm_Date'),'%Y-%m-%dT%H:%i:%s')),
					ExtractValue(NEW.xmlData,'//Mm_Sender_Name'),
					ExtractValue(NEW.xmlData,'//Msg_Text'),
					IF (ExtractValue(NEW.xmlData,'//Mm_Importance') = 'Y' ,'1', '0' ),
					MD5(@MsgID),
					@MsgID
					) ON DUPLICATE KEY UPDATE modified=UNIX_TIMESTAMP();
			ELSE
				IF(@isDeleted = 1 OR @SQLAction = 'delete')
				THEN
					DELETE FROM wr_main WHERE ElementID = ( SELECT ElementID FROM wr_item_news WHERE MsgID = @MsgID);
					DELETE FROM wr_item_newsrecipients WHERE MsgID = @MsgID;
					DELETE FROM wr_item_news WHERE MsgID = @MsgID;
				END IF; 
			END IF;
				
		END;
	WHEN 'Message_Ref'
	THEN
		BEGIN
		
		INSERT INTO wr_item_newsrecipients (
				ParentID,
				Recipient,
				IsRead,
				MsgID
			) 
			SELECT 
				@lastID,
				ExtractValue(NEW.xmlData,'//Mf_Receiver_Name'),
				IF (ExtractValue(NEW.xmlData,'//Mf_Message_Read') = 'Y' ,'1', '0' ),
				ExtractValue(NEW.xmlData,'//Mf_Message_Id')
				;
				
		END;
	END CASE;
END
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723692
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибок две.
Первая - вместо того, чтобы выбросить всё нахрен и написАть с нуля, но в форме процедуры, предпринимается попытка "исправить". Она основаная, идеологическая.

Вторая - декларируется хренова гора переменных, которые потом не используются. Она синтаксическая и, в общем, безобидная.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723698
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

вообщем то, код и написан с нуля. в форме процедуры или триггера - помоему не сильно важно. возможно ошибаюсь, поясните.

синтаксические ошибки помогите исправить.


идея вынести основную логику в процедуру и вызывать из тригера ее, была, просто не дошел до этого момента, тк споткнулся на сабж топика.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723707
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nevinnyв форме процедуры или триггера - помоему не сильно важноno comments
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723755
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akinanevinnyв форме процедуры или триггера - помоему не сильно важноno comments

авторвозможно ошибаюсь, поясните.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723775
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поясняю.
1) Триггер жёстко привязан к записи, добавление/удаление/изменение которой вызвало срабатывание триггера. Процедура такой привязки не имеет.
2) Триггер ограничен в перечне используемых конструкций. В т.ч. и как следствие из 1-го отличия. Ограничения у процедур несколько мягче.
3) Триггер гарантированно срабатывает только на определённый и, к сожалению, не исчерпывающий, набор действий, формально выполняющий условия срабатывания. Процедура при вызове выполняется безусловно.
4) Триггер выполняется линейно (выполнение триггера для следующей запписи набора начинается только после завершения выполнения триггера для предыдущей записи) и, емнип, однозадачно (т.е. не могут одновременно выполняться два тела одного триггера, инициированные двумя разными запросами). Экземпляры процедур выполняются параллельно.
5) Триггер всегда обрабатывает только одну запись инициирующего набора. Процедура не имеет такого ограничения.

Эти отличия (и куча прочих) имеют следствием то, что подход при написании триггера и процедуры различен.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723803
nevinny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Спасибо за пояснения, очень помогли! )

решил свою проблему с помощью процедур.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723804
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akinaне могут одновременно выполняться два тела одного триггера, инициированные двумя разными запросамиЭм... Это точно?
Не вижу никаких логичных причин для этого...
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723889
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftAkinaне могут одновременно выполняться два тела одного триггера, инициированные двумя разными запросамиЭм... Это точно?
Не вижу никаких логичных причин для этого...
Если это НЕ так - триггер просто обязан блокировать как минимум текущую запись на всё время своей работы. В противном случае возможна параллельная работа двух экземпляров триггера над одной и той же записью, что потенциально приведёт к нарушению целостности и/или разрушению данных. А с учётом того, что триггеру позволено изменять данные других таблиц - он должен блокировать также и их, по тем же причинам.
...
Рейтинг: 0 / 0
Проверка записи на существование в триггере
    #38723911
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akinamiksoftпропущено...
Эм... Это точно?
Не вижу никаких логичных причин для этого...
Если это НЕ так - триггер просто обязан блокировать как минимум текущую запись на всё время своей работы. Это и так происходит. В случае MyISAM блокируется вся таблица. В случае InnoDB блокируется, как минимум, изменяемая запись.
Все равно не вижу, почему один и тот же триггер не может работать одновременно над двумя разными записями в двух разных сессиях.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проверка записи на существование в триггере
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]