问题描述
我正在创建项目记录编号生成器。目的是要有一个表来容纳各种不同类型的所有记录号/序列器。例如,对于“零件”,您可能需要一个类似于“ 110-00001-00”的数字。 seqItem表将保存此数字生成器的定义(SeqName,preFix,postFix,padding)。
InventorySys=# SELECT * FROM information_schema.sequences;
sequence_catalog | sequence_schema | sequence_name | data_type | numeric_precision | numeric_precision_radix | numeric_scale | start_value | minimum_value | maximum_value | increment | cycle_option
------------------+-----------------+---------------+-----------+-------------------+-------------------------+---------------+-------------+---------------+---------------+-----------+--------------
(0 rows)
InventorySys=# \d "SeqItem"
Table "public.SeqItem"
Column | Type | Collation | Nullable | Default
---------+---------+-----------+----------+---------
SeqName | text | | not null |
prefix | text | | |
postfix | text | | |
padding | integer | | not null | 5
Indexes:
"SeqItem_pkey" PRIMARY KEY,btree ("SeqName")
"SeqName" UNIQUE CONSTRAINT,btree ("SeqName")
Triggers:
dropsqeitem AFTER DELETE ON "SeqItem" FOR EACH ROW EXECUTE FUNCTION "RemoveSeq"()
inssqeitem AFTER INSERT ON "SeqItem" FOR EACH ROW EXECUTE FUNCTION "CreateSeq"()
InventorySys=#
将新记录添加到该表时,我想使用“ SeqName”创建一个新的Sequence。因此,我创建了以下触发器/函数:
CREATE OR REPLACE FUNCTION public."CreateSeq"() RETURNS TRIGGER as $CreateSeq$
BEGIN
EXECUTE format('CREATE SEQUENCE %I INCREMENT BY 1 MINVALUE 1 NO MAXVALUE START WITH 1 NO CYCLE',NEW."SeqName");
RETURN NEW;
END
$CreateSeq$ LANGUAGE plpgsql;
CREATE TRIGGER insSqeItem AFTER INSERT ON "SeqItem"
FOR EACH ROW EXECUTE FUNCTION "CreateSeq"();
这很完美,每条新记录都会创建一个新的音序器。如果行被删除,我还创建了另一个函数/触发器来删除音序器。
CREATE OR REPLACE FUNCTION public."RemoveSeq"() RETURNS TRIGGER as $RemoveSeq$
BEGIN
EXECUTE format('DROP SEQUENCE IF EXISTS %I',OLD."SeqName");
RETURN NEW;
END
$RemoveSeq$ LANGUAGE plpgsql;
CREATE TRIGGER dropSqeItem AFTER DELETE ON "SeqItem"
FOR EACH ROW EXECUTE FUNCTION "RemoveSeq"();
到目前为止一切顺利!因此,让我们添加一条新记录,看看是否添加了音序器:
InventorySys=# INSERT into "SeqItem" ("SeqName",prefix,padding) Values ('testItem1','115-',6);
INSERT 0 1
InventorySys=# SELECT * FROM "SeqItem";
SeqName | prefix | postfix | padding
-----------+--------+---------+---------
testItem1 | 115- | | 6
(1 row)
InventorySys=# SELECT * FROM information_schema.sequences;
sequence_catalog | sequence_schema | sequence_name | data_type | numeric_precision | numeric_precision_radix | numeric_scale | start_value | minimum_value | maximum_value | increment | cycle_option
------------------+-----------------+---------------+-----------+-------------------+-------------------------+---------------+-------------+---------------+---------------------+-----------+--------------
InventorySys | public | testItem1 | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO
(1 row)
InventorySys=#
但是,当我尝试使用触发器中新创建的音序器时,出现以下错误,即找不到音序器。
InventorySys=# select CONCAT("prefix",LPAD((select nextval("SeqItem"."SeqName"))::text,"padding",'0'),"postfix") from "SeqItem" where "SeqName" = 'testItem1' ;
ERROR: relation "testitem1" does not exist
InventorySys=#
错误:关系“ testitem1”不存在
如果我创建一个没有触发器的新音序器,它将正常工作:
InventorySys=# CREATE SEQUENCE test1;
CREATE SEQUENCE
InventorySys=# SELECT NEXTVAL ('test1');
nextval
---------
1
(1 row)
InventorySys=#
InventorySys=# select CONCAT("prefix",LPAD((select nextval('test1'))::text,"postfix") from "SeqItem" where "SeqName" = 'testItem1' ;
concat
------------
115-000002
(1 row)
InventorySys=#
两个音序器在我看来都很好,但是由触发器创建的音序器我无法使用...
InventorySys=# SELECT * FROM information_schema.sequences;
sequence_catalog | sequence_schema | sequence_name | data_type | numeric_precision | numeric_precision_radix | numeric_scale | start_value | minimum_value | maximum_value | increment | cycle_option
------------------+-----------------+---------------+-----------+-------------------+-------------------------+---------------+-------------+---------------+---------------------+-----------+--------------
InventorySys | public | testItem1 | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO
InventorySys | public | test1 | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO
(2 rows)
InventorySys=#
任何帮助将不胜感激!
解决方法
好的,我想我已经解决了我的问题。似乎音序器名称必须全部小写吗?或者,我应该说,如果我全部使用小写字母,就可以了...
InventorySys=# INSERT into "SeqItem" ("SeqName",prefix,padding) Values ('testitem3','110-',4);
INSERT 0 1
InventorySys=# select CONCAT("prefix",LPAD((select nextval("SeqItem"."SeqName"))::text,"padding",'0'),"postfix") from "SeqItem" where "SeqName" = 'testitem3' ;
concat
----------
110-0001
(1 row)
InventorySys=# select CONCAT("prefix","postfix") from "SeqItem" where "SeqName" = 'testitem3' ;
concat
----------
110-0002
(1 row)
InventorySys=#
我不确定为什么它不接受大写和小写字符...