在本文中,我们将详细介绍PLPGSQL级联触发器?的各个方面,并为您提供关于sql触发器级联更新的相关解答,同时,我们也将为您带来关于mysql级联删除、MySQL级联删除和级联修改、MySQL级联复
在本文中,我们将详细介绍PLPGSQL级联触发器?的各个方面,并为您提供关于sql触发器级联更新的相关解答,同时,我们也将为您带来关于mysql级联删除、MySQL级联删除和级联修改、MySQL级联复制(A->B->C)、MYSQL级联查询,包括向上向下的级联的有用知识。
本文目录一览:PLPGSQL级联触发器?(sql触发器级联更新)
我试图创建一个触发器,以便每当我添加一条新记录时,它都会在同一张表中添加另一条记录。会话字段将仅采用1到4之间的值。因此,当我在会话中添加1时,我希望它添加另一条记录,但会话3被阻止。但是问题在于,这会导致级联触发器,并且一次又一次地插入自身,因为触发器是在插入时触发的。
例如,我有一个简单的表:
CREATE TABLE example(id SERIAL PRIMARY KEY,name VARCHAR(100) NOT NULL,session INTEGER,status VARCHAR(100));
我的触发函数是:
CREATE OR REPLACE FUNCTION add_block() RETURNS TRIGGER AS $$BEGININSERT INTO example VALUES (NEW.id + 1, NEW.name, NEW.session+2, ''blocked'');RETURN NULL;END;$$ LANGUAGE ''plpgsql'';
触发是:
CREATE TRIGGER add_blockAFTER INSERT OR UPDATEON exampleFOR EACH ROWEXECUTE PROCEDURE add_block();
我收到错误消息:
SQL statement "INSERT INTO example VALUES ( $1 +1, $2 , $3 + 2, $4)"PL/pgSQL function "add_block" line 37 at SQL statement
这个错误重复了很多次,以至于我看不到顶部。
我该如何解决?
编辑:
CREATE TABLE block_rules(id SERIAL PRIMARY KEY,session INTEGER,block_session INTEGER);
该表包含阻止规则。因此,如果将新记录插入到具有会话1的示例表中,则它会通过在上面的同一张(示例)表(而非block_rules)中插入具有阻塞状态的新记录来相应地阻塞会话3。会话2相同,但会阻止会话4。
block_rules表保存阻止会话的规则(或模式)。它拥有
id | session | block_session------------------------------1 | 1 | 32 | 2 | 43 | 3 | 2
我如何将其放在触发器的WHEN语句中,以及下面的Erwin Branstetter的答案?
谢谢
答案1
小编典典已编辑问题的新答案
此触发功能根据表中的信息添加被阻止的会话block_rules
。
我 假设 这些表是通过链接链接的id
-信息在问题中丢失了。
我现在假设阻止规则是所有会话的通用规则,并通过链接session
。仅针对非阻塞会话调用触发器,并插入匹配的阻塞会话。
触发功能:
CREATE OR REPLACE FUNCTION add_block() RETURNS TRIGGER AS$BODY$BEGIN INSERT INTO example (name, session, status) VALUES (NEW.name ,(SELECT block_session FROM block_rules WHERE session = NEW.session) ,''blocked''); RETURN NULL;END;$BODY$ LANGUAGE plpgsql;
扳机:
CREATE TRIGGER add_blockAFTER INSERT -- OR UPDATEON exampleFOR EACH ROWWHEN (NEW.status IS DISTINCT FROM ''blocked'')EXECUTE PROCEDURE add_block();
回答原始问题
仍有改进的空间。考虑以下设置:
CREATE OR REPLACE FUNCTION add_block() RETURNS TRIGGER AS$BODY$BEGININSERT INTO example (name, session, status)VALUES (NEW.name, NEW.session + 2, ''blocked'');RETURN NULL;END;$BODY$ LANGUAGE plpgsql;CREATE TRIGGER add_blockAFTER INSERT -- OR UPDATEON exampleFOR EACH ROWWHEN (NEW.session < 3)-- WHEN (status IS DISTINCT FROM ''blocked'') -- alternative guess at filterEXECUTE PROCEDURE add_block();
要点:
对于PostgreSQL 9.0或更高版本, 您可以在触发器定义中使用 WHEN条件 。这将是最有效的。对于较旧的版本,您在触发函数中使用相同的条件。
有 没有必要添加一列 ,如果你能定义的标准来辨别自动插入的行。您没有告诉,因此
session > 2
在我的示例中我假设只有自动插入的行。我添加了替代WHEN
条件status = ''blocked''
作为评论。您应该 始终 提供INSERT的 列列表 。如果不这样做,以后对该表进行更改可能会产生意想不到的副作用!
千万 不能 插
NEW.id + 1
在触发手动。这不会 增加序列 ,而下一个 序列INSERT
将因重复的键冲突而失败。id
是serial
专栏,所以什么也不要做。nextval()
序列中的默认值将自动插入。您的描述仅提及
INSERT
,但是您有一个触发器AFTER INSERT OR UPDATE
。我剪掉了UPDATE
一部分。关键字
plpgsql
不必加引号。
mysql级联删除
DELETE a,bFROM a LEFT JOIN b ON a.id=b .group_id WHERE a.id= xxxx
MySQL级联删除和级联修改
1、新建主键table
1 create table demo1_zhujian (
2 id int primary key auto_increment,
3 name varchar(10));
2、新建外键table
1 create table demo2_waijian (
2 id int primary key auto_increment,
3 _id int not null default 0,
4 name varchar(10),
5 index (_id),
6 FOREIGN KEY (_id) REFERENCES demo1_zhujian(id) ON DELETE CASCADE ON UPDATE CASCADE);
7
8 create table demo3_waijian (
9 id int primary key auto_increment,
10 _id int not null default 0,
11 name varchar(10),
12 index (_id),
13 FOREIGN KEY (_id) REFERENCES demo1_zhujian(id) ON DELETE CASCADE ON UPDATE CASCADE);
3、添加数据
1 insert into demo1_zhujian
2 (name)
3 values
4 (''11111'');
5
6 insert into demo2_waijian
7 (_id, name)
8 values
9 (1, ''demo2_1'');
10
11 insert into demo3_waijian
12 (_id, name)
13 values
14 (1, ''demo3_1'');
4、查询数据
1 select * from demo1_zhujian;
2 select * from demo2_waijian;
3 select * from demo3_waijian;
5、修改主键数据
1 update demo1_zhujian set id=22 where id=1;
6、重复第4步
外键table中修改外键不行
7、主键table中删除数据
1 delete from demo1_zhujian where id=22;
8、重复第4步
MySQL级联复制(A->B->C)
MySQL主从结构实际中是用到最多的一种架构。 新上的两台服务器B和C,要替换掉之前旧的服务器A,同时,B和C是新的主从关系。因此,配置成级联复制,来迁移数据,也方便切换。 架构图如下: master A ------> slave B ------> slave C 有这么情况发生了,服务器B可以正常复制服务器A的数据,服务器B和C主从状态Slave_IO_Running和Slave_SQL_Running都是yes的,但是服务器C却无法复制新的数据。 原因分析: 1. 检查服务器B有没有开启二进制日志log_bin 2. log_slave_updates是否启用 log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。 上面的问题是由于没有启用log_slave_updates = 1导致的。 总结: 因此,对于mysql级联复制,上游的从服务器不仅仅要开启log_bin还要开启log_slave_updates,否则将导致下游的从服务器无法更新复制。 转载请注明来自 运维生存时间: http://www.ttlsa.com/html/3481.htmlMYSQL级联查询,包括向上向下的级联
-- 名称:mysql递归查询存储过程(2014-04-05)
-- 入:@table 表名[varchar(200)]
-- 入:@field 要查询返回的字段名(例如: name,age,remark)[text]
-- 入:@order 返回结果的排序(例如 name desc,age asc)[text]
-- 入:@idName 主键列名[varchar(200)]
-- 入:@pidName父键列名[varchar(200)]
-- 入:@id 主键值[varchar(200)],不能为null,如果值是null,说明要查询全部,请自己查询
-- 入:@upDown 向上级联还是向下级联,1=上 0=下[int]
-- 入:@self 是否包含自己 1=是 0=否[int]
-- 返回查询结果集
DROP PROCEDURE IF EXISTS Query_Dg;
CREATE PROCEDURE Query_Dg
(
IN table_ VARCHAR(200),
IN field_ TEXT,
IN order_ TEXT,
IN idName_ VARCHAR(200),
IN pidName_ VARCHAR(200),
IN id_ VARCHAR(200),
IN upDown_ INT,
IN self_ INT
)
BEGIN
DECLARE _sqlStr VARCHAR(4000); -- 动态sql
DECLARE _idParam VARCHAR(4000); -- id存放的变量
DECLARE _idSet VARCHAR(4000); -- 结果
SET @_idSet = '''';
-- 查询id开始
IF(self_ = 1)THEN -- 包含自己
SET @_idSet = id_;
END IF;
-- 递归开始
IF(upDown_ = 1)THEN -- 向上递归
SET @_sql = CONCAT(''SELECT '',pidName_,'' INTO @_idParam FROM '',table_,'' WHERE '',idName_,'' = ?'');
ELSE -- 向下递归
SET @_sql = CONCAT(''SELECT GROUP_CONCAT('',idName_,'') INTO @_idParam FROM '',table_,'' WHERE FIND_IN_SET('',pidName_,'', ?) > 0'');
END IF;
SET @_idParam = id_; -- 输入参数使用时不能 @
PREPARE _sqlStr FROM @_sql;
EXECUTE _sqlStr USING @_idParam;
WHILE @_idParam IS NOT NULL DO
SET @_idSet = CONCAT(@_idSet,'','',@_idParam);
EXECUTE _sqlStr USING @_idParam;
END WHILE;
-- 查询id结束
SET @_sql = CONCAT(''SELECT '',field_,'' FROM '',table_,'' WHERE FIND_IN_SET('',idName_,'', ? ) > 0 order by '',order_); -- 查询
DEALLOCATE PREPARE _sqlStr; -- 解除预编译
PREPARE _sqlStr FROM @_sql; -- 重新预编译
EXECUTE _sqlStr USING @_idSet;
DEALLOCATE PREPARE _sqlStr;
END
今天的关于PLPGSQL级联触发器?和sql触发器级联更新的分享已经结束,谢谢您的关注,如果想了解更多关于mysql级联删除、MySQL级联删除和级联修改、MySQL级联复制(A->B->C)、MYSQL级联查询,包括向上向下的级联的相关知识,请在本站进行查询。
本文标签: