在PostgreSQL函数/触发器中设置变量

在PostgreSQL函数/触发器中设置变量,postgresql,function,triggers,partitioning,Postgresql,Function,Triggers,Partitioning,我正在尝试在PostgreSQL数据库中创建关于时间的分区。虽然下面的函数/触发器是我遇到的服务器,但我仍然需要找出一种方法来设置参数的表名和模式名。因为我们计划通过更改参数值为不同的表和模式运行相同的触发器。非常感谢您的帮助,因为我几乎没有使用函数/触发器的经验 CREATE OR REPLACE FUNCTION myschema.server_partition_function() RETURNS TRIGGER AS $BODY$ DECLARE _new_time int; _ta

我正在尝试在PostgreSQL数据库中创建关于时间的分区。虽然下面的函数/触发器是我遇到的服务器,但我仍然需要找出一种方法来设置参数的表名和模式名。因为我们计划通过更改参数值为不同的表和模式运行相同的触发器。非常感谢您的帮助,因为我几乎没有使用函数/触发器的经验

CREATE OR REPLACE FUNCTION
myschema.server_partition_function()
RETURNS TRIGGER AS 
$BODY$
DECLARE
_new_time int;
_tablename text;
_startdate text;
_enddate text;
_result record;
BEGIN
--Takes the current inbound "time" value and determines when midnight is for the given date
_new_time := ((NEW."time"/86400)::int)*86400;
_startdate := to_char(to_timestamp(_new_time), 'YYYY-MM-DD');
_tablename := 'server_'||_startdate;

-- Check if the partition needed for the current record exists
PERFORM 1
FROM   pg_catalog.pg_class c
JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  c.relkind = 'r'
AND    c.relname = _tablename
AND    n.nspname = 'myschema';

-- If the partition needed does not yet exist, then we create it:
-- Note that || is string concatenation (joining two strings to make one)
IF NOT FOUND THEN
_enddate:=_startdate::timestamp + INTERVAL '1 day';
EXECUTE 'CREATE TABLE myschema.' || quote_ident(_tablename) || ' (
CHECK ( "time" >= EXTRACT(EPOCH FROM DATE ' || quote_literal(_startdate) || ')
AND "time" < EXTRACT(EPOCH FROM DATE ' || quote_literal(_enddate) || ')
)
) INHERITS (myschema.server_master)';

-- Table permissions are not inherited from the parent.
-- If permissions change on the master be sure to change them on the child also.
EXECUTE 'ALTER TABLE myschema.' || quote_ident(_tablename) || ' OWNER TO postgres';
EXECUTE 'GRANT ALL ON TABLE myschema.' || quote_ident(_tablename) || ' TO my_role';

-- Indexes are defined per child, so we assign a default index that uses the partition columns
EXECUTE 'CREATE INDEX ' || quote_ident(_tablename||'_indx1') || ' ON myschema.' || quote_ident(_tablename) || ' (time, id)';
END IF;

-- Insert the current record into the correct partition, which we are sure will now exist.
EXECUTE 'INSERT INTO myschema.' || quote_ident(_tablename) || ' VALUES ($1.*)' USING NEW;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql;
创建或替换函数
myschema.server\u partition\u函数()
将触发器返回为
$BODY$
声明
_新时代国际;
_表名文本;
_起始文本;
_结束日期文本;
_结果记录;
开始
--获取当前入站“时间”值,并确定给定日期的午夜时间
_新时间:=((新“时间”/86400)::int)*86400;
_startdate:=to_char(to_timestamp(_new_time),'YYYY-MM-DD');
_tablename:=“服务器”| | |开始日期;
--检查当前记录所需的分区是否存在
表演1
来自pg_catalog.pg_c类
将pg_catalog.pg_命名空间n连接到n.oid=c.relnamespace
其中c.relkind='r'
和c.relname=\u tablename
n.nspname='myschema';
--如果所需的分区尚不存在,则我们将创建它:
--请注意| |是字符串串联(将两个字符串连接成一个)
如果没有找到的话
_enddate:=_startdate::时间戳+间隔“1天”;
执行“创建表myschema”。| | quote_ident(_tablename)| |”(
选中(“时间”>=提取(从日期“| |引用|文字(_startdate)| |”开始的历元)
和“时间”<摘录(从日期开始的历元“| |引用|文字(_enddate)| |”)
)
)继承(myschema.server_master)';
--表权限不是从父级继承的。
--如果在主服务器上更改权限,请确保在子服务器上也更改权限。
执行“altertablemyschema.”| |引用| ident(_tablename)| | |“postgres的所有者”;
执行'GRANT ALL ON TABLE myschema'。| |引用_ident(_tablename)| |'TO my_role';
--索引是按每个子级定义的,因此我们分配一个使用分区列的默认索引
在myschema上执行“创建索引”| | quote|ident(|表名| | 124x1')| |'。| | quote|ident(|表名)|'(时间,id);
如果结束;
--将当前记录插入正确的分区,我们确信该分区现在将存在。
使用NEW执行“INSERT INTO myschema.”| | quote_ident(_tablename)| | value($1.*);
返回NULL;
结束;
$BODY$
语言plpgsql;

您可能需要使用一些动态触发器特殊变量。调用触发器时,PostgreSQL会使用特殊变量自动提供一些值:


与其重新发明车轮,不如看看pg_partman:
_tablename  := TG_TABLE_NAME || '_' || _startdate;
_schemaname := TG_TABLE_SCHEMA || '_partitions';