我正在使用PostgreSQL 10.3中的下表:
CREATE TABLE s_etpta.tab1 (
Number VARCHAR(40) NOT NULL,
id VARCHAR(8),
CONSTRAINT i_tab1 PRIMARY KEY(Number)
)
我需要在id
每次插入时将列增加1。我不能更改表,因为我不是所有者,因此除了增加varchar
列之外别无选择。
该列的类型varchar
以零开头。如果表为空,如何指定我要以“ 00000001”开头?因为当我的表中已经有值时,触发器会获取最后一个值,并在下一次插入时将其递增,这是正确的,但是当我的表为空时,id列将保持为空,因为触发器没有要递增的值。
CREATE OR REPLACE FUNCTION schema."Num" (
)
RETURNS trigger AS
$body$
DECLARE
BEGIN
NEW.id := lpad(CAST(CAST(max (id) AS INTEGER)+1 as varchar),8, '0') from
schema.tab1;
return NEW;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
RETURNS NULL ON NULL INPUT
SECURITY INVOKER
COST 100;
触发器设计是不安全且昂贵的欺骗,很容易在并发写入负载下失败。不要使用触发器。使用serial
或IDENTITY
列代替:
请勿使用text
(或varchar
)作为numeric
值。
不要填充前导零。您可以格式化你的号码,你喜欢的任何方式显示有to_char()
:
在Postgres 10或更高版本中,您的表可能如下所示:
CREATE TABLE s_etpta.tab1 (
number numeric NOT NULL PRIMARY KEY, -- not VARCHAR(40)
id bigint GENERATED ALWAYS AS IDENTITY -- or just int?
);
没有触发器。
似乎number
是PK。看起来id
应该是。也许您根本不需要id
表中的列?
如果需要同步基础序列:
如果您无法修复表,则此触发器函数将与现有函数一起使用(在并发写入负载下不可靠):
CREATE OR REPLACE FUNCTION schema.tab1_number_inc()
RETURNS trigger AS
$func$
DECLARE
BEGIN
SELECT to_char(COALESCE(max(id)::int + 1, 0), 'FM00000000')
FROM schema.tab1
INTO NEW.id;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
触发:
CREATE TRIGGER tab1_before_insert
BEFORE INSERT ON schema.tab1
FOR EACH ROW EXECUTE PROCEDURE schema.tab1_number_inc();
该FM
修正去除前导空格to_char()
的输出:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句