记录这篇文章前,是今天写了一个存过的需求,嗯,咋说,不想新建临时表,所以想了下用自定义type的形式想办法在纯过里面搞一个table级别的数据集合,先上代码:
CREATE OR REPLACE PROCEDURE GET_TAG_COM(
INDATA IN VARCHAR2,
OUTDATA OUT SYS_REFCURSOR
)
IS
-----------------重点:自定义类型-------------------------------------------------------------
V_MYTAB1 MYTABLE_COL1_TAB;
V_MYTAB4 MYTABLE_COL4_TAB;
V_INDATA MYARRAY;
V_ONEDATA MYARRAY;
---------------------------------------------------------------------------------------------
V_CONDITION VARCHAR2(30000);
I NUMBER;
V_QUERYID NUMBER;
V_TIME NUMBER;
V_SQL1 VARCHAR2(30000);
V_SQL2 VARCHAR2(30000);
BEGIN
--自定义方法用于数据库切分字符串------------------------------------------
--前端入参格式:["UPDATETIME=5,isCalCount=Y,CHANNELID=21,QUERYID=1,PageIndex=1,startLine=1,recCount=20,PageSize=20"]
--自定义函数切分后得到的格式:["UPDATETIME=5","isCalCount=Y","CHANNELID=21","QUERYID=1","PageIndex=1","startLine=1","recCount=20","PageSize=20"]
V_INDATA := COMMON_FUNC.SplitString(INDATA,',');
--用于where后面的sql拼接,一个很好的解决是否要and的方法
V_CONDITION := ' AND 1=1';
--循环遍历的初始赋值
I := 0
FOR I IN 1 .. V_INDATA.COUNT LOOP
--再次调用自定义切分函数,由于第一次已经把字符串切分成一个数组,这里循环数组取出单个进行而且切分
--切分前格式:["UPDATETIME=5"]
--切分后格式:["UPDATETIME","5"]
V_ONEDATA := COMMON_FUNC.SplitString(V_INDATA(I),'=');
IF UPPER(V_ONEDATA(1)) = 'QUERYID'
THEN
--由于二次切分,就可以更具数组判定入参值了,甚至还能调整想要的参数
V_QUERYID := TO_NUMBER(V_ONEDATA(2));
ELSIF UPPER(V_ONEDATA(1)) = 'UPDATETIME'
THEN
V_TIME := TO_NUMBER(V_ONEDATA(2)/(24*60));
END IF;
END LOOP;
---------------------------------全量--------------------------------------------------
--根据入参可以分逻辑处理事件
IF V_QUERYID = 1
THEN
--------------------------------获取参数数据--------------------------------------------
FOR I IN 1 .. V_INDATA.COUNT LOOP
V_ONEDATA := COMMON_FUNC.SplitString(V_INDATA(1),'=');
--这里再次调用自定义二次切分函数,通过凭借到where 1=1 可以得到where条件的拼接
SELECT V_CONDITION || DECODE(V_ONEDATA(1),
'CHANNELID',
' AND TZC.Channelid IN( ''' || REPLACE(V_ONEDATA(2),'