Чтобы сделать как ответ выше, вы можете переопределить метод фрагмента onAttach
:
public static class DummySectionFragment extends Fragment{
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
DBHelper = new DatabaseHelper(activity);
}
}
В качестве обходного пути вы можете использовать временную метку (старую и новую) для проверки, но это not обновляется, если в строке нет изменений. (Возможно, это источник путаницы? Потому что этот тоже называется «при обновлении», но не выполняется, когда не происходит никаких изменений). Изменения в течение одной секунды не будут выполнять ту часть триггера, но в некоторых случаях это может быть хорошо (например, когда у вас есть приложение, которое все равно отклоняет быстрые изменения.)
Например, вместо
IF NEW.a <> OLD.a or NEW.b <> OLD.b /* etc, all the way to NEW.z <> OLD.z */
THEN
INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ;
END IF
вы можете использовать
IF NEW.ts <> OLD.ts
THEN
INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ;
END IF
Then
РЕДАКТИРОВАТЬ: Добавлен полный пример
create table foo (a INT, b INT, ts TIMESTAMP);
create table bar (a INT, b INT);
INSERT INTO foo (a,b) VALUES(1,1);
INSERT INTO foo (a,b) VALUES(2,2);
INSERT INTO foo (a,b) VALUES(3,3);
DELIMITER ///
CREATE TRIGGER ins_sum AFTER UPDATE ON foo
FOR EACH ROW
BEGIN
IF NEW.ts <> OLD.ts THEN
INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b);
END IF;
END;
///
DELIMITER ;
select * from foo;
+------+------+---------------------+
| a | b | ts |
+------+------+---------------------+
| 1 | 1 | 2011-06-14 09:29:46 |
| 2 | 2 | 2011-06-14 09:29:46 |
| 3 | 3 | 2011-06-14 09:29:46 |
+------+------+---------------------+
3 rows in set (0.00 sec)
-- UPDATE without change
UPDATE foo SET b = 3 WHERE a = 3;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
-- the timestamo didnt change
select * from foo WHERE a = 3;
+------+------+---------------------+
| a | b | ts |
+------+------+---------------------+
| 3 | 3 | 2011-06-14 09:29:46 |
+------+------+---------------------+
1 rows in set (0.00 sec)
-- the trigger didn't run
select * from bar;
Empty set (0.00 sec)
-- UPDATE with change
UPDATE foo SET b = 4 WHERE a=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- the timestamp changed
select * from foo;
+------+------+---------------------+
| a | b | ts |
+------+------+---------------------+
| 1 | 1 | 2011-06-14 09:29:46 |
| 2 | 2 | 2011-06-14 09:29:46 |
| 3 | 4 | 2011-06-14 09:34:59 |
+------+------+---------------------+
3 rows in set (0.00 sec)
-- and the trigger ran
select * from bar;
+------+------+---------------------+
| a | b | ts |
+------+------+---------------------+
| 3 | 4 | 2011-06-14 09:34:59 |
+------+------+---------------------+
1 row in set (0.00 sec)
Он работает, когда вы обновляете схему (вопрос, который вы упомянули в вопросе.) из-за поведения mysql при обработке временных меток. Временная метка обновляется только в том случае, если в обновлениях произошли изменения.
Документация находится здесь: https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization. html
desc foo;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| a | int(11) | YES | | NULL | |
| b | int(11) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
Используйте следующий запрос, чтобы увидеть, какие строки имеют изменения:
(select * from inserted) except (select * from deleted)
Результаты этого запроса должны состоять из всех новых записей, отличных от старых.
MYSQL TRIGGER BEFORE UPDATE IF OLD.a<>NEW.b
USE `pdvsa_ent_aycg`;
DELIMITER $$
CREATE TRIGGER `cisterna_BUPD` BEFORE UPDATE ON `cisterna` FOR EACH ROW
BEGIN
IF OLD.id_cisterna_estado<>NEW.id_cisterna_estado OR OLD.observacion_cisterna_estado<>NEW.observacion_cisterna_estado OR OLD.fecha_cisterna_estado<>NEW.fecha_cisterna_estado
THEN
INSERT INTO cisterna_estado_modificaciones(nro_cisterna_estado, id_cisterna_estado, observacion_cisterna_estado, fecha_cisterna_estado) values (NULL, OLD.id_cisterna_estado, OLD.observacion_cisterna_estado, OLD.fecha_cisterna_estado);
END IF;
END
НО представьте себе большую таблицу с изменяющимися столбцами. Вы должны сравнить каждый столбец, и если в базе данных изменится настройка триггера. И не «хорошо» сравнивать каждую строку с жестким кодом:)
blockquote>Да, но это способ продолжения.
В качестве побочного примечания, это также Перед тем, как обновить, проверьте правильную практику:
UPDATE foo SET b = 3 WHERE a=3 and b <> 3;
В вашем примере это позволит обновить (и, таким образом, переписать) две строки вместо трех.
UPDATE
(update + trigger), если есть необходимость. Ваш чек просто замедляет работу.
– Johan
9 June 2011 в 17:56
Здесь, если какая-либо строка влияет на новую вставку, тогда она будет обновляться в другой таблице в базе данных.
DELIMITER $$
CREATE TRIGGER "give trigger name" AFTER INSERT ON "table name"
FOR EACH ROW
BEGIN
INSERT INTO "give table name you want to add the new insertion on previously given table" (id,name,age) VALUES (10,"sumith",24);
END;
$$
DELIMITER ;
Вы можете сделать это, сравнивая каждое поле, используя оператор NULL-safe equals <=>
, а затем , отрицая результат, используя NOT
.
Полный триггер станет следующим:
DROP TRIGGER IF EXISTS `my_trigger_name`;
DELIMITER $$
CREATE TRIGGER `my_trigger_name` AFTER UPDATE ON `my_table_name` FOR EACH ROW
BEGIN
/*Add any fields you want to compare here*/
IF !(OLD.a <=> NEW.a AND OLD.b <=> NEW.b) THEN
INSERT INTO `my_other_table` (
`a`,
`b`
) VALUES (
NEW.`a`,
NEW.`b`
);
END IF;
END;$$
DELIMITER ;
(На основании другого ответа моего .)
Я не могу ответить, поэтому просто будьте осторожны, если в столбце поддерживаются значения NULL, OLD.x & lt;> NEW.x не достаточно, потому что
SELECT IF(1<>NULL,1,0)
возвращает 0 как и
NULL<>NULL 1<>NULL 0<>NULL 'AAA'<>NULL
Таким образом, он не будет отслеживать изменения FROM и TO NULL
Правильный способ в этом сценарии -
((OLD.x IS NULL AND NEW.x IS NOT NULL) OR (OLD.x IS NOT NULL AND NEW.x IS NULL) OR (OLD.x<>NEW.x))
COALESCE()
, который возвращает первый из своих аргументов, который не является NULL
. Таким образом, вы можете записать его как IF COALESCE(OLD.X,'') <> COALESCE(NEW.X,'')
– Lyman Zerga
5 February 2014 в 02:20
<=>
.
– djmj
27 March 2014 в 02:27