前两天改了一个小的无参存储过程,以至于差点忽略掉参数的重要性,今天改了一个大约700行的存储过程,本身有参数传入并计算出返回值,感受到参数的重要性,这次分享下含参存储过程的学习总结;
含参存储过程结构:
create or replace procedure A(B in varchar,C out integer,D out SYS_REFCURSOR)
as V_B
begin
end;
这里我定义了存储过程A的三个参数B C D,由之前经验分享得知,B是只能传出,不会传出,C D 是传出参数,不能传入;
此次我遇到的问题是线上传一个字符串,要通过存储过程解析求得值并反馈回字段;
所以存储过程写了一个B的in类型接字符串值,B拿到值后,通过变量的赋值的形式附到变量上去计算,最后同步变量计算赋值到返回类型的C 和D上进行返回值处理,原存储过程如下:
CREATE OR REPLACE PACKAGE BODY COMMON_QUERY_3 IS
PROCEDURE GET_MERCHANT_ORDER_LIST(INDATA IN VARCHAR2
,TOTAL OUT INTEGER
,OUTDATA OUT SYS_REFCURSOR) AS
I INTEGER;
V_MYVALS MYARRAY; --查询条件
V_ONEVALS MYARRAY;
V_MYSQL VARCHAR2(30000); --返回用
V_SQLCOUNT VARCHAR2(30000); --统计用
V_PAGEINDEX INTEGER DEFAULT 1; --页码
V_PAGESIZE INTEGER DEFAULT 10; --每页条数
V_CONDITION VARCHAR2(5000); --查询列表集用
V_CONDITION_SPLIT VARCHAR2(5000); --查询拆分订单用
V_START_RN INTEGER; --起始数据rownumber
V_END_RN INTEGER; --结束数据rownumber
V_ISEXP INTEGER; --是否为导出需求
V_MERCHANTID INTEGER;
BEGINa
TOTAL := 0;
V_MYVALS := COMMON_FUNC.SPLITSTRING(INDATA, ',');
V_CONDITION := ' WHERE 1=1
';
V_CONDITION_SPLIT := ' WHERE 1=1
';
--FOR 查询分类
FOR I IN 1 .. V_MYVALS.COUNT LOOP
V_ONEVALS := COMMON_FUNC.SPLITSTRING(V_MYVALS(I), '=');
IF UPPER(V_ONEVALS(1)) = 'MERCHANTID' AND V_ONEVALS(2) IS NOT NULL
THEN
--商户编号
V_MERCHANTID := TO_NUMBER(V_ONEVALS(2));
V_CONDITION := V_CONDITION || ' AND (TCI.BUSINESS_ID = ' || TO_NUMBER(V_ONEVALS(2))
|| ' OR TMI.ID = ' || TO_NUMBER(V_ONEVALS(2)) || ') ';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND (TCI.BUSINESS_ID = ' || TO_NUMBER(V_ONEVALS(2))
|| ' OR TMI.ID = ' || TO_NUMBER(V_ONEVALS(2)) || ') ';
ELSIF UPPER(V_ONEVALS(1)) = 'COMMODITYID' AND V_ONEVALS(2) IS NOT NULL
THEN
--商品编号
V_CONDITION := V_CONDITION || ' AND TCIO.COMMODITY_ID = ' || TO_NUMBER(V_ONEVALS(2));
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCSIO.COMMODITY_ID = ' || TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'SPAY_TIME' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单支付开始时间
V_CONDITION := V_CONDITION || ' AND TCO.PAY_TIME >= date''' || V_ONEVALS(2) || '''';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCSO.PAY_TIME >= date''' || V_ONEVALS(2) || '''';
ELSIF UPPER(V_ONEVALS(1)) = 'EPAY_TIME' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单支付结束时间
V_CONDITION := V_CONDITION || ' AND TCO.PAY_TIME < date''' || V_ONEVALS(2) || ''' + 1 ';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCSO.PAY_TIME < date''' || V_ONEVALS(2) || ''' + 1 ';
ELSIF UPPER(V_ONEVALS(1)) = 'SEND_TIME' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单签收开始时间
V_CONDITION := V_CONDITION || ' AND TCIO.END_TIME >= date''' || V_ONEVALS(2) || '''';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCIO.END_TIME >= date''' || V_ONEVALS(2) || '''';
ELSIF UPPER(V_ONEVALS(1)) = 'EEND_TIME' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单签收结束时间
V_CONDITION := V_CONDITION || ' AND TCIO.END_TIME < date''' || V_ONEVALS(2) || ''' + 1';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCIO.END_TIME < date''' || V_ONEVALS(2) || ''' + 1';
ELSIF UPPER(V_ONEVALS(1)) = 'ORDER_STATUS' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单状态
V_CONDITION := V_CONDITION || ' AND TCO.STATUS = ' || TO_NUMBER(V_ONEVALS(2));
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCO.STATUS = ' || TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'CARDNO' AND V_ONEVALS(2) IS NOT NULL
THEN
--商品卡号
V_CONDITION := V_CONDITION || ' AND TCD.CARDNO = ''' || V_ONEVALS(2) || '''';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCD.CARDNO = ''' || V_ONEVALS(2) || '''';
ELSIF UPPER(V_ONEVALS(1)) = 'ORDER_ID' AND V_ONEVALS(2) IS NOT NULL
THEN
--订单编号
V_CONDITION := V_CONDITION || ' AND TCO.ORDER_ID = ' || TO_NUMBER(V_ONEVALS(2));
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCSO.ORDER_ID = ' || TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'CUST_ID' AND V_ONEVALS(2) IS NOT NULL
THEN
--客户编号
V_CONDITION := V_CONDITION || ' AND TCO.CUST_ID = ''' || V_ONEVALS(2) || '''';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCO.CUST_ID = ''' || V_ONEVALS(2) || '''';
ELSIF UPPER(V_ONEVALS(1)) = 'STATUS' AND V_ONEVALS(2) IS NOT NULL
THEN
--发货状态
V_CONDITION := V_CONDITION || ' AND TCIO.STATUS = ' || TO_NUMBER(V_ONEVALS(2));
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCIO.STATUS = ' || TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'LEVEL_ID' AND V_ONEVALS(2) IS NOT NULL
THEN
--仓库编号
V_CONDITION := V_CONDITION || ' AND TCI.LEVEL_ID = ' || TO_NUMBER(V_ONEVALS(2));
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' AND TCI.LEVEL_ID = ' || TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'MOBILE_NO' AND V_ONEVALS(2) IS NOT NULL
THEN
--下单手机号
V_CONDITION := V_CONDITION || ' and tco.username_tx = ''' || V_ONEVALS(2) || '''';
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' and tco.username_tx = ''' || V_ONEVALS(2) || '''';
ELSIF UPPER(V_ONEVALS(1)) = 'DELAYED_STATUS' AND V_ONEVALS(2) IS NOT NULL
THEN
--延迟发货
V_CONDITION := V_CONDITION || ' and tco.DELAYED_STATUS = ' || V_ONEVALS(2) ;
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' and tco.DELAYED_STATUS = ' || V_ONEVALS(2) ;
ELSIF UPPER(V_ONEVALS(1)) = 'PAGEINDEX' AND V_ONEVALS(2) IS NOT NULL
THEN
--页码
V_PAGEINDEX := TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'PAGESIZE' AND V_ONEVALS(2) IS NOT NULL
THEN
--每页条数
V_PAGESIZE := TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'ISEXP' AND V_ONEVALS(2) IS NOT NULL
THEN
--是否为导出
V_ISEXP := TO_NUMBER(V_ONEVALS(2));
ELSIF UPPER(V_ONEVALS(1)) = 'TIME_OUT' AND V_ONEVALS(2) IS NOT NULL
THEN
--超时发货
IF V_ONEVALS(2) = 1 THEN
V_CONDITION := V_CONDITION || ' and NVL(TCIO.OUT_TIME,SYSDATE)-TCO.PAY_TIME > 2 AND TCI.TYPE_ID = 1' ;
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' and NVL(TCIO.OUT_TIME,SYSDATE)-TCO.PAY_TIME > 2 AND TCI.TYPE_ID = 1' ;
ELSIF V_ONEVALS(2) = 0 THEN
V_CONDITION := V_CONDITION || ' and ((NVL(TCIO.OUT_TIME,SYSDATE)-TCO.PAY_TIME <= 2 AND TCI.TYPE_ID = 1) OR TCI.TYPE_ID <>1) ' ;
V_CONDITION_SPLIT := V_CONDITION_SPLIT || ' and ((NVL(TCIO.OUT_TIME,SYSDATE)-TCO.PAY_TIME <= 2 AND TCI.TYPE_ID = 1) OR TCI.TYPE_ID <>1)' ;
END IF;
END IF;
END LOOP;
V_START_RN := (V_PAGEINDEX - 1) * V_PAGESIZE + 1;
V_END_RN := (V_PAGEINDEX) * V_PAGESIZE;
V_MYSQL := '
tableA
' || V_CONDITION_SPLIT || ') A )';
V_SQLCOUNT := '
WITH RESULTTAB AS (
SELECT /*+index(TCO,IDX_COMMODRDER_PAYDATE) use_nl(TCO,TCIO) use_nl(TCIO,TCI)*/
DISTINCT TCIO.ID 序号
FROM T_COMMODITY_ORDER TCO
LEFT JOIN T_COMMODITY_INORDER TCIO ON TCIO.ORDER_ID = TCO.ORDER_ID
LEFT JOIN T_COMMODITY_INFO TCI ON TCIO.COMMODITY_ID = TCI.COMMODITY_ID
LEFT JOIN T_COMMODITY_DUMMY TCD ON TCIO.ID = TCD.BUYID
LEFT JOIN T_MERCHANT_INFO TMI ON TCO.OPERATOR = TMI.BWAP_CHANNEL
' || V_CONDITION || ' AND TCO.IS_SPLIT = 0
UNION ALL
SELECT /*+index(TCO,IDX_COMMOSPLITDRDER_PAYDATE) use_nl(TCO,TCIO) use_nl(TCIO,TCI)*/
DISTINCT TCSIO.ID 序号
FROM T_COMMODITY_SPLIT_ORDER TCSO
JOIN T_COMMODITY_SPLIT_INORDER TCSIO ON TCSIO.ORDER_ID = TCSO.ORDER_ID
JOIN T_COMMODITY_ORDER TCO ON TCSO.MAIN_ORDERID = TCO.ORDER_ID
JOIN T_COMMODITY_INORDER TCIO ON TCO.ORDER_ID = TCIO.ORDER_ID
LEFT JOIN T_COMMODITY_INFO TCI ON TCIO.COMMODITY_ID = TCI.COMMODITY_ID
LEFT JOIN T_COMMODITY_SPLIT_DUMMY TCSD ON TCSIO.ID = TCSD.ORDER_DETAIL_ID
LEFT JOIN T_COMMODITY_DUMMY TCD ON TCSD.ID = TCD.ID
LEFT JOIN T_MERCHANT_INFO TMI ON TCO.OPERATOR = TMI.BWAP_CHANNEL
' || V_CONDITION_SPLIT || ')
SELECT COUNT(*) FROM RESULTTAB';
V_MYSQL := V_MYSQL || '
SELECT 下单时间, 支付时间, 发货时间, 配送物流公司, 运单号,是否超时发货
FROM RESULTTAB RT WHERE RN >= :A AND RN <= :B
ORDER BY RN';
dbms_output.put_line(V_MYSQL);
EXECUTE IMMEDIATE V_SQLCOUNT
INTO TOTAL;
--如果为导出则全量
IF V_ISEXP = 1
THEN
V_START_RN := 1;
V_END_RN := TOTAL;
END IF;
OPEN OUTDATA FOR(V_MYSQL)
USING V_START_RN, V_END_RN;
END GET_MERCHANT_ORDER_LIST;