LightDB/PostgreSQL 相容Oracle儲存過程

哎呀我的天吶發表於2022-08-04

測試資料

create table PRODUCTS (PRODUCT_ID NUMBER,PRICE NUMBER,PRODUCT_TYPE_ID NUMBER);
insert into PRODUCTS values(1,10000,8);
insert into PRODUCTS values(2,1000,9);
insert into PRODUCTS values(3,100,8);
insert into PRODUCTS values(4,20000,9);
insert into PRODUCTS values(5,2000,8);
insert into PRODUCTS values(6,200,9);
insert into PRODUCTS values(7,2,8);
insert into PRODUCTS values(8,100000,9);

Oracle:

SQL> CREATE OR REPLACE FUNCTION GET_AVG_PRICE(P_TYPE_ID IN PRODUCTS.PRODUCT_TYPE_ID%TYPE)
  2    RETURN PRODUCTS.PRICE%TYPE IS
  3    V_AVG_PRICE PRODUCTS.PRICE%TYPE;
  4  BEGIN
  5    SELECT AVG(PRICE)
  6      INTO V_AVG_PRICE
  7      FROM PRODUCTS
  8     WHERE PRODUCT_TYPE_ID = P_TYPE_ID
  9     GROUP BY PRODUCT_TYPE_ID;
 10    RETURN V_AVG_PRICE;
 11  END GET_AVG_PRICE;
 12  /
Function created.
SQL> SELECT get_avg_price(9) FROM dual;  
GET_AVG_PRICE(9)
----------------
           30300
SQL> insert into sys.PRODUCTS values(9,100,10);
1 row created.
SQL> commit; 
Commit complete.
SQL> 
SQL> SELECT get_avg_price(9) FROM dual;
GET_AVG_PRICE(9)
----------------
           30300
SQL> SELECT get_avg_price(10) from dual;
GET_AVG_PRICE(10)
-----------------
              100

LightDB:

lightdb@postgres=# CREATE OR REPLACE FUNCTION GET_AVG_PRICE(P_TYPE_ID IN PRODUCTS.PRODUCT_TYPE_ID%TYPE)
lightdb@postgres-#   RETURN PRODUCTS.PRICE%TYPE IS
lightdb@postgres$#   V_AVG_PRICE PRODUCTS.PRICE%TYPE;
lightdb@postgres$# BEGIN
lightdb@postgres$#   SELECT AVG(PRICE)
lightdb@postgres$#     INTO V_AVG_PRICE
lightdb@postgres$#     FROM PRODUCTS
lightdb@postgres$#    WHERE PRODUCT_TYPE_ID = P_TYPE_ID
lightdb@postgres$#    GROUP BY PRODUCT_TYPE_ID;
lightdb@postgres$#   RETURN V_AVG_PRICE;
lightdb@postgres$# END GET_AVG_PRICE;
lightdb@postgres$# /
NOTICE:  type reference products.product_type_id%TYPE converted to numeric
NOTICE:  type reference products.product_type_id%TYPE converted to numeric
NOTICE:  type reference products.price%TYPE converted to numeric
NOTICE:  type reference products.product_type_id%TYPE converted to numeric
CREATE FUNCTION
lightdb@postgres=# SELECT get_avg_price(9) FROM dual;
   get_avg_price    
--------------------
 30300.000000000000
(1 row)
lightdb@postgres=# SELECT get_avg_price(10) FROM dual;
    get_avg_price     
----------------------
 100.0000000000000000
(1 row)

緊接上面測試包和包體

CREATE OR REPLACE PACKAGE PRODUCT_PACKAGE 
IS
  TYPE T_REF_CURSOR IS REF CURSOR;
  FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR;
  PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,P_FACTOR IN NUMBER);
END PRODUCT_PACKAGE;
/*包體*/
CREATE OR REPLACE PACKAGE BODY PRODUCT_PACKAGE
 IS
  FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR IS
    V_PRODUCTS_REF_CURSOR T_REF_CURSOR;
  BEGIN
    OPEN V_PRODUCTS_REF_CURSOR FOR
      SELECT PRODUCT_ID, PRICE FROM PRODUCTS;
    RETURN V_PRODUCTS_REF_CURSOR;
  END GET_PRODUCTS_REF_CURSOR;
  PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,
                                 P_FACTOR     IN NUMBER) IS
    V_PRODUCT_COUNT NUMBER;
  BEGIN
    SELECT COUNT(*)
      INTO V_PRODUCT_COUNT
      FROM PRODUCTS
     WHERE PRODUCT_ID = P_PRODUCT_ID;
    IF V_PRODUCT_COUNT = 1 THEN
      UPDATE PRODUCTS
         SET PRICE = PRICE * P_FACTOR
       WHERE PRODUCT_ID = P_PRODUCT_ID;
      COMMIT;
    END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      ROLLBACK;
  END UPDATE_PRODUCT_PRICE;
