Trigger to get next prefixed ID: Is there a better way?

Wil*_*son 2 trigger oracle uniqueidentifier oracle-12c

I have a projects table:

+------------+-----+
| PROJECT_ID | ... |
+------------+-----+
| LC000001   |     |
| LC000002   |     |
| LC000003   |     |
| LC000004   |     |
| LC000005   |     |
+------------+-----+
Run Code Online (Sandbox Code Playgroud)

As you can see, the PROJECT_ID column has a text datatype (NVARCHAR2) and it has a prefix (LC).

I'm guessing that creating an ID with a prefix might have been a been a poor design choice. But, right or wrong, this is how my organization has set up it's business.

I've written a trigger that automatically inserts the next PROJECT_ID when a new row is created in the application's attribute editing environment (more here).

CREATE OR REPLACE TRIGGER "PROJECTS_PROJECT_ID_TRIG" BEFORE INSERT ON PROJECTS
    FOR EACH ROW
      BEGIN
        SELECT 'LC' || LPAD(TO_CHAR(CAST(SUBSTR(MAX(PROJECT_ID),-6) AS NUMBER(15,0)) + 1),6, '0')
        INTO :NEW.PROJECT_ID
        FROM PROJECTS;
      END;
Run Code Online (Sandbox Code Playgroud)

However, this is literally the very first trigger I have ever written. The fact that it deconstructs the textual ID, get's the next number, and then reconstructs the textual ID, seems overly complicated to me. I can't help but think Oracle might have a more sophisticated way of handling this.

Is there a better way?


I have a subsequent, related question here: Can an Oracle IDENTITY column be nullable?

a1e*_*x07 6

我希望您的触发器抛出运行时“变异表”错误。除非使用自治事务,因为您无法查询在其主体内触发行级触发器的表。

我宁愿保持简单 - 创建一个序列,例如 , CREATE SEQUENCE SEQ_PROJECT START WITH 6 INCREMENT BY 1. 另外,只有在 project_id 未设置 (WHEN子句) 时,我才会触发触发器。

CREATE OR REPLACE TRIGGER "PROJECTS_PROJECT_ID_TRIG" BEFORE INSERT ON PROJECTS
    FOR EACH ROW
    -- Fire trigger only if statement doesn't set project_id     
    WHEN (NEW.PROJECT_ID IS NULL) 
      BEGIN
       :NEW.PROJECT_ID := 'LC' ||to_char(SEQ_PROJECT.NEXTVAL,'FM000000');  <- Fill Mode
      END;
Run Code Online (Sandbox Code Playgroud)