Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: создание триггер в субд mysql

Помогите пожалуйста разобраться
При создании триггера появляется предупреждение (скриншот представлен ниже), но он создаётся.
Триггер работает на вычислении разности суммы, если сумма больше заданного поля из другой таблицы на заданный процент, то действие обновления отменяется...
Вот код триггера:
CREATE DEFINER = CURRENT_USER TRIGGER `realtor_agency`.`transaction_AFTER_UPDATE` AFTER UPDATE ON `transaction` FOR EACH ROW
BEGIN
declare sum float;
set sum = (select `price` from `objects` inner join `transaction` where
`objects`.`id_object` = `transaction`.`id_object`);
if (`transaction`.`amount_of_the_transaction` > (sum * 1.07)) then
update `transaction` set `transaction`.`amount_of_the_transaction` = 0;
end if;
END


Ошибка: Error Code: 1242. Subquery returns more than 1 row

К сообщению приложен файл. Размер - 45Kb
Ответ:
Akina
ArtemkaK
нужно именно триггером
Будьте любезны, обоснуйте.

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

Здравствуйте!

Помогите пожалуйста разобраться с триггер функцией
CREATE OR REPLACE VIEW bn."Косметика линии" AS
 SELECT "COSMETICA_POLY".mslink,
    "COSMETICA_POLY".label_ AS "Подпись",
    "COSMETICA_POLY".comment_ AS "Комментарий",
    "COSMETICA_POLY".datechange AS "Дата создания",
    "COSMETICA_POLY".userdomain AS "Автор",
    "COSMETICA_POLY".shape
   FROM bn."COSMETICA_POLY";

-- Создание триггер функции
CREATE OR REPLACE FUNCTION bn.trigger_cosmetica_poly_i()  RETURNS trigger LANGUAGE plpgsql AS
$$
BEGIN
  NEW.mslink := nextval('bn."COSMETICA_POLY_mslink_seq"'::regclass);
  NEW.userdomain := 'Проверка';
  INSERT INTO bn."COSMETICA_POLY"(mslink, shape, label_, comment_, datechange, userdomain)
         VALUES (NEW.mslink, NEW.shape, NEW.label_, NEW.comment_, NEW.datechange, NEW.userdomain);
  RETURN NEW;
END
$$

-- Создание триггера
CREATE TRIGGER cosmetica_poly_i
INSTEAD OF INSERT ON bn."Косметика линии" FOR EACH ROW
EXECUTE PROCEDURE bn.trigger_cosmetica_poly_i ()


Я не совсем понимаю как правильно корректировать поле userdomain в триггер функции, если это поле в представлении имеет другое имя "Автор"? Как это сделать?
Ответ: Спасибо!
Вопрос: Создание триггера.

Здравствуйте. Начинаю писать триггеры. Хочу написать следующий триггер: при добавлении в таблицу ПТС такой строки, в которой будет совпадать ЛИБО VIN, ЛИБО Номер_ПТС, ЛИБО Государственный_знак с уже имеющимися в таблице, необходимо выдавать сообщение: Невозможно добавить строку!

Непосредственно таблица:
CREATE TABLE ПТС (
VIN                      varchar(30) NOT NULL PRIMARY KEY,
Номер_двигателя          varchar(50) NOT NULL UNIQUE REFERENCES Описание_двигателя(Номер_двигателя),
Цвет                     varchar(30) NOT NULL,
Тип_тс                   varchar(20) NOT NULL,
Категория_тс             varchar(15) NOT NULL,
Номер_ПТС                varchar(15) NOT NULL UNIQUE,
Государственный_знак     varchar(15) NOT NULL UNIQUE
);


Мои попытки создания триггера:
CREATE FUNCTION new_PTS()
  RETURNS TRIGGER AS
$$
BEGIN
IF EXISTS(   
         SELECT *
         FROM ПТС
         WHERE VIN IN(
         SELECT VIN
         FROM ПТС))
         THEN        
     RAISE EXCEPTION 'Невозможно добавить строку!';   
   END IF;
   RETURN NULL;
END
$$ LANGUAGE plpgsql;