END PRODUCT_PACKAGE;  
================================================================
SQL> CREATE OR REPLACE PACKAGE PRODUCT_PACKAGE 
  2  IS
  3    TYPE T_REF_CURSOR IS REF CURSOR;
  4    FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR;
  5    PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,P_FACTOR IN NUMBER);
  6  END PRODUCT_PACKAGE;
  7  /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY PRODUCT_PACKAGE
 IS
  2    3    FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR IS
  4      V_PRODUCTS_REF_CURSOR T_REF_CURSOR;
  5    BEGIN
  6      OPEN V_PRODUCTS_REF_CURSOR FOR
  7        SELECT PRODUCT_ID, PRICE FROM PRODUCTS;
  8      RETURN V_PRODUCTS_REF_CURSOR;
  9    END GET_PRODUCTS_REF_CURSOR;
 10    PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,
 11                                   P_FACTOR     IN NUMBER) IS
 12      V_PRODUCT_COUNT NUMBER;
  BEGIN
 13   14      SELECT COUNT(*)
 15        INTO V_PRODUCT_COUNT
 16        FROM PRODUCTS
 17       WHERE PRODUCT_ID = P_PRODUCT_ID;
 18      IF V_PRODUCT_COUNT = 1 THEN
 19        UPDATE PRODUCTS
 20           SET PRICE = PRICE * P_FACTOR
 21         WHERE PRODUCT_ID = P_PRODUCT_ID;
 22        COMMIT;
 23      END IF;
  EXCEPTION
 24   25      WHEN NO_DATA_FOUND THEN
 26        ROLLBACK;
 27  
 28    END UPDATE_PRODUCT_PRICE;
 29  END PRODUCT_PACKAGE;  
 30  /
Package body created.
SQL> select PRODUCT_PACKAGE.GET_PRODUCTS_REF_CURSOR from dual;
GET_PRODUCTS_REF_CUR
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
PRODUCT_ID      PRICE
---------- ----------
         1      10000
         2       1000
         3        100
         4      20000
         5       2000
         6        200
         7          2
         8     100000
         9        100
9 rows selected.
================================================================
lightdb@postgres=# CREATE OR REPLACE PACKAGE PRODUCT_PACKAGE 
lightdb@postgres-# IS
lightdb@postgres$#   TYPE T_REF_CURSOR IS REF CURSOR;
lightdb@postgres$#   FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR;
lightdb@postgres$#   PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,P_FACTOR IN NUMBER);
lightdb@postgres$# END PRODUCT_PACKAGE;
lightdb@postgres$# /
NOTICE:  type reference products.product_id%TYPE converted to numeric
CREATE PACKAGE
lightdb@postgres=# /*包體*/
lightdb@postgres-# CREATE OR REPLACE PACKAGE BODY PRODUCT_PACKAGE
lightdb@postgres-#  IS
lightdb@postgres$#   FUNCTION GET_PRODUCTS_REF_CURSOR RETURN T_REF_CURSOR IS
lightdb@postgres$#     V_PRODUCTS_REF_CURSOR T_REF_CURSOR;
lightdb@postgres$#   BEGIN
lightdb@postgres$#     OPEN V_PRODUCTS_REF_CURSOR FOR
lightdb@postgres$#       SELECT PRODUCT_ID, PRICE FROM PRODUCTS;
lightdb@postgres$#     RETURN V_PRODUCTS_REF_CURSOR;
lightdb@postgres$#   END GET_PRODUCTS_REF_CURSOR;
lightdb@postgres$#   PROCEDURE UPDATE_PRODUCT_PRICE(P_PRODUCT_ID IN PRODUCTS.PRODUCT_ID%TYPE,
lightdb@postgres$#                                  P_FACTOR     IN NUMBER) IS
lightdb@postgres$#     V_PRODUCT_COUNT NUMBER;
lightdb@postgres$#   BEGIN
lightdb@postgres$#     SELECT COUNT(*)
lightdb@postgres$#       INTO V_PRODUCT_COUNT
lightdb@postgres$#       FROM PRODUCTS
lightdb@postgres$#      WHERE PRODUCT_ID = P_PRODUCT_ID;
lightdb@postgres$#     IF V_PRODUCT_COUNT = 1 THEN
lightdb@postgres$#       UPDATE PRODUCTS
lightdb@postgres$#          SET PRICE = PRICE * P_FACTOR
lightdb@postgres$#        WHERE PRODUCT_ID = P_PRODUCT_ID;
lightdb@postgres$#       COMMIT;
lightdb@postgres$#     END IF;
lightdb@postgres$#   EXCEPTION
lightdb@postgres$#     WHEN NO_DATA_FOUND THEN
lightdb@postgres$#       ROLLBACK;
lightdb@postgres$# 
lightdb@postgres$#   END UPDATE_PRODUCT_PRICE;
lightdb@postgres$# END PRODUCT_PACKAGE;  
lightdb@postgres$# /
NOTICE:  type reference products.product_id%TYPE converted to numeric
CREATE PACKAGE BODY
lightdb@postgres=# select PRODUCT_PACKAGE.GET_PRODUCTS_REF_CURSOR from dual;
 get_products_ref_cursor 
-------------------------
 <unnamed portal 1>
(1 row)

兩者返回的都是隱式遊標名,只是兩者對於隱式遊標的命名方式不同,查詢結果不同,使用內容一致。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29990276/viewspace-2908983/,如需轉載,請註明出處,否則將追究法律責任。

相關文章