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');

每次我这样插入数据的时候,若是开始的时候,没有建立对应的序列的化,咱们还要先建立,并且,有可能命名冲突,等一些状况,感受使用起来不方便spa

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

第一步:
/*
   描述:取字符串左边几个字符
   做者: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的时候,若是在存储过程没有这个的化,会出现权限不足的问题。code

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

这样建立之后,咱们就能够这样调用咱们的插入语句了:blog

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

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

相关文章
相关标签/搜索