CREATE TRIGGER new_pp
  AFTER INSERT
  ON ПТС
  FOR EACH ROW
  EXECUTE PROCEDURE new_PTS();


Понимаю, что в функции необходимо, скорее всего, использовать таблицу NEW и с ней как-то взаимодействовать, но как - тоже вопрос.
Ответ: ambasador,

Можно:
Вопрос: Создание триггера, который переносит удаляемую строчку в другую таблицу

Здравствуйте, нужно создать триггер, который срабатывает при удалении и переносит удаляемую строчку в другую таблицу(если ее нет, создает и вставляет, а если она есть то просто добавляет). Вот если таблицы нет, у меня получилось, а вот если она уже создана, я не могу придумать условие
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
ALTER TRIGGER   Клиенты_триггер ON Клиенты
FOR DELETE AS
PRINT 'Попытка удаления'+STR(@@ROWCOUNT)+'строк из таблицы Заказы'
PRINT 'Пользователь'+CURRENT_USER
IF CURRENT_USER!='dbo'
BEGIN
PRINT 'Удаление запрещено' ROLLBACK TRANSACTION
END ELSE
PRINT 'Удаление разрешено'
SELECT *FROM deleted
SELECT *
INTO Клиенты_вспомогательная
FROM deleted
Добавлено через 9 минут
SQL
1
2
3
SELECT *
INTO Клиенты_вспомогательная
FROM deleted
Создает таблицу и переносит
SQL
1
SELECT *FROM Клиенты_вспомогательная
-переносит в уже существующую таблицу. Вот как написать условие, если нет таблицы то 1, а если она есть то 2
Ответ:
Сообщение от danilshik
задание:
1. Для созданной в лабораторной работе № 2 таблицы разработать триггер, запускаемый при удалении строки таблицы. Удаленная строка должна быть переписана во вспомогательную таблицу. Произвести несколько удалений строк в основной таблице и просмотреть содержимое вспомогательной таблицы.
Ну и отлично, в задании нигде не сказано, что вспомогательная таблица не должна существовать на момент первого применения триггера. Можете спокойно создать ее заранее.
Вопрос: Разделение прав и создание триггера

Не пойму в чём затык.

Есть пользователь CREATOR, который создаёт объекты базы и раздаёт всем права.

Есть пользователь REPLICATOR с ролью REPLICATORS, который пытается создать триггер на обновление

CREATE TRIGGER some_table_u FOR some_table
ACTIVE AFTER UPDATE POSITION 0
AS BEGIN
END


и получает сообщение об ошибке:
unsuccessful metadata update
DEFINE TRIGGER failed
no permission for control access to TABLE SOME_TABLE


При этом, если из под REPLICATOR-а запустить
select * from some_table

то это нормально отрабатывает.

Привилегии на таблицу для роли REPLICATORS такие:
GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
 ON some_table TO ROLE REPLICATORS;


Что я не учёл?
Ответ: ArtDen,

А версия сервера какая? Поскольку в 3-ке можно делигировать ALTER TABLE, который позволит создавать триггеры для таблицы.
Вопрос: Триггер в Erwin для базы данных

