Oracle技術_5分鐘會用預存程序_預存程序簡單一實例(包含迴圈、條件、增改查、參數傳入、變數賦值、java調用等),oracle_5

來源:互聯網
上載者:User

Oracle技術_5分鐘會用預存程序_預存程序簡單一實例(包含迴圈、條件、增改查、參數傳入、變數賦值、java調用等),oracle_5

例子業務功能:

1.根據傳入的類型A_TYPE聯集查詢PROCEDURE_TEST_A表、PROCEDURE_TEST_A_SUB表中的資料,並顯示主要內容。

2.根據傳入的類型A_TYPE聯集查詢PROCEDURE_TEST_A表、PROCEDURE_TEST_A_SUB表,並將結果插入PROCEDURE_TEST_B表中。

這裡若B_EMAIL欄位為空白則取傳入的預設值。

3.若PROCEDURE_TEST_B表進行了插入操作,則分組統計ASUB_NUMBER欄位更新或插入PROCEDURE_TEST_C表中。


完整代碼點我下載


裡麵包含了預存程序常用的大部分操作,包含迴圈、條件、增改查、參數傳入、變數賦值等,話不多說直接上例子:

1.建立所需要的表,並初始化資料建立4張表,其中3個表需要初始資料,代碼如下:
--資料來源表PROCEDURE_TEST_ACREATE TABLE PROCEDURE_TEST_A(  A_ID     VARCHAR2(255) NOT NULL,  A_USER   VARCHAR2(255),  A_EMAIL  VARCHAR2(255),  A_TYPE   VARCHAR2(5),  CONSTRAINT PROCEDURE_TEST_A PRIMARY KEY (A_ID)  );--資料來源表的子表PROCEDURE_TEST_A_SUBCREATE TABLE PROCEDURE_TEST_A_SUB(  ASUB_ID      VARCHAR2(255) NOT NULL,  ASUB_NAME    VARCHAR2(255),  ASUB_NUMBER  NUMBER(18,2),  ASUB_COMMENT VARCHAR2(2000),  A_ID         VARCHAR2(255),  CONSTRAINT PROCEDURE_TEST_A_SUB PRIMARY KEY (ASUB_ID),  CONSTRAINT PROCEDURE_TEST FOREIGN KEY (A_ID) REFERENCES PROCEDURE_TEST_A (A_ID));--資料整合後插入表CREATE TABLE PROCEDURE_TEST_B(  B_ID       VARCHAR2(255) NOT NULL,  B_USER     VARCHAR2(255),  B_EMAIL    VARCHAR2(255),  B_NAME     VARCHAR2(255),  B_NUMBER   NUMBER(18,2),  B_COMMENT  VARCHAR2(2000),  CONSTRAINT PROCEDURE_TEST_B PRIMARY KEY (B_ID)  );--資料整合後更新表CREATE TABLE PROCEDURE_TEST_C(  C_USER    VARCHAR2(255) NOT NULL,  C_NUMBER   NUMBER(18,2),  CONSTRAINT PROCEDURE_TEST_C PRIMARY KEY (C_USER)  );--PROCEDURE_TEST_A初始化INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00006', 'system', '', 'T00');INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00001', 'popkidorc', 'popkidorc@mail.com', 'T01');INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00002', 'csdn', 'csdn@mail.com', 'T01');INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00003', 'pop', '', 'T01');INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00004', 'kid', 'kid@mail.com', 'T01');INSERT INTO PROCEDURE_TEST_A  (A_ID, A_USER, A_EMAIL, A_TYPE)VALUES  ('AID00005', 'orc', 'orc@mail.com', 'T01');--PROCEDURE_TEST_A_SUB初始化INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00001', 'oralce_blog', 9.90, 'oralce部落格', 'AID00001');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00002', 'sql_blog', 1.50, 'sql部落格', 'AID00001');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00003', 'swift_blog', 1.00, 'swift部落格', 'AID00001');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00004', 'game_blog', 6.00, 'game部落格', 'AID00003');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00005', 'sport_blog', 5.55, 'sport部落格', 'AID00003');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00006', 'kid_blog', 99.00, 'kid部落格', 'AID00004');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00007', 'zero_blog', 0.00, 'zero部落格', 'AID00005');INSERT INTO PROCEDURE_TEST_A_SUB  (ASUB_ID, ASUB_NAME, ASUB_NUMBER, ASUB_COMMENT, A_ID)VALUES  ('ASUBID00008', 'large_blog', 100000.00, 'large部落格', 'AID00005');--PROCEDURE_TEST_C初始化INSERT INTO PROCEDURE_TEST_C  (C_USER, C_NUMBER)VALUES  ('popkidorc', 9.90);

執行後,表結構及資料結果

