Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте.
Есть вот такой триггер:
drop trigger if exists `synk_qt`
delimiter $$
CREATE TRIGGER `sync_qt` AFTER UPDATE ON `a_table`
FOR EACH ROW
BEGIN
UPDATE `b_table` SET `p_q` = `a_table.p_q`;
END $$
delimiter;
При его наличие нельзя сделать апдейт записи - выдает ошибку #1054 - Unknown column 'a_table.p_q' in 'field list'. А он должен срабатывать как раз после такого апдейта.
Подскажите, пожалуйста, где ошибка. Я в SQL ноль, мои познания закончились 20 лет назад на DBase 4
Заранее благодарю.
Неактивен
Доброго дня.
`a_table.p_q`
попробуйте заменить на
`a_table`.`p_q`
Неактивен
На самом деле, оно так и написано, я упрощал здесь названия таблиц и полей и промахнулся.
Неактивен
А Вы не упрощайте, приведие ровно так, как есть. и структуру таблички не забудьте приложить ( show create table `t` )
Неактивен
ОК, триггер:
drop trigger if exists `synk_qt`
delimiter $$
CREATE TRIGGER `sync_qt` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
BEGIN
UPDATE amr_jshopping_products SET product_quantity = art_jshopping_products.product_quantity;
END $$
delimiter;
таблица:
Field Type Null Key Default Extra
product_id int(11) NO PRI NULL auto_increment
parent_id int(11) NO MUL NULL
product_ean varchar(32) NO MUL NULL
product_quantity decimal(12,2) NO NULL
unlimited tinyint(1) NO MUL NULL
product_availability varchar(1) NO NULL
product_date_added datetime NO 0000-00-00 00:00:00
date_modify datetime NO 0000-00-00 00:00:00
product_publish tinyint(1) NO MUL NULL
product_tax_id tinyint(3) NO MUL NULL
currency_id int(4) NO MUL NULL
product_template varchar(64) NO default
product_url varchar(255) NO NULL
product_old_price decimal(14,4) NO NULL
product_buy_price decimal(14,4) NO NULL
product_price decimal(18,6) NO MUL NULL
min_price decimal(12,2) NO MUL NULL
different_prices tinyint(1) NO NULL
product_weight decimal(14,4) NO NULL
product_thumb_image varchar(255) NO NULL
product_name_image varchar(255) NO NULL
product_full_image varchar(255) NO NULL
product_manufacturer_id int(11) NO MUL NULL
product_is_add_price tinyint(1) NO NULL
add_price_unit_id int(3) NO MUL NULL
average_rating float(4,2) NO MUL NULL
reviews_count int(11) NO MUL NULL
delivery_times_id int(4) NO MUL NULL
hits int(11) NO MUL NULL
weight_volume_units decimal(14,4) NO NULL
basic_price_unit_id int(3) NO MUL NULL
label_id int(11) NO MUL NULL
vendor_id int(11) NO MUL NULL
access int(3) NO MUL 1
name_en-GB varchar(255) NO NULL
alias_en-GB varchar(255) NO NULL
short_description_en-GB text NO NULL
description_en-GB text NO NULL
meta_title_en-GB varchar(255) NO NULL
meta_description_en-GB text NO NULL
meta_keyword_en-GB text NO NULL
name_ru-RU varchar(255) NO NULL
alias_ru-RU varchar(255) NO NULL
short_description_ru-RU text NO NULL
description_ru-RU text NO NULL
meta_title_ru-RU varchar(255) NO NULL
meta_description_ru-RU text NO NULL
meta_keyword_ru-RU text NO NULL
Неактивен
Не очень пойму смысл триггера Вашего - Вы же ничего не делаете с полем product_quantity.
А вообще NEW нужно указывать
UPDATE amr_jshopping_products SET NEW.product_quantity = art_jshopping_products.product_quantity;
( см. http://dev.mysql.com/doc/refman/5.6/en/ … yntax.html )
Неактивен
Без продвинутого ХШ не понять, но если мой не врет, то подразумевалось что-то вроде:
Неактивен
deadka написал:
Не очень пойму смысл триггера Вашего - Вы же ничего не делаете с полем product_quantity.
А вообще NEW нужно указывать
UPDATE amr_jshopping_products SET NEW.product_quantity = art_jshopping_products.product_quantity;
( см. http://dev.mysql.com/doc/refman/5.6/en/ … yntax.html )
Да, про NEW я уже понял.
Опишу проблему:
есь три и-магазина на джумле. Движки одинаковые, БД общая, таблицы - разные, id товаров одинаковые, цены и описания разные.
Я пытаюсь с помощью триггеров на апдейт синхронизировать остатки всех трех магазинов (склад у них общий).
Идея в том, чтобы на каждую таблицу товара повесить триггер, который при изменении остатка товара будет изменять остаток в 2х других таблицах. Но так получается замкнутый круг. Разорвать его мне кажется можно проверкой if - then - если разницы между новым и старым значением нет, то и апдейт выполнять не нужно. Но что-то я делаю не так, но не понимаю что.
Триггер сейчас вот такой:
DROP TRIGGER IF EXISTS `sync_qt_art`;
CREATE TRIGGER `sync_qt_art` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
BEGIN
IF OLD.`product_quantity` > NEW.`product_quantity` THEN
UPDATE `amr_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
END IF;
END;
Без if - then он работает пока я его не повесил на все три таблицы. Когда повесил на все три БД стала ругаться. Правда триггер с if - then тоже не работает.
Неактивен
Что значит "ругаться"?
Есть ощущение, что вы вообще пошли не тем путем, и вам нужно просто сделать update.
Приведите тестовый набор данных на трех таблицах и какой результат вы хотите получить.
Неактивен
vasya написал:
Что значит "ругаться"?
Есть ощущение, что вы вообще пошли не тем путем, и вам нужно просто сделать update.
Приведите тестовый набор данных на трех таблицах и какой результат вы хотите получить.
Приведу 2 таблицы с полями, которые участвуют в транзакциях (третья - аналогичная):
art_jshopping_products
+-------------+-------------------+
| product_id | product_quantity |
| | |
+-------------+-------------------+
| 1 | 3 |
| 2 | 5 |
+-------------+-------------------+
amr_jshopping_products
+-------------+-------------------+
| product_id | product_quantity |
| | |
+-------------+-------------------+
| 1 | 3 |
| 2 | 5 |
+-------------+-------------------+
Движок 1го магазина изменяет art_jshopping_products.product_quantity с product_id = 2 c 5 на 3, триггер после этого изменения изменяет значение 2ой таблицы amr_jshopping_products.product_quantity с product_id = 2 c 5 на 3. Во второй таблице есть такой же триггер, но с другими префиксами таблиц, который делает эту же операцию с третьей таблицей, а та в свою очередь меняет первую. Это делается для того, чтобы триггеры были максимально простыми (с одним условием). Если продажа произойдет во втором или третьем магазине, их триггеры сработают так же и product_quantity изменится во всех трех таблицах. Но в такой ситуации должно быть условие, по которому этот цикл останавливается (т.е. когда значение product_quantity в двух таблицах одинаковое).
Вот этот триггер делает просто апдейт. Но если из три и действие одного приводит к срабатыванию следующего (и так по кругу), то джумла ругается "Ошибка записи в базу данных", а phpmyadmin говорит, что таблица уже занята триггером
DROP TRIGGER IF EXISTS `sync_qt_art`;
CREATE TRIGGER `sync_qt_art` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
UPDATE `amr_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
Отредактированно pawana (12.04.2015 17:08:17)
Неактивен
А для чего делать триггер с одним условием?
Логично, если при изменении первой таблице триггер обновит значения во второй и третьей, а так вы на ровном месте создаете цикличность, которую потом пытаетесь героически преодолеть.
Неактивен
vasya написал:
А для чего делать триггер с одним условием?
Логично, если при изменении первой таблице триггер обновит значения во второй и третьей, а так вы на ровном месте создаете цикличность, которую потом пытаетесь героически преодолеть.
Ну да, тут Вы правы на все 100.
Но, даже если переделываю триггер, то он все равно вызовет срабатывание аналогичных триггеров в 2х других таблицах. Все равно цикл выходит. И его все равно нужно остановить.
Я повесил вот такой триггер на 3 таблицы (ессно, названия триггера и префиксы разные)
DROP TRIGGER IF EXISTS `sync_qt_tls`;
CREATE TRIGGER `sync_qt_tls` AFTER UPDATE ON `tls_jshopping_products`
FOR EACH ROW
UPDATE `art_jshopping_products`, `amr_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
Выдает такую ошибку: Column 'product_quantity' in field list is ambiguous. Цикл все равно срабатывает.
Неактивен
Если вы хотите обновить значение `product_quantity` в таблицах `art_jshopping_products`, `amr_jshopping_products`, то сделайте 2 update
Неактивен
Ага, понял. Вот пример для двух таблиц.
Неактивен
Сделал вот так:
CREATE TRIGGER `synk_art` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
begin
select `amr_joomshopping_products`.`product_quantity` into @a from `amr_joomshopping_products` where `product_ean` = new.`product_ean`;
if new.`product_quantity` > @a then
UPDATE `amr_joomshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_ean` = new.`product_ean`;
end if;
end
Вылезла ошибка: ошибка #1064 (42000) - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
Неактивен
Извините, просто phpmyadmin - зло
Неактивен
Переделал триггер
delimiter $$
DROP TRIGGER IF EXISTS sync_qt_art;
CREATE TRIGGER `sync_qt_art` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
begin
select amr_jshopping_products.product_quantity into @a from amr_jshopping_products where product_id = new.product_id;
if new.product_id > @a then
UPDATE `amr_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
end if;
end $$
ошибок нет, но значение во второй таблице не изменяется
Неактивен
Называется найдите 10 отличий
Почему у вас new.product_id > @a ?
Неактивен
Извините, не только phpmyadmin, но и нубы тоже зло
Vasya, Deadka, спасибо огроменное вам. Мучения многих лет похоже закончились.
Это итоговый триггер, изменяющий поле с остатком товара в 2 таблицах после апдейта в искомой.
delimiter $$
DROP TRIGGER IF EXISTS `sync_qt_art`;
CREATE TRIGGER `sync_qt_art` AFTER UPDATE ON `art_jshopping_products`
FOR EACH ROW
begin
select amr_jshopping_products.product_quantity into @art1 from amr_jshopping_products where product_id = new.product_id;
if new.product_quantity < @art1 then
UPDATE `amr_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
end if;
select tls_jshopping_products.product_quantity into @art2 from tls_jshopping_products where product_id = new.product_id;
if new.product_quantity < @art2 then
UPDATE `tls_jshopping_products` SET `product_quantity` = NEW.`product_quantity` WHERE `product_id` = new.`product_id`;
end if;
end $$
Остальные триггеры - аналогичные с учетом изменения префиксов и имен переменных.
Жаль нет плюсиков каких-нибудь, я бы три поставил
Отредактированно pawana (12.04.2015 20:00:12)
Неактивен
Ну радоваться рано - это только начало.
Решение плохое. Изменили первую таблицу, триггер меняет данные во второй, в это время вновь изменили первую, триггер на второй лезет в первую и ошибка.
Так что как временное решение пойдет, но дальше смотреть в сторону правки кода джумлы под себя (например, чтобы сразу менять данные во всех трех таблицах).
Неактивен
Я согласен, что решение не идеальное, но хак ядра джумлы тоже не фонтан, там боков еще больше может быть. При небольшой нагрузке на магазин при небольшом кол-ве товара это решение жизнеспособное. Возможно, есть возможность изменить триггеры, типа лока таблицы и очереди на апдейт. Но с учетом, что без вас я и это бы не сделал, то...
Неактивен