Здравствуйте, не могу разобраться как написать триггер для представления Enterprise_Indicators, вернее, не могу найти понятной справочной информации.
Необходимо написать триггер, реализующий оценку эффективности работы предприятия. Суть его работы в том, что берутся показатели эффективности работы предприятия и их значения за последний квартал. Среднее значение за квартал для каждого показателя должно быть > 300, если хоть какие-то показатели не удовлетворяют этому требованию, то работу предприятия за квартал можно считать неэффективной, иначе, эффективной.
Как я понял, задача следующая:
1) Найти значения показателей за предыдущий целый квартал, т.е., если сегодня 18.04.2016, то выбираем промежуток с 01.01.2016 по 01.04.2016
2) Подсчитать среднее значение за квартал (Dynamics_of_indicators.Value) для каждого показателя и проверить все ли показатели имеют среднее значение > 300. Значение для каждого показателя поступает 1 раз в месяц, т.е. за квартал нужно найти среднее от трех значений (за 3 месяца).
3) Если хотя бы 1 показатель не удовлетворяет этому условию, то присвоить полю Enterprise_performance значение "Работа неэффективна", в противном случае "Работа эффективна"
Небольшое пояснение: представление Enterprise_Indicators отображает Название предприятия, название показателя (например рост и т.д.), его значение (90, 100 и т.д.), дату(01.01.2016, 01.02.2016 и т.д.), валюту, в которой измеряется показатель и поле "Эффективность работы предприятия" - именно этому полю и нужно присвоить значение после работы триггера.
При создании триггера для представления, сгенерировался шаблон. Вопрос, как его исправить в рамках моей задачи. Схему для базы данных sql server прилагаю.
CREATE TRIGGER %ProcedureOwner(.)%TriggerName ON %TableOwner(.)%TableName
%SQLServerWithOptions %Fire %Actions(",")
%ProcedureProps
AS
/* ERwin Builtin Trigger */
/* %Actions(",") trigger on %TableName */
/* default body for %TriggerName */
BEGIN
DECLARE @NUMROWS int,
@nullcnt int,
@validcnt int,
%PKDecl(,@ins)%decl(bComma,0)%ForEachAtt() {%if(%AttIsPk) {%=(bComma,1)} }%if (%==(%:bComma,1)) {,}
@errno int,
@errmsg varchar(255)

SELECT @NUMROWS = @@rowcount
%ForEachChildRel() {
%RelTemplate
}
%ForEachParentRel() {
%RelTemplate
}
RETURN
ERROR:
raiserror @errno @errmsg
rollback transaction
END
%DBMSDelim
Ответ: Вы правы, это действительно процедура.
При создании процедуры, сгенерировался шаблон:
CREATE PROCEDURE %ProcedureOwner(.)%TemplateName %Parameters
%SQLServerWithOptions %ProcedureProps
AS

Буду рад любым подсказкам.
Вопрос: Кривое создание триггера для CONSTRAINT <name> CHECK (...)

И снова здравствуйте!
Пользую FirebirdSQL Server v2.5.7. При описании таблиц, обычно задаю ограничение на столбец не непосредственно в описании столбца, а через CONSTRAINT с указанием имени, как по привычке, так и для того, чтобы раздать триггеру по CHECK права на используемые им таблицы. Мало того, что триггер создается в двух экземплярах (по одному для INSERT и UPDATE) с именами CHECK_<номер>, так еще и GRANT ... TO TRIGGER <check_constraint_name> не учитывает эту особенность и не раздает права на эти триггеры CHECK_<номер>.
Можно ли как-то поправить эту кривизну в следующих снапшотах, например, созданием одного триггера BEFORE INSERT OR UPDATE с заданным именем ограничения CHECK?
Ответ: hvlad, именно такой workaround и сделал.
Вопрос: Создание триггера!

Есть таблица ZAKAZI в ней 3 поля NAME_KLIENT-имя клиента, SUMMA - цена заказа, STATUS - статус заказа( Купил или нет). Вторая таблица INFO_ZAKAZI хранит информацию о заказах в ней 3 поля KLIENT - имя клиента, ALL_SUMMA - сумма по всем заказам данного клиента, KOL-VO -кол-во заказов данного клиента.
ЗАДАНИЕ: Создать триггер который при переводе заказа из Не купил в Купил( то есть после обновления статуса ) увеличивает кол-во заказов и сумму заказов данного клиента в таблице INFO-ZAKAZI.
Код триггера рабочий:
CREATE OR ALTER TRIGGER ZAKAZ FOR ZAKAZI
ACTIVE AFTER UPDATE POSITION 0
AS begin
IF(NEW.STATUS='Купил') then
update  info_zakaz SET INFO_ZAKAZ.kol_vo=INFO_ZAKAZ.kol_vo+1, INFO_ZAKAZ.all_summa=INFO_ZAKAZ.all_summa+new.summa
WHERE info_zakaz.klient = new.NAME_KLIENT;
IF(NEW.STATUS='Не купил')then
update  info_zakaz SET INFO_ZAKAZ.kol_vo=INFO_ZAKAZ.kol_vo-1, INFO_ZAKAZ.all_summa=INFO_ZAKAZ.all_summa-new.summa
WHERE info_zakaz.klient = new.NAME_KLIENT;
end

