• ORACLE 自动增长通过封装函数,方便调用


      好的编程习惯,是一个很有必要的过程。好的编程习惯,可以因人而异,但是简单地、基本地代码级别的就那些:写注释、合理的缩进、换行、变量命名等。

      对我们程序员来说,大部分时间都对着电脑,在对着电脑的大部分时间都在对着代码,要么是看别人代码,要么是在写代码。在看别人的代码的过程中,当看到别人 的代码很乱的时候,心里肯定会说,这他妈的谁写的代码,看起来真费劲,要注释没注释,该换行的时候没换行,缩进也没规则。所以,好的编程习惯,一个好处就是,方便自己,也方便别人看自己的代码。编程的时候很多情况是由于一些细节没有注意。在自己代码走读的过程成中会出现对应错误,良好的代码习惯,也有利于问题代码能快速的定位。好的编程习惯,好处就是,可以避免一些问题的发生,从而提高工作效率。

      一般情况下我们的ORACLE 使用关键字上要使用大写的,这样有利于 编程规范,所以这边提供一个小技巧:

      在PL/SQL Tool -> Preferences 中的:

      

    Oracle 数据库中,创建一个表的过程,并且其中主键是自动增长的,因为ORACLE 不提供自动增长的自主id,所以,需要我们自己先创建序列然后在调用序列的方法实现自动增长一般过程如下:

    -- Create table
    
    CREATE TABLE T_Test(
    
            test_id INTEGER CONSTRAINT t_test_pk PRIMARY KEY,
    
            name VARCHAR2(10) NOT NULL
    
    );      
    
    -- Add comments to the table
    
    COMMENT ON TABLE T_Test
    
      is '测试表';
    
    -- Add comments to the columns
    
    COMMENT ON COLUMN  T_Test.test_id
    
      is '自增主键';
    
    COMMENT ON COLUMN  T_Test.name
    
      is '名称';
    
    -- Create/Sequences
    
    CREATE SEQUENCE SEQ_T_Test MINVALUE 1 MAXVALUE 1E27 START WITH 1 INCREMENT BY 1 NOCACHE CYCLE;
    
    --insert
    
    INSERT INTO t_test(test_id,NAME)VALUES(seq_t_test.nextval,'linkepeng');

    每次我这样插入数据的时候,如果开始的时候,没有创建对应的序列的化,我们还要先创建,而且,有可能命名冲突,等一些情况,感觉使用起来不方便

    这边我写个函数,是为了解决,自动创建的函数这样调用者,不用去关心,序列是否已经创建,而且只要每次调用传入对应的表名字,这样就能获取对应的增长的ID。

    第一步:
    /*
       描述:取字符串左边几个字符
       作者:linkepeng
       日期:2016-08-07
    */
    CREATE OR REPLACE FUNCTION LeftStr
    (
           M_Text VARCHAR2,
           M_Count INTEGER
    )
    RETURN VARCHAR
    AS
           L_Result VARCHAR(4000);
    BEGIN
           L_Result:='';
           IF M_Text IS NOT NULL THEN
             L_Result:=Substr(M_Text,1,M_Count);
           END IF;
           RETURN L_Result;
    END;
    
    /*
       描述:创建序列对象
       作者:linkepeng
       日期:2016-08-07
    */
    CREATE OR REPLACE PROCEDURE CreateSequence
    (
           M_TableName IN VARCHAR2 --表名或序列对象名称
    )
    --这个在普通用户情况下,需要添加这条语句。
    AUTHID CURRENT_USER
    AS
      L_UserName         VARCHAR2(30);
      L_SqlString        VARCHAR2(1000);
      L_SequenceName_C   VARCHAR2(500);
      L_RowCount         INTEGER;
      L_MAXID            NUMBER;
      L_Key_FieldName    VARCHAR2(50);
    BEGIN
       --根据表名得到序列名称
      L_SequenceName_C := REPLACE(M_TableName,'-','_');
      IF UPPER(LeftStr(L_SequenceName_C,4))<>'SEQ_' THEN
        L_SequenceName_C := 'SEQ_' || L_SequenceName_C;
      END IF;
      L_SequenceName_C := UPPER(LeftStr(L_SequenceName_C,30));
       --根据表名取出主键字段
      BEGIN
        SELECT COLUMN_NAME INTO L_Key_FieldName
        FROM User_Cons_Columns
        WHERE CONSTRAINT_NAME IN (
              SELECT CONSTRAINT_NAME
              FROM User_Constraints
              WHERE CONSTRAINT_TYPE = 'P' AND UPPER(TABLE_NAME)=UPPER(M_TableName)
        ) AND ROWNUM=1;
        --根据表名、主键字段取出最大值
        L_SqlString := 'SELECT MAX(' || L_Key_FieldName || ') FROM ' || M_TableName;
        BEGIN
          EXECUTE IMMEDIATE L_SqlString INTO L_MAXID;
        EXCEPTION
           --捕捉错误
          WHEN OTHERS THEN
            L_MAXID:=0;
        END;
      EXCEPTION
        WHEN OTHERS THEN
          L_MAXID:=0;
      END;
      L_MAXID := NVL(L_MAXID, 0);
      --修改下一个值
      L_MAXID := L_MAXID + 1;
      L_SqlString := 'CREATE SEQUENCE ' || L_SequenceName_C;
      L_SqlString:=L_SqlString ||' MINVALUE 1 MAXVALUE 1E27 START WITH '||to_char(L_MAXID) || ' INCREMENT BY 1 NOCACHE CYCLE';
      PRAGMA AUTONOMOUS_TRANSACTION;
      EXECUTE IMMEDIATE L_SqlString;
    END;
    
    /*
       描述:获取某个表主键新ID
       作者:linkepeng
       日期:2016-08-07
    */
    CREATE OR REPLACE FUNCTION GetNewID
    (
           M_TableName       IN VARCHAR2
    )
    RETURN INTEGER
    AUTHID CURRENT_USER
    AS
           L_StrSql VARCHAR2(1000);
           L_NewID INTEGER;
           L_RowCount INTEGER;
           L_SequenceName_T VARCHAR2(255);
    BEGIN
           L_SequenceName_T :=LeftStr('Seq_'||REPLACE(M_TableName,'-','_'),30);
            --判断序列是否存在
           SELECT COUNT(*) INTO L_RowCount FROM User_Objects
           WHERE Object_Type = 'SEQUENCE' AND Upper(OBJECT_NAME) = Upper(L_SequenceName_T);
           IF L_RowCount=0 THEN
             --通过存储过程创建序列
             CreateSequence(M_TableName);
           END IF;
           L_StrSql:='SELECT '||L_SequenceName_T||'.Nextval FROM dual';
           EXECUTE IMMEDIATE L_StrSql INTO L_NewID;
           RETURN L_NewID;
    END;

    其中 AUTHID CURRENT_USER 为的防止用户出现: EXECUTE IMMEDIATE 如果在执行DDL的时候,如果在存储过程没有这个的化,会出现权限不足的问题。

    还有一种解决方案是:给用户提高权限:在sysdba权限 用户下,提高权限命令:       GRANT CREATE ANY TABLE TO '用户名';

    这样创建以后,我们就可以这样调用我们的插入语句了:

      INSERT INTO t_test(test_id,NAME)VALUES(getnewid('t_test'),'linkepeng');

    在写代码的时候,可能出现的序列未创建的异常就可以很好的避免了。

     

  • 相关阅读:
    javascript 日期月份加减
    ActiveRecord 的类型初始值设定项引发异常
    angularjs $q、$http 处理多个异步请求
    angular.foreach 格式
    PHP基础知识2
    第一个月的学习总结
    JavaScript的学习5
    JavaScript的学习4
    JavaScript的学习3
    JavaScript的学习2
  • 原文地址:https://www.cnblogs.com/lynn-lkp/p/5741399.html
Copyright © 2020-2023  润新知