我想为这个 varchar 创建一个序列。如果它是一个数字而不是 varchar,那会更容易。在那种情况下,我可以做
seq_no := seq_no + 1;
但是,当我想将列中的下一个值存储为 A0000002 时,当上一个值为 A0000001(将下一个 varchar 行中的数字增加 1)时,我该怎么办?
这可以通过
to_char(seq_no,'FM0000000')
您的示例可以通过在 oracle 中创建序列来完成
create sequence seq_no start with 1 increment by 1;
然后
select 'A'||to_char(seq_no.nextval,'FM0000000') from dual;
现在我已经在双重使用..但是把这个
'A'||to_char(seq_no.nextval,'FM0000000')
在您所需的查询中..这将创建您提到的序列
序列是纯数字的。但是,无论如何您都需要一个触发器,因此只需调整此类触发器以插入所需的前缀:
CREATE OR REPLACE TRIGGER FOO_TRG1
BEFORE INSERT
ON FOO
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF :NEW.FOO_ID IS NULL THEN
SELECT 'A' || TO_CHAR(FOO_SEQ1.NEXTVAL, 'FM0000000') INTO :NEW.FOO_ID FROM DUAL;
END IF;
END FOO_TRG1;
/
ALTER TRIGGER FOO_TRG1 ENABLE;
如果可以的话,我实际上会使用CREATE TABLE语法中定义的虚拟列。如果需要,它可以更容易地扩展。
这是一个工作示例。
SQL> create table tmp_test (
2 id number(7,0) primary key
3 , col1 number
4 , seq varchar2(8 char) generated always as (
5 'A' || to_char(id, 'FM0999999'))
6 );
Table created.
SQL>
SQL> create sequence tmp_test_seq;
Sequence created.
SQL>
SQL> create or replace trigger tmp_test_trigger
2 before insert on tmp_test
3 for each row
4 begin
5
6 :new.id := tmp_test_seq.nextval;
7 end;
8 /
Trigger created.
SQL> show errors
No errors.
SQL>
SQL> insert into tmp_test (col1)
2 values(1);
1 row created.
SQL>
SQL> select * from tmp_test;
ID COL1 SEQ
---------- ---------- --------------------------------
1 1 A0000001
话说回来; 除非您有令人难以置信的紧迫业务需求,否则您最好不这样做。通过在数字前面加上一个常数值来让自己的生活变得更加困难并没有什么意义。因为 A 将永远是 A,所以它是否存在并不重要。
如果格式始终是一个字母后跟 7 位数字,您可以执行以下操作:
sequence = lpad(substr(sequence,2,7)+1,7,'0')