Oracle-存储过程示例

时光总嘲笑我的痴心妄想 提交于 2020-01-10 01:45:25

方式1:

--(1) 创建将“卡片编号”以“指定字符串”进行拆分,并通过表结构返回结果。
CREATE OR REPLACE TYPE STR_SPLIT IS TABLE OF VARCHAR2 (4000);
CREATE OR REPLACE FUNCTION SPLITSTR(P_STRING IN VARCHAR2, P_DELIMITER IN VARCHAR2)
    RETURN STR_SPLIT
    PIPELINED
AS
    V_LENGTH   NUMBER := LENGTH(P_STRING);
    V_START    NUMBER := 1;
    V_INDEX    NUMBER;
BEGIN
    WHILE(V_START <= V_LENGTH)
    LOOP
        V_INDEX := INSTR(P_STRING, P_DELIMITER, V_START);

        IF V_INDEX = 0
        THEN
            PIPE ROW(SUBSTR(P_STRING, V_START));
            V_START := V_LENGTH + 1;
        ELSE
            PIPE ROW(SUBSTR(P_STRING, V_START, V_INDEX - V_START));
            V_START := V_INDEX + 1;
        END IF;
    END LOOP;
    RETURN;
END SPLITSTR;
 

--(2) 创建生成新版本卡片的存储过程
CREATE OR REPLACE PROCEDURE PROC_CREATENEWCARDVERSION(SRCUNITCODE VARCHAR2, DSTPERIOD INTEGER, DSTCARDVALIDTIME date, DSTCARDINVALIDTIME date, SRCCARDBILLCODES VARCHAR2)
AS
--获取这些卡片编号下对应的最后一个版本卡片数据
CURSOR C_SRCCARD IS SELECT T.RECID, T.COSTVALUE, T.AVE, T.DPRCTVALUE
                       FROM (SELECT A.RECID, A.COSTVALUE, A.AVE, A.DPRCTVALUE, ROW_NUMBER() OVER (PARTITION BY A.ORGUNIT, A.BILLCODE ORDER BY A.INVALIDTIME DESC) AS RN
                               FROM AM_CARD A
                               WHERE A.ORGUNIT = (SELECT RECID FROM MD_ORG WHERE STDCODE = SRCUNITCODE)
                                 AND A.BILLCODE IN (SELECT * FROM TABLE(SPLITSTR(SRCCARDBILLCODES,',')))
                             ) T
                      WHERE T.RN = 1;
                      
--获取卡片表所有字段标识
CURSOR C_CARDFIELD IS SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME= 'AM_CARD' ORDER BY COLUMN_NAME;
--定义游标类型
SRCCARD C_SRCCARD%ROWTYPE;
CARDFIELD C_CARDFIELD%ROWTYPE;