2.建立預存程序代碼如下,注釋非常詳細,直接copy就可慢慢看:
CREATE OR REPLACE PROCEDURE PROCEDURE_TEST(I_A_TYPE       VARCHAR2,                                           I_DEFAULT_MAIL VARCHAR2) IS  --聲明變數 start--  L_DEFAULT_MAIL VARCHAR2(255) := 'default@mail.com'; --聲明變數,並賦值;若第二個輸入參數不為空白,則取該值作為MAIL欄位的預設值  L_TEST_B_COUNT INTEGER; --B表更新後影響記錄數  L_TEST_C_COUNT INTEGER; --C表更新後影響記錄數  CURSOR A_CURSOR IS    SELECT A.A_USER, S.ASUB_NUMBER      FROM PROCEDURE_TEST_A_SUB S      LEFT JOIN PROCEDURE_TEST_A A        ON A.A_ID = S.A_ID     WHERE A.A_TYPE = I_A_TYPE; --遊標對象,用來儲存結果集  --聲明變數 end--BEGIN  --迴圈顯示A表中資料 start--  FOR A_C IN A_CURSOR LOOP    DBMS_OUTPUT.PUT_LINE('===LOOP PROCEDURE_TEST_A===' || A_C.A_USER ||                         '===' || A_C.ASUB_NUMBER);  END LOOP; --這裡用的是FOR IN迴圈,WHILE迴圈也比較常用,可以去查一下  --迴圈顯示A表中資料 end--    --查詢A、A_SUB表,並插入B表 start--  INSERT INTO PROCEDURE_TEST_B    (B_ID, B_USER, B_EMAIL, B_NAME, B_NUMBER, B_COMMENT)    SELECT SYS_GUID(),           A.A_USER,           DECODE(A.A_EMAIL,                  NULL,                  DECODE(I_DEFAULT_MAIL,                         NULL,                         L_DEFAULT_MAIL,                         I_DEFAULT_MAIL),                  A.A_EMAIL),           S.ASUB_NAME,           S.ASUB_NUMBER,           S.ASUB_COMMENT      FROM PROCEDURE_TEST_A_SUB S      LEFT JOIN PROCEDURE_TEST_A A        ON A.A_ID = S.A_ID     WHERE A.A_TYPE = I_A_TYPE;  L_TEST_B_COUNT := SQL%ROWCOUNT;  DBMS_OUTPUT.PUT_LINE('===INSERT PROCEDURE_TEST_B ROWCOUNT===' ||                       L_TEST_B_COUNT); --影響的記錄數,SQL%ROWCOUNT  --查詢A、A_SUB表,並插入B表 end--  --更新C表 start--  IF L_TEST_B_COUNT > 0 THEN    --先判斷若B表有更改才來更新C表    MERGE INTO PROCEDURE_TEST_C C    USING (SELECT A.A_USER, SUM(S.ASUB_NUMBER) AS SUM_NUMBER             FROM PROCEDURE_TEST_A_SUB S             LEFT JOIN PROCEDURE_TEST_A A               ON A.A_ID = S.A_ID            GROUP BY A.A_USER) A    ON (A.A_USER = C.C_USER)    WHEN MATCHED THEN      UPDATE SET C.C_NUMBER = A.SUM_NUMBER    WHEN NOT MATCHED THEN      INSERT VALUES (A.A_USER, A.SUM_NUMBER);    L_TEST_C_COUNT := SQL%ROWCOUNT;    DBMS_OUTPUT.PUT_LINE('===UPDATE OR INSERT PROCEDURE_TEST_C ROWCOUNT===' ||                         L_TEST_C_COUNT); --影響的記錄數,SQL%ROWCOUNT  END IF;  --更新C表 end--  --提交事務 start--  COMMIT; --這裡慎用,最好不要直接在預存程序中提交,而是使用服務端代碼手動提交。  --提交事務 end--  --異常處理 start--EXCEPTION  --很多異常我就不一一寫出來了,常見的寫兩個,其他的用OTHER了  WHEN DUP_VAL_ON_INDEX THEN    --違反了唯一性限制。    DBMS_OUTPUT.PUT_LINE('===DUP_VAL_ON_INDEX EXCEPTION===');    RAISE;  WHEN NO_DATA_FOUND THEN    --SELECT時候未找到資料    DBMS_OUTPUT.PUT_LINE('===NO_DATA_FOUND EXCEPTION===');    RAISE;    --終止進程  WHEN OTHERS THEN    DBMS_OUTPUT.PUT_LINE('===OTHERS EXCEPTION===');    RAISE;    --異常處理 end--END PROCEDURE_TEST;
3.執行預存程序直接執行,代碼如下:
BEGIN  --執行預存程序  PROCEDURE_TEST('T01', 'test@mail.com');END;
java通過thin調用,代碼如下(關鍵代碼):
Class.forName("資料庫驅動包");Connection conn =  DriverManager.getConnection("連接字串", "使用者名稱", "密碼");CallableStatement proc = null;proc = conn.prepareCall("{ call PROCEDURE_TEST(?,?) }");proc.setString(1, "T01");proc.setString(2, "test@mail.com");proc.execute();

執行結果如,DBMS控制台列印的:

兩個被更新的表:

點擊進入ooppookid的部落格

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.