我正在使用Oracle SQL:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0
PL/SQL Release 12.1.0.2.0 - Production 0
CORE 12.1.0.2.0 Production 0
TNS for Linux: Version 12.1.0.2.0 - Production 0
NLSRTL Version 12.1.0.2.0 - Production
我需要帮助找出如何为下面的关键字段创建序列:
我有一个名为MY_ID的字段的表。
插入记录时,需要使用序列自动生成MY_ID。
序列的规则是字符串前缀,每天1个计数器增量,午夜重置和日期的组合。
例如: 在9月10日,我们插入了2条记录,然后MY_ID应为:
PREFIX_01_20170910
PREFIX_02_20170910
9月11日:
PREFIX_01_20170911
PREFIX_02_20170911
PREFIX_03_20170911
9月12日,整个表格看起来像这样
PREFIX_01_20170910
PREFIX_02_20170910
PREFIX_01_20170911
PREFIX_02_20170911
PREFIX_03_20170911
PREFIX_01_20170912
到目前为止,无论日期如何,我对序列的所有操作都会增加1:
CREATE SEQUENCE SEQ_MY_TABLE INCREMENT BY 1 MAXVALUE 9999999999999999999999999999 MINVALUE 1 NOCACHE;
和触发器:
create or replace TRIGGER MY_TABLE_TRG
BEFORE INSERT ON MY_TABLE
FOR EACH ROW
BEGIN
<<COLUMN_SEQUENCES>>
BEGIN
IF INSERTING AND :NEW.MY_ID IS NULL THEN
SELECT SEQ_MY_TABLE .NEXTVAL INTO :NEW.MY_ID FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
谢谢!
答案 0 :(得分:3)
您可能想出一个方案来生成这个PREFIX_nn_date
密钥,它似乎在您的开发环境中起作用,但我会给您一些不必要的建议:不要浪费您的时间它。使主键成为一个简单的NUMBER列,从序列中填充它,然后继续。一旦你的代码进入生产阶段,同时会有更多的用户同时敲打你的桌面,你精心设计的生成PREFIX_nn_date
密钥的方案可能会失败 - 而且你用它来修复问题的助攻器就越多它会变得越糟糕。
祝你好运。
答案 1 :(得分:2)
跟进Bob Jarvis的回答,您可以随时在需要时创建字符串。这是一个简单的例子。
with records as (
select 1 id, to_date('20170901', 'yyyymmdd') theDate
from dual
union
select 2 id, to_date('20170901', 'yyyymmdd') theDate
from dual
union
select 3 id, to_date('20170902', 'yyyymmdd') theDate
from dual
)
select 'prefix_' ||
to_char(theDate, 'yyyymmdd') || '_' ||
to_char( rank() over (partition by theDate order by id)) prefix
from records
返回:
prefix_20170901_1
prefix_20170901_2
prefix_20170902_1
我没有那么多oracle工作,但如果你要重复这样做,你可能想把这个逻辑合并到一个函数或视图中。
答案 2 :(得分:1)
您可以按如下方式修改TRIGGER
。由于您需要序列中的每个数字为01,02,03附加到您的前缀,因此我在fm
中使用了TO_CHAR
说明符'00'
。如果每天的总插入次数超过99次,则需要使用fm000
create or replace TRIGGER MY_TABLE_TRG
BEFORE INSERT ON MY_TABLE
FOR EACH ROW
DECLARE
BEGIN
<<COLUMN_SEQUENCES>>
BEGIN
IF INSERTING AND :NEW.MY_ID IS NULL THEN
SELECT 'PREFIX_'||TO_CHAR(SEQ_MY_TABLE.NEXTVAL,'fm00')||'_'||TO_CHAR(SYSDATE,'YYYYMMDD') INTO :NEW.MY_ID FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
注意:为了建议一个好的做法,我不建议将其用作PRIMARY KEY
。最好在填充记录时简单地在所有应用程序代码中生成序列PRIMARY KEY
。
答案 3 :(得分:1)
最简单的方法是通过工作每个午夜重新创建序列。但使用序列并不是一个好主意。我认为这个ID对你很重要,但序列可以缓存一些值,某些值可能会丢失。所以你会得到:
PREFIX_01_20170910
PREFIX_02_20170910
PREFIX_04_20170910
PREFIX_07_20170910
... 等等。例如,您有“缓存10”,插入了2条记录并退出,或者进行了回滚,或者其他内容。
仅使用数字作为增量字段并计算此假身份证。
答案 4 :(得分:0)
您可以创建如下所示的函数来获取新ID并在插入查询中使用它。
CREATE OR REPLACE FUNCTION F_GETID (P_DT IN VARCHAR2) RETURN VARCHAR2
IS
V_NEW_ID VARCHAR2(50);
BEGIN
SELECT 'PREFIX_' || COUNT(*)+1 ||'_' || P_DT INTO V_NEW_ID FROM MY_TABLE
WHERE MY_ID LIKE 'PREFIX%'||P_DT;
RETURN V_NEW_ID;
END;
然后
insert into my_table(my_id , ...) values(F_GETID('20170927'),...);