方式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');
来源:CSDN
作者:尼古拉斯.小王
链接:https://blog.csdn.net/wjh5240313226/article/details/52049380