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

在寫代碼的時候,可能出現的序列未建立的異常就能夠很好的避免了。

相關文章
相關標籤/搜索