Тут предусмотрел если наоборот клиент передумал и отменил заказ то есть изменил Купил на Не КУПИЛ. В задание это не входит но я подумал данный триггер работает только если во второй таблице изначально существуют поля с такимиже именами клиентов как и в первой таблице вообщем решил сделать триггер который срабатывает перед добавлением то есть он смотрит есть ли такой клиент в таблице прежде чем его добавить если нет то создать такого клиента при этом нужно посмотреть сразу статус Купил или Не купил если купил то сразу прибавить к общей сумме и кол-ву во 2ой таблице вот код
create trigger ZAKAZ2 FOR zakazi
ACTIVE after insert
AS begin
per=(SELECT COUNT(*) FROM INFO_ZAKAZ WHERE KLIENT=NEW.NAME_KLIENT);
IF(per>0) THEN
update  info_zakaz SET INFO_ZAKAZ.kol_vo=INFO_ZAKAZ.kol_vo+1, INFO_ZAKAZ.all_summa=INFO_ZAKAZ.all_summa+new.summa
WHERE info_zakaz.klient = new.NAME_KLIENT;
IF(per=0 AND NEW.STATUS='Купил') then
INSERT INTO info_zakaz(KLIENT,KOL_VO,ALL_SUMMA)
VALUES(NEW.NAME_KLIENT,1,NEW.SUMMA);
IF(per=0 AND NEW.STATUS='Не купил') then
INSERT INTO info_zakaz(KLIENT,KOL_VO,ALL_SUMMA)
VALUES(NEW.NAME_KLIENT,0,0);
end

ругаеться на 4 строчку там где переменной присваиваю результат выборки ( в ней смотрю есть ли поля с таким именем ) помогите исправить не как не допру что не так еще нужен триггер после удаления записи из первой таблице но его я сделаю сразу как с этим разберусь может быть так присваивать нельзя или ее нужно объявить где до присваивания ? в ней храниться либо 0 либо число int формата
Ответ:
Симонов Денис
WildSery,

я бы добавил Пропил


А я бы цифиркой заменил - мой посыл изначально в эту сторону был.
Вопрос: Создание триггера по времени

Доброго времени суток, форумчане!
Есть такая задача: написать триггер, который будет срабатывать, например, раз в сутки, т.е. запуск исключительно по времени. Триггер проверяет определенную таблицу, и удаляет оттуда строки, сравнивая значение в строке и текущее время. Пользователь никаких действий не совершает, update, insert и т.п. Я много чего уже пересмотрел, пробовал через задания(sp_add_job), но от меня потребовали именно триггер. Кто-нибудь может что-то посоветовать? Буду благодарен за примеры кода. Использую я MS SQL Server 2005 Express, поэтому можно использовать возможности только его. Использовать полную или более позднюю версию сейчас не имею возможности.
Ответ: windows scheduler в таком случае спасет отца русской демократии
Вопрос: Ошибка при создании триггера

Добрый день
Нечаянно удалил из базы все триггеры на одну таблицу, DDL у меня есть,но при компиляции получаю ошибку.
Триггер:
CREATE DEFINER = 'ukm_server'@'localhost' TRIGGER `local_auth_account_after_upd_tr` AFTER UPDATE ON `local_auth_account`
  FOR EACH ROW
BEGIN
    call wbn_setnotify('account',2,CONCAT('<p>{accId:'',NEW.id,'',accName:'',IFNULL(NEW.name,''),'',credit:'',IFNULL(NEW.credit,''),'',params:'',IFNULL(NEW.params,''),'',closed:'',IFNULL(DATE_FORMAT(NEW.closed,'%d.%m.%Y'),''),''}</p>'),concat('account_',NEW.id));
END;


Ошибка:
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 '%m.%Y'),''),''}</p>'),concat('account_',NEW.id));
END' at line 4
Ответ: ТС, оборачивайте конкатенируемые значения двойными кавычками, а внутри лепите столько одинарных, сколько надо. Без лишних повторений.
select concat("'preved',medved","'''","cccc''c'''''c'c'cc'")
'preved',medved'''cccc''c'''''c'c'cc'