--第一步:准备SQL:生成一个卡片新版本数据
INSERTNEWCARDSQL VARCHAR2(10000) := NULL;
INSERTNEWCARDSQL_START VARCHAR2(4000) := NULL;
INSERTNEWCARDSQL_END VARCHAR2(4000) := NULL;
--第二步:准备SQL:更新旧版本的版本相关系统字段
UPDATESRCCARDSQL VARCHAR2(300):= NULL;
--达梦:NEWRECVERCARDRECID VARBINARY(8188) := NULL; ORACLE: NEWRECVERCARDRECID RAW(16) := NULL
NEWRECVERCARDRECID VARBINARY(8188):= NULL;
BEGIN
  FOR SRCCARD IN C_SRCCARD LOOP
    EXIT WHEN C_SRCCARD%NOTFOUND;
    --重置复制新版本卡片SQL
    INSERTNEWCARDSQL := NULL;
    INSERTNEWCARDSQL_START := NULL;
    INSERTNEWCARDSQL_END := NULL;
    UPDATESRCCARDSQL := NULL;
    --准备待生成新版本卡片的随机RECID
    NEWRECVERCARDRECID := SYS_GUID();
    --第一步:生成一个卡片新版本数据:Insert into Table2(recid,field1,field2,...) select NEWRECVERCARDRECID,value1,value2,... from am_card where recid='srcrecid';
    FOR CARDFIELD IN C_CARDFIELD LOOP
      EXIT WHEN C_CARDFIELD%NOTFOUND;
      INSERTNEWCARDSQL_START := INSERTNEWCARDSQL_START || CARDFIELD.COLUMN_NAME || ',';
        IF CARDFIELD.COLUMN_NAME      = 'RECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || NEWRECVERCARDRECID || '''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISVALID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 1 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'VALIDTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDVALIDTIME || '''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'INVALIDTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDINVALIDTIME || '''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'DSTRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 'NULL' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'SRCRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || SRCCARD.RECID || '''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'BIZTYPEID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000002''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'LOCKRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000001''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'LOCKDEFID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000002''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'BIZMEMO' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''月结''' || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'PERIOD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || DSTPERIOD || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISNEW' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISDPRCT' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISINPUTLOAD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ACTUALREPAIRVALUE' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISREPAIRPICK' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'CURRDPRCTVALUE' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'ISDPRCT_TAX' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'CURRDPRCTVALUE_TAX' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'COSTBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARD.COSTVALUE || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'COSTD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'COSTC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'AVEBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARD.AVE || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'AVED' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'AVEC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'DPRCTBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARD.DPRCTVALUE || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'DPRCTD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'DPRCTC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELD.COLUMN_NAME   = 'LOGTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDVALIDTIME || '''' || ',' ;
        ELSE
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || CARDFIELD.COLUMN_NAME || ',';
      END IF;
    END LOOP;
    INSERTNEWCARDSQL := 'INSERT INTO AM_CARD (' || substr(INSERTNEWCARDSQL_START, 0, length(INSERTNEWCARDSQL_START)-1) || ') SELECT ' || substr(INSERTNEWCARDSQL_END, 0, length(INSERTNEWCARDSQL_END)-1) || ' FROM AM_CARD WHERE RECID = ' || '''' || SRCCARD.RECID || '''';
    --执行生成新版本卡片数据
    execute immediate INSERTNEWCARDSQL;
    COMMIT;
    --第二步:更新旧版本的版本相关系统字段
    UPDATESRCCARDSQL = 'UPDATE AM_CARD A SET DSTRECID = ' || '''' || NEWRECVERCARDRECID || '''' || ', ISVALID =0, INVALIDTIME =' || '''' || DSTCARDVALIDTIME || '''' || ' WHERE A.RECID = ' || '''' || SRCCARD.RECID || '''';
    execute immediate UPDATESRCCARDSQL;
    COMMIT;
  END LOOP;
  CLOSE C_CARDFIELD;
  CLOSE C_SRCCARD;
END;
--CALL "JQ_FSSC"."PROC_CREATENEWCARDVERSION"('T02001001','5','2016/04/30','2016/04/30','03010022,03010023');


 

方式2

CREATE OR REPLACE PROCEDURE PROC_CREATENEWCARDVERSION(SRCUNITCODE VARCHAR2, DSTPERIOD INTEGER, DSTCARDVALIDTIME date, DSTCARDINVALIDTIME date, SRCCARDBILLCODES VARCHAR2)
AS
--定义游标类型
TYPE C_SRCCARDTYPE IS REF CURSOR;
TYPE C_CARDFIELDTYPE IS REF CURSOR;
C_SRCCARD C_SRCCARDTYPE;
C_CARDFIELD C_CARDFIELDTYPE;

--定义游标参数
SQL_SRCCARD VARCHAR2(3000):= NULL;
SQL_CARDFIELD VARCHAR2(300):= NULL;
CARDFIELDNAME VARCHAR2(100) := NULL;--卡片字段标识

--第一步:准备SQL:生成一个卡片新版本数据
INSERTNEWCARDSQL VARCHAR2(10000) := NULL;
INSERTNEWCARDSQL_START VARCHAR2(4000) := NULL;
INSERTNEWCARDSQL_END VARCHAR2(4000) := NULL;
--第二步:准备SQL:更新旧版本的版本相关系统字段
UPDATESRCCARDSQL VARCHAR2(300):= NULL;
--达梦:NEWRECVERCARDRECID VARBINARY(8188) := NULL; ORACLE: NEWRECVERCARDRECID RAW(16) := NULL
NEWRECVERCARDRECID VARBINARY(8188):= NULL;
SRCCARDRECID VARBINARY(8188):= NULL;
SRCCARDCOSTVALUE NUMBER(18,2) := 0;
SRCCARDAVE NUMBER(18,2):= 0;
SRCCARDDPRCTVALUE NUMBER(18,2):= 0;
BEGIN
  --获取这些卡片编号下对应的最后一个版本卡片数据
  SQL_SRCCARD := 'SELECT T.RECID, T.COSTVALUE, T.AVE, T.DPRCTVALUE FROM AM_CARD T WHERE T.RECID IN (SELECT T.RECID
                       FROM (SELECT A.RECID, ROW_NUMBER() OVER (PARTITION BY A.ORGUNIT, A.BILLCODE ORDER BY A.INVALIDTIME DESC) AS RN
                               FROM AM_CARD A
                               WHERE A.ORGUNIT = (SELECT RECID FROM MD_ORG WHERE STDCODE =' || '''' || SRCUNITCODE || '''' || ')
                                 AND A.BILLCODE IN ('||'''' || REPLACE(SRCCARDBILLCODES, ',' , ''',''') || '''' ||')) T
                      WHERE T.RN = 1)';
  --获取卡片表所有字段标识
  SQL_CARDFIELD := 'SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME= ' || '''AM_CARD''' || ' ORDER BY COLUMN_NAME';
 
  --DBMS_OUTPUT.PUT_LINE(SQL_SRCCARD);
  --DBMS_OUTPUT.PUT_LINE(SQL_CARDFIELD);
 
  OPEN C_SRCCARD FOR SQL_SRCCARD;
  LOOP
    FETCH C_SRCCARD INTO SRCCARDRECID, SRCCARDCOSTVALUE, SRCCARDAVE, SRCCARDDPRCTVALUE;
    EXIT WHEN C_SRCCARD%NOTFOUND;
    --重置复制新版本卡片SQL
    INSERTNEWCARDSQL := NULL;
    INSERTNEWCARDSQL_START := NULL;
    INSERTNEWCARDSQL_END := NULL;
    UPDATESRCCARDSQL := NULL;
    --准备待生成新版本卡片的随机RECID
    NEWRECVERCARDRECID := SYS_GUID();
    --第一步:生成一个卡片新版本数据:Insert into Table2(recid,field1,field2,...) select NEWRECVERCARDRECID,value1,value2,... from am_card where recid='srcrecid';
    OPEN C_CARDFIELD FOR SQL_CARDFIELD;
    LOOP
      FETCH C_CARDFIELD INTO CARDFIELDNAME;
      EXIT WHEN C_CARDFIELD%NOTFOUND;
      INSERTNEWCARDSQL_START := INSERTNEWCARDSQL_START || CARDFIELDNAME || ',';
        IF CARDFIELDNAME              = 'RECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || NEWRECVERCARDRECID || '''' || ',';
        ELSIF CARDFIELDNAME           = 'ISVALID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 1 || ',';
        ELSIF CARDFIELDNAME           = 'VALIDTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDVALIDTIME || '''' || ',';
        ELSIF CARDFIELDNAME           = 'INVALIDTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDINVALIDTIME || '''' || ',';
        ELSIF CARDFIELDNAME           = 'DSTRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 'NULL' || ',';
        ELSIF CARDFIELDNAME           = 'SRCRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || SRCCARDRECID || '''' || ',';
        ELSIF CARDFIELDNAME           = 'BIZTYPEID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000002''' || ',';
        ELSIF CARDFIELDNAME           = 'LOCKRECID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000001''' || ',';
        ELSIF CARDFIELDNAME           = 'LOCKDEFID' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''00000000000000000000000000000002''' || ',';
        ELSIF CARDFIELDNAME           = 'BIZMEMO' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''月结''' || ',';
        ELSIF CARDFIELDNAME           = 'PERIOD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || DSTPERIOD || ',';
        ELSIF CARDFIELDNAME           = 'ISNEW' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'ISDPRCT' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'ISINPUTLOAD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'ACTUALREPAIRVALUE' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'ISREPAIRPICK' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'CURRDPRCTVALUE' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'ISDPRCT_TAX' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'CURRDPRCTVALUE_TAX' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'COSTBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARDCOSTVALUE || ',';
        ELSIF CARDFIELDNAME           = 'COSTD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'COSTC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'AVEBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARDAVE || ',';
        ELSIF CARDFIELDNAME           = 'AVED' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'AVEC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'DPRCTBF' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || SRCCARDDPRCTVALUE || ',';
        ELSIF CARDFIELDNAME           = 'DPRCTD' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'DPRCTC' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || 0 || ',';
        ELSIF CARDFIELDNAME           = 'LOGTIME' THEN
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || '''' || DSTCARDVALIDTIME || '''' || ',' ;
        ELSE
                INSERTNEWCARDSQL_END := INSERTNEWCARDSQL_END || CARDFIELDNAME || ',';
        END IF;
    END LOOP;
    INSERTNEWCARDSQL := 'INSERT INTO AM_CARD (' || substr(INSERTNEWCARDSQL_START, 0, length(INSERTNEWCARDSQL_START)-1) || ') SELECT ' || substr(INSERTNEWCARDSQL_END, 0, length(INSERTNEWCARDSQL_END)-1) || ' FROM AM_CARD WHERE RECID = ' || '''' ||SRCCARDRECID || '''';
    --执行生成新版本卡片数据
    execute immediate INSERTNEWCARDSQL;
    COMMIT;
    --第二步:更新旧版本的版本相关系统字段
    UPDATESRCCARDSQL = 'UPDATE AM_CARD A SET DSTRECID = ' || '''' || NEWRECVERCARDRECID || '''' || ', ISVALID =0, INVALIDTIME =' || '''' || DSTCARDVALIDTIME || '''' || ' WHERE A.RECID = ' || '''' || SRCCARDRECID || '''';
    execute immediate UPDATESRCCARDSQL;
    COMMIT;
  END LOOP;
  CLOSE C_CARDFIELD;
  CLOSE C_SRCCARD;
END;
--CALL PROC_CREATENEWCARDVERSION('T02001001',9,'2016/04/30 12:00:00','9999/12/31 12:00:00','03010024,03010025');

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!