利用触发器生成主键,程序怎么写?oracle不熟,请达人帮忙。表credit_inf 的主键是credit_no,主键的格式是日期加4位数字,如201106110001,就是首先判断表里有无当日数据,如果有,则给主键+1,如201106110002,如果没有当日的数据,则主键的后4位为0001。这个功能触发器能实现吗?

解决方案 »

  1.   

    在ORACLE中实现自增列方式是序列加触发器
    参考我这在这个贴子的回复

      

  2.   

    --复位序列过程(参数为序列名称)
    CREATE OR REPLACE PROCEDURE p_reset_seq(seq_name VARCHAR2) AUTHID CURRENT_USER IS
    BEGIN
      EXECUTE IMMEDIATE 'drop sequence ' || seq_name;
      EXECUTE IMMEDIATE 'create sequence ' || seq_name || ' START WITH 1';
    END;
    /--取得流水号函数(参数为序列名称)
    CREATE OR REPLACE FUNCTION f_get_no(seq_name VARCHAR2) RETURN VARCHAR2 IS
      v_no VARCHAR2(30);
    BEGIN
      EXECUTE IMMEDIATE 'SELECT to_char(SYSDATE, ''yyyymmdd'') || lpad(' ||
                        seq_name || '.nextval, 4, ''0'') FROM dual'
        INTO v_no;
      RETURN v_no;
    END;
    /--创建job(每天0点复位)
    DECLARE
      jobno NUMBER;
    BEGIN
      --假定你的序列名为t_seq
      dbms_job.submit(jobno,
                      'p_reset_seq(''t_seq'');',
                      trunc(sysdate)+1,
                      'trunc(SYSDATE) + 1');
      COMMIT;
    END;
    /
      

  3.   

    感谢tangren,不过我看不懂,还是不知道该怎么加,能给我写个完整的吗?
      

  4.   

    SQL> --复位序列过程(参数为序列名称)
    SQL> CREATE OR REPLACE PROCEDURE p_reset_seq(seq_name VARCHAR2) AUTHID CURRENT_USER IS
      2  BEGIN
      3    EXECUTE IMMEDIATE 'drop sequence ' || seq_name;
      4    EXECUTE IMMEDIATE 'create sequence ' || seq_name || ' START WITH 1';
      5  END;
      6  /
     
    Procedure created
    SQL> --取得流水号函数(参数为序列名称)
    SQL> CREATE OR REPLACE FUNCTION f_get_no(seq_name VARCHAR2) RETURN VARCHAR2 IS
      2    v_no VARCHAR2(30);
      3  BEGIN
      4    EXECUTE IMMEDIATE 'SELECT to_char(SYSDATE, ''yyyymmdd'') || lpad(' ||
      5                      seq_name || '.nextval, 4, ''0'') FROM dual'
      6      INTO v_no;
      7    RETURN v_no;
      8  END;
      9  /
     
    Function created
    SQL> --创建job(每天0点复位)
    SQL> DECLARE
      2    jobno NUMBER;
      3  BEGIN
      4    --假定你的序列名为t_seq
      5    dbms_job.submit(jobno,
      6                    'p_reset_seq(''t_seq'');',
      7                    trunc(sysdate)+1,
      8                    'trunc(SYSDATE) + 1');
      9    COMMIT;
     10  END;
     11  /
     
    PL/SQL procedure successfully completed
     
    SQL> create sequence t_seq start with 1;
     
    Sequence created
     
    SQL> select f_get_no('t_seq') from dual;
     
    F_GET_NO('T_SEQ')
    --------------------------------------------------------------------------------
    201106110001
     
    SQL> select f_get_no('t_seq') from dual;
     
    F_GET_NO('T_SEQ')
    --------------------------------------------------------------------------------
    201106110002
     
    SQL> exe p_reset_seq('t_seq');
     
    exe p_reset_seq('t_seq')
     
    ORA-00900: 无效 SQL 语句
     
    SQL> exec p_reset_seq('t_seq');
     
    PL/SQL procedure successfully completed
     
    SQL> select f_get_no('t_seq') from dual;
     
    F_GET_NO('T_SEQ')
    --------------------------------------------------------------------------------
    201106110001
     
    SQL> 
      

  5.   

    把上面的代码在pl/sql中一执行就行了吗?
      

  6.   

    汗~~
    那JOB是要在晚上0点自动执行。你如果要通过改日期来模拟,可以手动调用一下存储过程
    SQL> exe p_reset_seq('t_seq');
      

  7.   

    这个JOB,手动运行和自动运行都失败了,能删掉序列,但是新建不了。报错信息:
    ORA-12011:   execution   of   1   jobs   failed 
    ORA-06512:   at   "SYS.DBMS_IJOB ",   line   405 
    ORA-06512:   at   "SYS.DBMS_JOB ",   line   267 
    ORA-06512:   at   line   2