工作常用
--报表:注意:AD_PI_ID对应数据字段 别忽略
-----执行计划
explain plan for sql_statement;
select * from table(dbms_xplan.display);
----后台自动任务(每五分钟运行一次):
DECLARE
JOB_ID PLS_INTEGER;
BEGIN
SYS.DBMS_JOB.SUBMIT(JOB => JOB_ID,
WHAT => 'XQ_MIDSO_GEN;',
INTERVAL => 'sysdate + 5/(24*60)');
COMMIT;
END;
------------------------------------------------------------------------------------------
--自动获取单据编号示例:
v_table_id ad_table.id%TYPE; --采购退货单m_ret_pur表的id
v_m_ret_pur_docno m_ret_pur.docno%TYPE; ----采购退货单m_ret_pur单据编号
--获取表m_ret_pur的id
SELECT id
INTO v_table_id
FROM ad_table
WHERE NAME = upper('m_ret_pur');
--自动生成单据编号
SELECT t.sequencename
INTO v_m_ret_pur_docno
FROM ad_column t
WHERE t.ad_table_id = v_table_id
AND t.dbname = 'DOCNO';
v_m_ret_pur_docno := get_sequenceno(v_m_ret_pur_docno,
v.ad_client_id);
------------------------------------------------------------------------------------------
--查看某表或视图上的触发器
select * from all_triggers WHERE table_name=upper('m_in');
查看代码引用:
select * from user_source a where instr(lower(a.TEXT),'get_sequenceno') >= 1;
--扩展类常用于明细新增商品时,弹出界面,选择颜色尺寸和输入数量
nds.schema.AttributeDetailSupportTableImpl
获取序号生成器语句:
select * from ad_sequence where name='序号生成器名称';
--提交状态:字段翻译器
nds.web.alert.LimitValueAlerter
italic-purple-font-row
green-font-bold-row
---表的扩展属性排序示例---------------------------------
{"orderby":[{"column":"BILL_TYPE","desc":false},{"column":"NC_VOUCH_TEMPLETSET_ID","desc":false},{"column":"DOCNO","desc":false}
,{"column":"DEPFLAG", "asc":true},{"column":"NC_ACCSUBJ_ID", "asc":true}]}
---------------------------------------------------------------
------------------------------------------------------------------------------------
查找存储过程被哪些session锁住而无法编译
select * FROM dba_ddl_locks where name ='OPERATIONDATA_IMP';
--查看被锁的表
select p.spid,c.object_name,b.session_id,b.oracle_username,b.os_user_name ,b.OBJECT_ID,a.sid,a.SERIAL#
from v$process p,v$session a, v$locked_object b,all_objects c
where p.addr=a.paddr and a.process=b.process and c.object_id=b.object_id-- and c.object_id=111579
order by p.SPID;
--查看数据库中的表锁(特定表被哪些session锁住)
SELECT A.OWNER,A.OBJECT_NAME,B.XIDUSN,B.XIDSLOT,B.XIDSQN,B.SESSION_ID,
B.ORACLE_USERNAME,B.OS_USER_NAME,B.PROCESS,B.LOCKED_MODE,C.MACHINE,C.STATUS,
C.SERVER,C.SID,C.SERIAL#,C.PROGRAM
FROM ALL_OBJECTS A,V$LOCKED_OBJECT B,SYS.GV_$SESSION C
WHERE ( A.OBJECT_ID = B.OBJECT_ID )
AND (B.PROCESS = C.PROCESS )
ORDER BY 1,2;
------------------------------------------------------------------------------------
---------------------------临时表无法修改解决------------------------------------
方法一:
select sid, serial#
from v$session
where sid in
(
select sid
from v$lock
where id1 =
(
select object_id
from user_objects
where object_name = upper('rp_o2o_salesources10')
)
);
alter system kill session '140,64317';
方法二:
select 'alter system kill session '||''''||a.SID||','||c.SERIAL#||''';',a.ID1,b.object_name
from v$lock a,dba_objects b,v$session c
where a.ID1=b.object_id and a.SID=c.SID and b.object_name='rp_o2o_salesources10';
alter system kill session 'SID,SERIAL#';
------------------------------------------------------
select count(*) from B_PAY where STATUS = 1 AND id=$OBJECTID$ AND ISACTIVE='Y'
drop index idx_
---------------------------------解析前台配置clob字段
v_sql VARCHAR2(4000);
v_sql1 VARCHAR2(4000);
r_store_ids r_tabid := r_tabid(); --门店id集合
v_sql := get_fitler_sql(v_marketid);
v_sql1 := 'select t.id from c_store t where t.id ' || v_sql;
r_store_ids := f_fast_table(v_sql1);
-----------------------------------------------------------
单对象界面按钮:动作定义内调用动作定义
v_mppp_id b_canso.m_product_pub_po_id%TYPE; --added by xy 20180728
v_query VARCHAR2(255); --added by xy 20180728
v_mppp_tabid ad_table.id%TYPE;--added by xy 20180728
--begin added by xy 20180728
--如果本单的宣传品征订单不为空,则:调用动作定义【撤单 M_PRODUCT_PUB_PO_CANCEL】
IF v_mppp_id IS NOT NULL THEN
SELECT id
INTO v_mppp_tabid
FROM ad_table
WHERE NAME = upper('m_product_pub_po');
v_query := '<id>' || v_mppp_id || '</id><query/><table>' ||
v_mppp_tabid || '</table>';
m_product_pub_po_cancel(p_user_id, v_query, r_code, r_message);
END IF;
--end added by xy 20180728
------------------------------------------------------------------------
---------------------------------------------trigger
CREATE OR REPLACE TRIGGER bi_m_product_pub
BEFORE UPDATE ON m_product_pub
FOR EACH ROW
DECLARE
----------------------------------------------
--author:xy
--date:20180727
--description:
--如果品种状态不为0或1,不允许修改商品编码。
--更新是否有尺寸要求、计量单位、备注、商品编码为最新的是否有尺寸要求、计量单位、备注、商品编码
----------------------------------------------
BEGIN
--如果品种状态不为0或1,不允许修改商品编码
IF (:new.typestatus <> 0 AND :new.typestatus <> 1) THEN
raise_application_error(-20001, '品种状态不为0或1,不允许修改商品编码!');
END IF;
--更新是否有尺寸要求、计量单位、备注、商品编码为最新的是否有尺寸要求、计量单位、备注、商品编码
UPDATE m_product_pub mpp
SET mpp.is_size = :new.is_size, mpp.units = :new.units,
mpp.description = :new.description, mpp.m_product_id = :new.m_product_id;
END;
---------------------------------------------
--AC模板
CREATE OR REPLACE PROCEDURE C_REBATE_ADJUST_AC(p_id IN NUMBER) AS
-------------------------------------------------------------------------
--History1.
--Author:xuyang
--Date:20180604
--Description:
--将库存表中店仓在头表所选的店仓内、款号上对应的供应商为头表所选的供应商、库存数量>0的数据插入到本单明细中
/*店仓:取符合条件的库存表的店仓
条码、商品、ASI:取符合条件的库存表里面的条码、商品、ASI
库存数量:取对应店仓、对应条码的库存数量
采购价:取对应款号档案的采购价
返利:取对应款号档案的固定返利
当期成本:取【商品成本】表中该款号的单品成本
调整成本:取采购价 - 返利
*/
-------------------------------------------------------------------------
begin
end;
-----------------------------------------------------
--提交存储过程模板
CREATE OR REPLACE PROCEDURE m_purchase_submit(p_submittedsheetid IN NUMBER,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
-------------------------------------------------------------------------
--1. Author:XY
--Date:20180728
--Description:
--
--
--
-------------------------------------------------------------------------
v_status number(1);
BEGIN
--并发控制,20120216 add by vetica
EXECUTE IMMEDIATE ('select 1 from table_name t where t.id=' ||
p_submittedsheetid || ' for update');
SELECT ad_client_id, status, modifierid, doctype, docno, p.b_po_id, p.isagt,
description, p.is_bas
INTO v_clientid, v_status, v_userid, v_doctype, v_docno, v_po_id, v_isagt,
v_description, v_is_bas
FROM m_purchase p
WHERE id = p_submittedsheetid;
IF v_status = 2 THEN
raise_application_error(-20201, '单据已提交,不能重复提交!');
END IF;
--更新提交标记,提交人,提交时间
UPDATE m_purchase t
SET t.status = 2, t.statuserid = v_userid, t.statustime = SYSDATE
WHERE t.id = p_submittedsheetid;
UPDATE m_purchaseitem
SET status = 2
WHERE m_purchase_id = p_submittedsheetid;
r_code := 0;
r_message := v_docno || '提交成功!!';
END;
--地素:薪资管理-》基本薪资管理(author:me)
CREATE OR REPLACE PROCEDURE C_BASIC_SALARY_UNSUBMIT(p_submittedsheetid IN NUMBER,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
-------------------------------------------------------------------------
--HISTORY:
--1.AUTHOR:XUYANG
-- DATE:20180601
-- DESCRIPTION: 如果单据未提交,不允许取消提交。
-- 更新单据状态为1、提交人为空、提交时间为空
-------------------------------------------------------------------------
v_status C_BASIC_SALARY.status%TYPE; --单据提交状态
v_docno C_BASIC_SALARY.docno%TYPE; --单据编号
BEGIN
--并发控制
BEGIN
EXECUTE IMMEDIATE 'select 1 from C_BASIC_SALARY t where t.id=' ||
p_submittedsheetid || ' for update nowait';
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20201, '单据正在取消提交,不能重复取消!');
END;
--如果单据未提交,不允许取消提交
SELECT cbs.status, cbs.docno
INTO v_status, v_docno
FROM C_BASIC_SALARY cbs
WHERE cbs.id = p_submittedsheetid;
IF v_status = 1 THEN
raise_application_error(-20201, '单据未提交,不允许取消提交!');
END IF;
-- 更新单据状态为1、提交人为空、提交时间为空
UPDATE C_BASIC_SALARY cbs
SET cbs.status = 1, cbs.statuserid = NULL, cbs.statustime = NULL
WHERE cbs.id = p_submittedsheetid;
r_code := 0;
r_message := v_docno || '取消提交成功!!';
END;
--奇客巴士:成本与月结->返利成本调整ac程序(author:me):
CREATE OR REPLACE PROCEDURE c_rebate_adjust_ac(p_id IN NUMBER) AS
-------------------------------------------------------------------------
--History1.
--Author:xuyang
--Date:20180604
--Description:
--将库存表中店仓在头表所选的店仓内、款号上对应的供应商为头表所选的供应商、库存数量>0的数据插入到本单明细中
/*店仓:取符合条件的库存表的店仓
条码、商品、ASI:取符合条件的库存表里面的条码、商品、ASI
库存数量:取对应店仓、对应条码的库存数量
采购价:取对应款号档案的采购价
返利:取对应款号档案的固定返利
当期成本:取【商品成本】表中该款号的单品成本
调整成本:取采购价 - 返利
--注意:
(1)如果头表的供应商不为空,店仓不为空,则取库存表中店仓在头表所选的店仓内、款号上对应的供应商为头表所选的供应商、库存数量>0的数据插入到本单明细;
(2)如果头表的供应商不为空,店仓为空,则取库存表中、所有店仓下的、库存数量>0的、款号对应的供应商为头表所选供应商的、所有条码的数据插入到明细;
(3)如果头表的供应商为空、店仓不为空,则取所选店仓在库存表中、所有库存数量>0的所有条码的数据插入到明细;
(4)如果头表的供应商为空、店仓为空,则取库存表中、所有店仓下的、库存数量>0的所有条码的数据插入到明细
*/
-------------------------------------------------------------------------
v_ad_client_id c_rebate_adjust.ad_client_id%TYPE;
v_ad_org_id c_rebate_adjust.ad_org_id%TYPE;
v_ownerid c_rebate_adjust.ownerid%TYPE;
--v_modifierid C_REBATE_ADJUST.MODIFIERID%type;
--v_createdate C_REBATE_ADJUST.CREATIONDATE%type;
--v_modifydate C_REBATE_ADJUST.MODIFIEDDATE%type;
--v_cra_id c_rebate_adjust.id%TYPE;
--v_c_store_id c_store.id%type;
v_c_supplier_id c_rebate_adjust.c_supplier_id%TYPE;
/*用于获取所选店仓id集合*/
v_rebate_adjust c_rebate_adjust%ROWTYPE;
v_sql VARCHAR2(4000);
v_sql1 VARCHAR2(4000);
r_store r_tabid := r_tabid(); --店仓集合
v_c_store_filter c_rebate_adjust.c_store_filter%TYPE;
/*用于获取库存中满足条件(1)的数据记录*/
CURSOR cur_fa_storage1 IS
SELECT fas.m_product_id AS m_product_id, fas.c_store_id AS c_store_id,
fas.m_attributesetinstance_id AS m_attributesetinstance_id,
fas.qty AS qtystorage, fas.m_productalias_id AS m_productalias_id,
mp.precost AS precost, mp.fixrebate AS fixrebate,
fapc.percost AS precost_th,
(mp.precost - nvl(mp.fixrebate, 0)) AS precost_adj
FROM fa_storage fas
JOIN m_product mp
ON (fas.m_product_id = mp.id)
LEFT JOIN fa_product_cost fapc
ON (fapc.m_product_id = fas.m_product_id)
WHERE fas.qty > 0
AND mp.c_supplier_id = v_c_supplier_id
AND EXISTS (SELECT 1
FROM TABLE(r_store) t
WHERE t.id = fas.c_store_id);
TYPE list_table1 IS TABLE OF cur_fa_storage1%ROWTYPE INDEX BY BINARY_INTEGER;
type_list_table1 list_table1;
/*用于获取库存中满足条件(2)的数据记录*/
CURSOR cur_fa_storage2 IS
SELECT fas.m_product_id AS m_product_id, fas.c_store_id AS c_store_id,
fas.m_attributesetinstance_id AS m_attributesetinstance_id,
fas.qty AS qtystorage, fas.m_productalias_id AS m_productalias_id,
mp.precost AS precost, mp.fixrebate AS fixrebate,
fapc.percost AS precost_th,
(mp.precost - nvl(mp.fixrebate, 0)) AS precost_adj
FROM fa_storage fas
JOIN m_product mp
ON (fas.m_product_id = mp.id)
LEFT JOIN fa_product_cost fapc
ON (fapc.m_product_id = fas.m_product_id)
WHERE fas.qty > 0
AND mp.c_supplier_id = v_c_supplier_id;
TYPE list_table2 IS TABLE OF cur_fa_storage2%ROWTYPE INDEX BY BINARY_INTEGER;
type_list_table2 list_table2;
/*用于获取库存中满足条件(3)的数据记录*/
CURSOR cur_fa_storage3 IS
SELECT fas.m_product_id AS m_product_id, fas.c_store_id AS c_store_id,
fas.m_attributesetinstance_id AS m_attributesetinstance_id,
fas.qty AS qtystorage, fas.m_productalias_id AS m_productalias_id,
mp.precost AS precost, mp.fixrebate AS fixrebate,
fapc.percost AS precost_th,
(mp.precost - nvl(mp.fixrebate, 0)) AS precost_adj
FROM fa_storage fas
JOIN m_product mp
ON (fas.m_product_id = mp.id)
LEFT JOIN fa_product_cost fapc
ON (fapc.m_product_id = fas.m_product_id)
WHERE fas.qty > 0
AND EXISTS (SELECT 1
FROM TABLE(r_store) t
WHERE t.id = fas.c_store_id);
TYPE list_table3 IS TABLE OF cur_fa_storage3%ROWTYPE INDEX BY BINARY_INTEGER;
type_list_table3 list_table3;
/*用于获取库存中满足条件(4)的数据记录*/
CURSOR cur_fa_storage4 IS
SELECT fas.m_product_id AS m_product_id, fas.c_store_id AS c_store_id,
fas.m_attributesetinstance_id AS m_attributesetinstance_id,
fas.qty AS qtystorage, fas.m_productalias_id AS m_productalias_id,
mp.precost AS precost, mp.fixrebate AS fixrebate,
fapc.percost AS precost_th,
(mp.precost - nvl(mp.fixrebate, 0)) AS precost_adj
FROM fa_storage fas
JOIN m_product mp
ON (fas.m_product_id = mp.id)
LEFT JOIN fa_product_cost fapc
ON (fapc.m_product_id = fas.m_product_id)
WHERE fas.qty > 0;
TYPE list_table4 IS TABLE OF cur_fa_storage4%ROWTYPE INDEX BY BINARY_INTEGER;
type_list_table4 list_table4;
BEGIN
--获取相关数据
SELECT cra.ad_client_id, cra.ad_org_id, cra.ownerid, cra.c_supplier_id,
cra.c_store_filter
INTO v_ad_client_id,v_ad_org_id,v_ownerid, v_c_supplier_id, v_c_store_filter
FROM c_rebate_adjust cra
WHERE cra.id = p_id;
--获取所选店仓集合
IF v_c_store_filter IS NOT NULL THEN
SELECT *
INTO v_rebate_adjust
FROM c_rebate_adjust cra
WHERE cra.id = p_id;
v_sql := get_fitler_sql(v_rebate_adjust.c_store_filter);
v_sql1 := 'select t.id from c_store t where t.id ' || v_sql;
r_store := f_fast_table(v_sql1);
END IF;
--将库存表中店仓在头表所选的店仓内、款号上对应的供应商为头表所选的供应商、库存数量>0的数据插入到本单明细中
IF v_c_supplier_id IS NOT NULL AND r_store.count > 0 THEN
BEGIN
OPEN cur_fa_storage1;
FETCH cur_fa_storage1 BULK COLLECT
INTO type_list_table1;
FORALL idx IN 1 .. type_list_table1.count
INSERT INTO c_rebate_adjustitem crai
(crai.id, crai.ad_client_id, crai.ad_org_id, crai.ownerid,
crai.modifierid, crai.creationdate, crai.modifieddate,
crai.c_rebate_adjust_id, crai.c_store_id,
crai.m_productalias_id, crai.m_product_id, crai.qtystorage,
crai.precost, crai.fixrebate, crai.precost_ths,
crai.precost_adj, crai.m_attributesetinstance_id)
VALUES
(get_sequences('C_REBATE_ADJUSTITEM'), v_ad_client_id,
v_ad_org_id, v_ownerid, NULL, SYSDATE, NULL, p_id,
type_list_table1(idx).c_store_id,
type_list_table1(idx).m_productalias_id,
type_list_table1(idx).m_product_id,
type_list_table1(idx).qtystorage,
type_list_table1(idx).precost,
type_list_table1(idx).fixrebate,
type_list_table1(idx).precost_th,
type_list_table1(idx).precost_adj,
type_list_table1(idx).m_attributesetinstance_id);
CLOSE cur_fa_storage1;
END;
ELSIF v_c_supplier_id IS NOT NULL AND r_store.count = 0 THEN
--如果头表的供应商不为空,店仓为空,则取库存表中、所有店仓下的、库存数量>0的、款号对应的供应商为头表所选供应商的、所有条码的数据插入到明细
BEGIN
OPEN cur_fa_storage2;
FETCH cur_fa_storage2 BULK COLLECT
INTO type_list_table2;
FORALL idx IN 1 .. type_list_table2.count
INSERT INTO c_rebate_adjustitem crai
(crai.id, crai.ad_client_id, crai.ad_org_id, crai.ownerid,
crai.modifierid, crai.creationdate, crai.modifieddate,
crai.c_rebate_adjust_id, crai.c_store_id,
crai.m_productalias_id, crai.m_product_id, crai.qtystorage,
crai.precost, crai.fixrebate, crai.precost_ths,
crai.precost_adj, crai.m_attributesetinstance_id)
VALUES
(get_sequences('C_REBATE_ADJUSTITEM'), v_ad_client_id,
v_ad_org_id, v_ownerid, NULL, SYSDATE, NULL, p_id,
type_list_table2(idx).c_store_id,
type_list_table2(idx).m_productalias_id,
type_list_table2(idx).m_product_id,
type_list_table2(idx).qtystorage,
type_list_table2(idx).precost,
type_list_table2(idx).fixrebate,
type_list_table2(idx).precost_th,
type_list_table2(idx).precost_adj,
type_list_table2(idx).m_attributesetinstance_id);
CLOSE cur_fa_storage2;
END;
ELSIF nvl(v_c_supplier_id, 0) = 0 AND r_store.count > 0 THEN
--如果头表的供应商为空、店仓不为空,则取所选店仓在库存表中、所有库存数量>0的所有条码的数据插入到明细;
BEGIN
OPEN cur_fa_storage3;
FETCH cur_fa_storage3 BULK COLLECT
INTO type_list_table3;
FORALL idx IN 1 .. type_list_table3.count
INSERT INTO c_rebate_adjustitem crai
(crai.id, crai.ad_client_id, crai.ad_org_id, crai.ownerid,
crai.modifierid, crai.creationdate, crai.modifieddate,
crai.c_rebate_adjust_id, crai.c_store_id,
crai.m_productalias_id, crai.m_product_id, crai.qtystorage,
crai.precost, crai.fixrebate, crai.precost_ths,
crai.precost_adj, crai.m_attributesetinstance_id)
VALUES
(get_sequences('C_REBATE_ADJUSTITEM'), v_ad_client_id,
v_ad_org_id, v_ownerid, NULL, SYSDATE, NULL, p_id,
type_list_table3(idx).c_store_id,
type_list_table3(idx).m_productalias_id,
type_list_table3(idx).m_product_id,
type_list_table3(idx).qtystorage,
type_list_table3(idx).precost,
type_list_table3(idx).fixrebate,
type_list_table3(idx).precost_th,
type_list_table3(idx).precost_adj,
type_list_table3(idx).m_attributesetinstance_id);
CLOSE cur_fa_storage3;
END;
ELSE
--如果头表的供应商为空、店仓为空,则取库存表中、所有店仓下的、库存数量>0的所有条码的数据插入到明细
BEGIN
OPEN cur_fa_storage4;
FETCH cur_fa_storage4 BULK COLLECT
INTO type_list_table4;
FORALL idx IN 1 .. type_list_table4.count
INSERT INTO c_rebate_adjustitem
(id, ad_client_id, ad_org_id, ownerid, modifierid,
creationdate, modifieddate, c_rebate_adjust_id, c_store_id,
m_productalias_id, m_product_id, qtystorage, precost,
fixrebate, precost_ths, precost_adj,
m_attributesetinstance_id, isactive)
VALUES
(get_sequences('C_REBATE_ADJUSTITEM'), v_ad_client_id,
v_ad_org_id, v_ownerid, NULL, SYSDATE, NULL, p_id,
type_list_table4(idx).c_store_id,
type_list_table4(idx).m_productalias_id,
type_list_table4(idx).m_product_id,
type_list_table4(idx).qtystorage,
type_list_table4(idx).precost,
type_list_table4(idx).fixrebate,
type_list_table4(idx).precost_th,
type_list_table4(idx).precost_adj,
type_list_table4(idx).m_attributesetinstance_id, 'Y');
CLOSE cur_fa_storage4;
END;
END IF;
END;
----奇客巴士:成本与月结->返利成本调整提交程序(author:me)
CREATE OR REPLACE PROCEDURE c_rebate_adjust_submit(p_submittedsheetid IN NUMBER,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
-------------------------------------------------------------------------
--History:
--1. Author:xuyang
--Date:2018-06-05
--增加控制:如果单据已经提交,不允许再次提交
--增加控制:如果明细中同一个商品存在调整成本不一致的记录,不允许!(提示:商品:XXX,在明细中的调整成本不一致,不允许!)
--增加控制:将本单数据生成一张已提交的成本调整单:
/*
单据编号:自动生成。
单据日期:返利成本调整单的单据日期。
经销商:取经销商级别为‘总部’的经销商档案的ID。
年月:返利成本调整单的单据日期对应的年月。
备注:由返利成本调整单:XXX 提交生成!
*/
--增加控制:将本单明细的数据按照商品汇总,生成成本调整单明细:
/*
商品:返利成本调整单明细的商品。
单品成本:取明细中该商品的调整成本(取平均值,不能取合计值)
*/
--更新单据状态为2、提交人为单据的修改人、提交时间为SYSDATE。
--
-------------------------------------------------------------------------
v_status c_rebate_adjust.status%TYPE; --单据提交状态
v_docno c_rebate_adjust.docno%TYPE; --单据号
v_submituserid c_rebate_adjust.modifierid%TYPE; --提交人为修改人
v_item_cnt NUMBER(10); --明细数量
v_precost_adj c_rebate_adjustitem.precost_adj%TYPE; --调整价
v_billdate c_rebate_adjust.billdate%TYPE; --单据日期
v_m_product_name m_product.name%TYPE; --款号名
v_ownerid c_rebate_adjust.ownerid%TYPE;
v_ad_org_id c_rebate_adjust.ad_org_id%TYPE;
v_ad_client_id c_rebate_adjust.ad_client_id%TYPE;
v_cost_adj_docno fa_costinitial.docno%TYPE; --成本调整单据编号
v_description fa_costinitial.description%TYPE; --成本调整单备注
v_c_customer_id fa_costinitial.c_customer_id%TYPE; --成本调整单经销商id
v_fa_costinitial_id fa_costinitial.id%TYPE;
v_table_id ad_table.id%TYPE; --表fa_costinitial的id
v_norepeat_cnt NUMBER(10); --返利成本调整单明细商品数(不重复)
BEGIN
--并发控制
EXECUTE IMMEDIATE ('select 1 from c_rebate_adjust t where t.id=' ||
p_submittedsheetid || ' for update');
--如果单据已经提交,不允许再次提交
SELECT cra.status, cra.docno, cra.modifierid, cra.billdate, ad_client_id,
ad_org_id, ownerid
INTO v_status, v_docno, v_submituserid, v_billdate, v_ad_client_id,
v_ad_org_id, v_ownerid
FROM c_rebate_adjust cra
WHERE cra.id = p_submittedsheetid;
IF v_status = 2 THEN
raise_application_error(-20201, '单据已提交,不允许重复提交!');
END IF;
--获取明细数量
SELECT COUNT(1)
INTO v_item_cnt
FROM c_rebate_adjustitem crai
WHERE crai.c_rebate_adjust_id = p_submittedsheetid;
--如果明细中同一个商品存在调整成本不一致的记录,不允许!(提示:商品:XXX,在明细中的调整成本不一致,不允许!)
IF v_item_cnt >= 2 THEN
FOR v_list IN (SELECT crai.id, crai.m_product_id,
nvl(crai.precost_adj, 0) AS precost_adj
FROM c_rebate_adjustitem crai
WHERE crai.c_rebate_adjust_id = p_submittedsheetid) LOOP
SELECT nvl(crai1.precost_adj, 0) AS precost_adj
INTO v_precost_adj
FROM c_rebate_adjustitem crai1
WHERE crai1.id <> v_list.id
AND crai1.m_product_id = v_list.m_product_id
AND rownum <= 1;
IF v_list.precost_adj <> v_precost_adj THEN
SELECT mp.name
INTO v_m_product_name
FROM m_product mp
WHERE mp.id = v_list.m_product_id;
raise_application_error(-20201,
'商品:' || v_m_product_name ||
',在明细中的调整成本不一致,不允许!');
END IF;
END LOOP;
END IF;
--增加控制:将本单数据生成一张已提交的成本调整单
/*
单据编号:自动生成。
单据日期:返利成本调整单的单据日期。
经销商:取经销商级别为‘总部’的经销商档案的ID。
年月:返利成本调整单的单据日期对应的年月。
备注:由返利成本调整单:XXX 提交生成!
*/
v_fa_costinitial_id := get_sequences('fa_costinitial');
--获取表fa_costinitial的id
SELECT id
INTO v_table_id
FROM ad_table
WHERE NAME = upper('fa_costinitial');
--自动生成单据编号
SELECT t.sequencename
INTO v_cost_adj_docno
FROM ad_column t
WHERE t.ad_table_id = v_table_id
AND t.dbname = 'DOCNO';
v_cost_adj_docno := get_sequenceno(v_cost_adj_docno, v_ad_client_id);
v_description := '由返利成本调整单:' || v_docno || '提交生成!';
--获取明细商品非重复数量
SELECT COUNT(DISTINCT(m_product_id))
INTO v_norepeat_cnt
FROM c_rebate_adjustitem crai
WHERE crai.c_rebate_adjust_id = p_submittedsheetid;
--取经销商级别为‘总部’的经销商档案的ID
SELECT cc.id
INTO v_c_customer_id
FROM c_customer cc
JOIN c_cusrank ccr
ON (cc.c_cusrank_id = ccr.id)
WHERE ccr.name = '总部';
INSERT INTO fa_costinitial fac
(id, ad_client_id, ad_org_id, ownerid, modifierid, creationdate,
modifieddate, isactive, docno, doctype, billdate, description, status,
au_state, au_pi_id, tot_lines, c_period_id, submitdate, statuserid,
statustime, c_customer_id, yearmonth)
VALUES
(v_fa_costinitial_id, v_ad_client_id, v_ad_org_id, v_ownerid,
v_submituserid, SYSDATE, SYSDATE, 'Y', v_cost_adj_docno, NULL,
v_billdate, v_description, 1, NULL, NULL, v_norepeat_cnt, NULL, NULL,
NULL, NULL, v_c_customer_id, substr(v_billdate, 1, 6));
--增加控制:将本单明细的数据按照商品汇总,生成成本调整单明细:
/*
商品:返利成本调整单明细的商品。
单品成本:取明细中该商品的调整成本(取平均值,不能取合计值)
*/
FOR v_list1 IN (SELECT m_product_id, AVG(precost_adj) AS precost_adj
FROM c_rebate_adjustitem
WHERE c_rebate_adjust_id = p_submittedsheetid
GROUP BY m_product_id) LOOP
INSERT INTO fa_costinitialitem faci
(id, ad_client_id, ad_org_id, ownerid, modifierid, creationdate,
modifieddate, isactive, fa_costinitial_id, m_product_id, percost,
status)
VALUES
(get_sequences('fa_costinitialitem'), v_ad_client_id, v_ad_org_id,
v_ownerid, v_submituserid, SYSDATE, NULL, 'Y', v_fa_costinitial_id,
v_list1.m_product_id, v_list1.precost_adj, 1);
END LOOP;
-- 更新单据状态为2、提交人为单据的修改人、提交时间为SYSDATE
UPDATE c_rebate_adjust cra
SET cra.status = 2, cra.statuserid = v_submituserid,
cra.statustime = SYSDATE
WHERE cra.id = p_submittedsheetid;
r_code := 0;
r_message := v_docno || '提交成功!!';
END;
--新骏:订单总汇报表示例(author:others):
CREATE OR REPLACE PROCEDURE rp_posum_gen(p_pi_id NUMBER) IS
--Author:Arwen
-- 1. Date:20180521
-- Author :Arwen
-- Modification :
/*新增报表模板【订单总汇报表】,类型:统计报表,类别:财务报表,事实表:RP_POSUM,
预计算程序:RP_POSUM_GEN,具体逻辑:
查询条件:单据日期(日期范围、必填) 、商品(关联款号档案,非必填)、
供应商(外键关联供应商档案,多选,非必填)、采购订单(外键关联采购订单,多选,非必填)、
店仓(外键关联店仓档案,多选,非必填)、工厂交期(日期范围、必填)、客人交期(日期范围、必填)
查询逻辑: 取单据日期在查询条件日期范围内、商品在查询条件的商品内、
供应商在查询条件的供应商内、采购订单在查询条件的采购订单内、
采购店仓在查询条件的店仓内、已提交、可用的【采购订单】的数据。*/
-- 2. Date:20180607
-- Author :xuyang
-- Modification :修改汇总字段: 运费和毛利
/* 运费:
原逻辑:取符合条件的销售单对应的销售核价单表头的【运费】字段(如果没有核价单,运费就取0)
现逻辑:取符合条件的销售单对应的销售核价单明细的【运费】字段(如果没有核价单,运费就取0
毛利:
原逻辑:卖价-买价。
现逻辑:卖价-买价-运费
*/
v_sql_0 VARCHAR(4000); --原始SQL
v_modifierid ad_pinstance.modifierid%TYPE; --修改人
v_ad_client_id ad_pinstance.ad_client_id%TYPE; --所属公司
v_ad_org_id ad_pinstance.ad_org_id%TYPE; --所属组织
v_date LONG; --日期
v_datebegin NUMBER(8); --单据日期开始
v_dateend NUMBER(8); --单据日期结束
v_date2 LONG; --日期
v_datebegin2 NUMBER(8); --工厂日期开始
v_dateend2 NUMBER(8); --工厂日期结束
v_date3 LONG; --日期
v_datebegin3 NUMBER(8); --客人日期开始
v_dateend3 NUMBER(8); --客人日期结束
r_c_supplier_id r_tabid; --供应商检索
r_b_po_id r_tabid; --采购订单检索
r_m_product r_tabid; --款号检索
r_c_store r_tabid; --店检索
v_sql_1 LONG; --检索条件1
v_sql_2 LONG; --检索条件2
v_sql_3 LONG; --检索条件3
v_sql_4 LONG;
BEGIN
EXECUTE IMMEDIATE ('truncate TABLE RP_POSUM');
--raise_application_error(-20201, p_pi_id);
/*获取检索条件*/
v_sql_0 := 'select t.info from ad_pinstance_para t
where t.name=:name and t.ad_pinstance_id=:pid';
SELECT t.modifierid, t.ad_client_id, t.ad_org_id
INTO v_modifierid, v_ad_client_id, v_ad_org_id
FROM ad_pinstance t
WHERE t.id = p_pi_id;
--供应商集合
EXECUTE IMMEDIATE v_sql_0
INTO v_sql_1
USING 'SUP', p_pi_id;
r_c_supplier_id := f_fast_table(v_sql_1);
--采购订单
EXECUTE IMMEDIATE v_sql_0
INTO v_sql_2
USING 'DOCNO', p_pi_id;
r_b_po_id := f_fast_table(v_sql_2);
--款号
EXECUTE IMMEDIATE v_sql_0
INTO v_sql_3
USING 'PRODUCT', p_pi_id;
r_m_product := f_fast_table(v_sql_3);
--店仓
EXECUTE IMMEDIATE v_sql_0
INTO v_sql_4
USING 'C_STORE', p_pi_id;
r_c_store := f_fast_table(v_sql_4);
--单据日期
SELECT t.info
INTO v_date
FROM ad_pinstance_para t
WHERE t.name = 'BILLDATE'
AND t.ad_pinstance_id = p_pi_id;
IF v_date IS NULL THEN
--如开始日期和结束日期都没有选择,则查询所有日期范围内数据
v_datebegin := 0;
v_dateend := 20991231;
ELSE
IF instr(v_date, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为20991231
v_dateend := 20991231;
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin
FROM dual;
ELSIF instr(v_date, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为0
v_datebegin := 0;
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend
FROM dual;
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取
SELECT substr(v_date, 21, 8), substr(v_date, 34, 8) --注意这里是不是分别从17,30开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin, v_dateend
FROM dual;
END IF;
END IF;
--工厂交期
SELECT t.info
INTO v_date2
FROM ad_pinstance_para t
WHERE t.name = 'GCJQDATE'
AND t.ad_pinstance_id = p_pi_id;
IF v_date2 IS NULL THEN
--如开始日期和结束日期都没有选择,则查询所有日期范围内数据
v_datebegin2 := 0;
v_dateend2 := 20991231;
ELSE
IF instr(v_date2, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为20991231
v_dateend2 := 20991231;
SELECT substr(v_date2, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin2
FROM dual;
ELSIF instr(v_date2, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为0
v_datebegin2 := 0;
SELECT substr(v_date2, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend2
FROM dual;
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取
SELECT substr(v_date2, 21, 8), substr(v_date2, 34, 8) --注意这里是不是分别从17,30开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin2, v_dateend2
FROM dual;
END IF;
END IF;
--客人交期
SELECT t.info
INTO v_date3
FROM ad_pinstance_para t
WHERE t.name = 'KRJQDATE'
AND t.ad_pinstance_id = p_pi_id;
IF v_date3 IS NULL THEN
--如开始日期和结束日期都没有选择,则查询所有日期范围内数据
v_datebegin3 := 0;
v_dateend3 := 20991231;
ELSE
IF instr(v_date3, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为20991231
v_dateend3 := 20991231;
SELECT substr(v_date3, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin3
FROM dual;
ELSIF instr(v_date3, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为0
v_datebegin3 := 0;
SELECT substr(v_date3, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend3
FROM dual;
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取
SELECT substr(v_date3, 21, 8), substr(v_date3, 34, 8) --注意这里是不是分别从17,30开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin3, v_dateend3
FROM dual;
END IF;
END IF;
/* 原逻辑:取符合条件的销售单对应的销售核价单表头的【运费】字段(如果没有核价单,运费就取0)
现逻辑:取符合条件的销售单对应的销售核价单明细的【运费】字段(如果没有核价单,运费就取0*/
--插入销售值
INSERT INTO rp_posum
(id, ad_client_id, ad_org_id, m_product_id, sa_contractno,
c_customer_id, pdtno, pz, contractno, contractpno, confirmdate,
factorydate, priceactual, amt_tran, sa_qty, sa_qtyout, sa_amtout,
m_attributesetinstance_id, ownerid, creationdate, modifierid,
modifieddate, isactive, ad_pi_id, m_productalias_id, pu_contractno)
SELECT get_sequences('rp_posum'), 37, 27, b.m_product_id,
/* a.contractno_orig*/ a.old_docno, a.c_customer_id, a.pdtno,
a.pz, a.contractno, a.contractpno, a.confirmdate, a.factorydate,
b.priceactual, AVG(nvl(b.amt_tran, 0)), SUM(b.qty), SUM(b.qtyout),
SUM(b.tot_amtout_actual), b.m_attributesetinstance_id,
v_modifierid, SYSDATE, v_modifierid, SYSDATE, 'Y', p_pi_id,
b.m_productalias_id, b.contractno_orig
FROM m_sale a, m_saleitem b, TABLE(r_c_store) rc, TABLE(r_m_product) rp
WHERE a.id = b.m_sale_id
AND b.contractno_orig IS NOT NULL
AND a.status = 2
AND a.isactive = 'Y'
AND a.c_store_id = rc.id
AND b.m_product_id = rp.id
AND a.billdate BETWEEN v_datebegin AND v_dateend
AND a.factorydate BETWEEN v_datebegin2 AND v_dateend2
AND a.confirmdate BETWEEN v_datebegin3 AND v_dateend3
GROUP BY b.m_product_id, /*a.contractno_orig*/ a.old_docno,
a.c_customer_id, a.pdtno, a.pz, a.contractno, a.contractpno,
a.confirmdate, a.factorydate, b.priceactual,
b.m_attributesetinstance_id, b.m_productalias_id,
b.contractno_orig;
--插入采购值
MERGE INTO rp_posum m
USING (SELECT a.id, a.docno, a.billdate, a.old_docno AS contractno,
a.c_supplier_id, b.m_product_id, b.m_productalias_id,
b.m_attributesetinstance_id AS asi,
AVG(b.priceactual) AS po_priceactual, SUM(b.qty) AS po_qty,
SUM(b.qtyconsign) AS po_qtyin
FROM b_po a, b_poitem b, TABLE(r_b_po_id) bp, TABLE(r_c_store) rc,
TABLE(r_m_product) rp, TABLE(r_c_supplier_id) rs
WHERE a.id = b.b_po_id
AND a.id = bp.id
AND a.c_supplier_id = rs.id
AND a.billdate BETWEEN v_datebegin AND v_dateend
AND a.c_store_id = rc.id
AND b.m_product_id = rp.id
GROUP BY a.id, a.docno, a.billdate, a.old_docno, a.c_supplier_id,
b.m_product_id, b.m_productalias_id,
b.m_attributesetinstance_id) n
ON (m.pu_contractno = n.contractno AND m.m_productalias_id = n.m_productalias_id)
WHEN MATCHED THEN
UPDATE
SET m.c_supplier_id = n.c_supplier_id, m.billdate = n.billdate,
m.po_priceactual = n.po_priceactual, m.po_qty = n.po_qty,
m.po_qtyin = n.po_qtyin, m.po_amtin = n.po_qtyin * n.po_priceactual,
m.b_po_id = n.id
WHERE m.ad_pi_id = p_pi_id
WHEN NOT MATCHED THEN
INSERT
(id, ad_client_id, ad_org_id, m_product_id, c_supplier_id, billdate,
pu_contractno, po_priceactual, po_qty, po_qtyin, po_amtin,
m_attributesetinstance_id, ownerid, creationdate, modifierid,
modifieddate, isactive, ad_pi_id, m_productalias_id, b_po_id)
VALUES
(get_sequences('rp_posum'), 37, 27, n.m_product_id, n.c_supplier_id,
n.billdate, n.contractno, n.po_priceactual, n.po_qty, n.po_qtyin,
n.po_qtyin * n.po_priceactual, n.asi, v_modifierid, SYSDATE,
v_modifierid, SYSDATE, 'Y', p_pi_id, n.m_productalias_id, n.id);
--入库日期更新
FOR v IN (SELECT a.b_po_id, MIN(a.datein) AS datein
FROM m_purchase a
WHERE EXISTS (SELECT 1
FROM rp_posum b
WHERE a.b_po_id = b.b_po_id
AND b.b_po_id IS NOT NULL
AND b.ad_pi_id = p_pi_id)
AND a.datein IS NOT NULL
GROUP BY a.b_po_id) LOOP
UPDATE rp_posum t
SET t.datein = v.datein
WHERE t.b_po_id = v.b_po_id
AND t.ad_pi_id = p_pi_id;
END LOOP;
--毛利计算
/*
毛利:
原逻辑:卖价-买价。
现逻辑:卖价-买价-运费
*/
UPDATE rp_posum t
SET t.profit = t.priceactual - t.po_priceactual - t.amt_tran,
t.diff_qty = t.po_qty - t.sa_qty, t.inventory = t.po_qtyin - t.sa_qtyout
WHERE t.ad_pi_id = p_pi_id;
--raise_application_error(-20201, v_datebegin3);
END;
--新骏:采购核价单-》平摊运费(动作定义)存储过程(author:me)
CREATE OR REPLACE PROCEDURE m_puramttran_avg(p_user_id IN NUMBER,
p_query IN VARCHAR2,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
---------------------------------------------------------
--author: xuyang
--date: 20180607
/*增加控制:如果单据已提交,不允许。
如果头表的运费不为空,则:
更新明细的运费=头表的运费*明细的审核金额/头表的总审核金额(最后多出来的放在最后一行)
*/
---------------------------------------------------------
--声明用于从p_query解析参数获得单据ID的相关记录和变量
TYPE t_queryobj IS RECORD(
"table" VARCHAR2(255),
query VARCHAR2(32676),
id VARCHAR2(10));
v_queryobj t_queryobj;
TYPE t_selection IS TABLE OF NUMBER(10) INDEX BY BINARY_INTEGER;
v_selection t_selection;
st_xml VARCHAR2(32676);
v_xml xmltype;
p_id NUMBER(10); --单据ID
--其他变量定义
v_status m_pur_price.status%TYPE; --单据状态
v_amt_tran m_pur_price.amt_tran%TYPE; --单据运费
v_docno m_pur_price.docno%TYPE; --单据编号
v_tot_amtin_pcheck m_pur_price.tot_amtin_pcheck%TYPE; --总审核金额
v_avg_amt_tran m_pur_price.amt_tran%TYPE; ----平摊运费
v_mod_amt_tran m_pur_price.amt_tran%TYPE; --剩余运费
v_m_purchase_id m_purchase.id%TYPE; --所属采购单ID
/*声明用于获取本单据明细中数量及存储各明细记录ID*/
TYPE type_list IS TABLE OF m_purchase.id%TYPE INDEX BY BINARY_INTEGER;
v_list type_list;
v_cnt NUMBER(10); --明细中行数
--用于获取明细数量的游标
CURSOR cur_list IS
SELECT id
FROM m_pur_priceitem
WHERE m_purchase_id = v_m_purchase_id;
BEGIN
-- 从p_query解析参数
st_xml := '<data>' || p_query || '</data>';
v_xml := xmltype(st_xml);
SELECT extractvalue(VALUE(t), '/data/table'),
extractvalue(VALUE(t), '/data/query'),
extractvalue(VALUE(t), '/data/id')
INTO v_queryobj
FROM TABLE(xmlsequence(extract(v_xml, '/data'))) t;
SELECT extractvalue(VALUE(t), '/selection')
BULK COLLECT
INTO v_selection
FROM TABLE(xmlsequence(extract(v_xml, '/data/selection'))) t;
p_id := v_queryobj.id;
--end 解析参数
--获取提交状态,运费,单据编号
SELECT mpp.status,nvl(mpp.amt_tran, 0), mpp.docno, mpp.tot_amtin_pcheck
INTO v_status, v_amt_tran, v_docno, v_tot_amtin_pcheck
FROM m_pur_price mpp
WHERE mpp.id = p_id;
--获取所属采购单ID
SELECT id
INTO v_m_purchase_id
FROM m_purchase
WHERE docno = v_docno;
--如果单据已提交,不允许
IF v_status = 2 THEN
raise_application_error(-20201, '单据已提交,不允许!');
END IF;
/*如果头表的运费不为空,则:更新明细的运费=头表的运费*明细的审核金额/头表的总审核金额(最后多出来的放在最后一行)*/
IF v_amt_tran <> 0 THEN
--获取需求运费和多余运费
OPEN cur_list;
FETCH cur_list BULK COLLECT
INTO v_list;
v_cnt := v_list.count;
IF v_list.count >= 2 THEN
v_mod_amt_tran := v_amt_tran; --起始剩余运费
--设置多行行明细运费
FOR idx IN 1 .. v_list.count - 1 LOOP
SELECT ((v_amt_tran * mppi.tot_amtin_pchecktax) /
v_tot_amtin_pcheck)
INTO v_avg_amt_tran
FROM m_pur_priceitem mppi
WHERE mppi.id = v_list(idx);
UPDATE m_purchaseitem mpi
SET mpi.amt_tran = v_avg_amt_tran
WHERE mpi.id = v_list(idx);
--剩余运费
v_mod_amt_tran := v_mod_amt_tran - v_avg_amt_tran;
END LOOP;
IF v_mod_amt_tran > 0 THEN
--设置最后一行明细运费
UPDATE m_purchaseitem mpi
SET mpi.amt_tran = v_mod_amt_tran
WHERE mpi.id = v_list(v_cnt);
END IF;
ELSIF v_list.count = 1 THEN
--设置单行明细运费
UPDATE m_purchaseitem mpi
SET mpi.amt_tran = v_amt_tran
WHERE mpi.m_purchase_id = v_m_purchase_id;
END IF;
CLOSE cur_list;
END IF;
r_code := 1;
r_message := '平摊运费成功!!';
END;
--新骏:销售核价单-》平摊运费(动作定义)存储过程(author:me)
CREATE OR REPLACE PROCEDURE m_saleamttran_avg(p_user_id IN NUMBER,
p_query IN VARCHAR2,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
---------------------------------------------------------
--author: xuyang
--date: 20180607
/*增加控制:如果单据已提交,不允许。
如果头表的运费不为空,则:
更新明细的运费=头表的运费*明细的审核金额/头表的总审核金额(最后多出来的放在最后一行)
*/
---------------------------------------------------------
--声明用于从p_query解析参数获得单据ID的相关记录和变量
TYPE t_queryobj IS RECORD(
"table" VARCHAR2(255),
query VARCHAR2(32676),
id VARCHAR2(10));
v_queryobj t_queryobj;
TYPE t_selection IS TABLE OF NUMBER(10) INDEX BY BINARY_INTEGER;
v_selection t_selection;
st_xml VARCHAR2(32676);
v_xml xmltype;
p_id NUMBER(10); --单据ID
--其他变量定义
v_status m_sale_pck.status%TYPE; --单据状态
v_amt_tran m_sale_pck.amt_tran%TYPE; --单据运费
v_docno m_sale_pck.docno%TYPE; --单据编号
v_tot_amtout_actual m_sale_pck.tot_amtout_actual%TYPE; --总审核金额
v_avg_amt_tran m_sale_pck.amt_tran%TYPE; ----平摊运费
v_mod_amt_tran m_sale_pck.amt_tran%TYPE; --剩余运费
v_m_sale_id m_sale.id%TYPE; --所属销售单ID
/*声明用于获取本单据明细中数量及存储各明细记录ID*/
TYPE type_list IS TABLE OF m_sale.id%TYPE INDEX BY BINARY_INTEGER;
v_list type_list;
v_cnt NUMBER(10); --销售明细中行数
--用于获取销售明细数量的游标
CURSOR cur_list IS
SELECT id
FROM m_sale_pckitem
WHERE m_sale_id = v_m_sale_id;
BEGIN
-- 从p_query解析参数
st_xml := '<data>' || p_query || '</data>';
v_xml := xmltype(st_xml);
SELECT extractvalue(VALUE(t), '/data/table'),
extractvalue(VALUE(t), '/data/query'),
extractvalue(VALUE(t), '/data/id')
INTO v_queryobj
FROM TABLE(xmlsequence(extract(v_xml, '/data'))) t;
SELECT extractvalue(VALUE(t), '/selection')
BULK COLLECT
INTO v_selection
FROM TABLE(xmlsequence(extract(v_xml, '/data/selection'))) t;
p_id := v_queryobj.id;
--end 解析参数
--获取提交状态,运费,单据编号
SELECT msp.status,nvl(msp.amt_tran, 0), msp.docno, msp.tot_amtout_actual
INTO v_status, v_amt_tran, v_docno, v_tot_amtout_actual
FROM m_sale_pck msp
WHERE msp.id = p_id;
--如果单据已提交,不允许
IF v_status = 2 THEN
raise_application_error(-20201, '单据已提交,不允许!');
END IF;
--获取所属销售单ID
SELECT id
INTO v_m_sale_id
FROM m_sale
WHERE docno = v_docno;
/*如果头表的运费不为空,则:更新明细的运费=头表的运费*明细的审核金额/头表的总审核金额(最后多出来的放在最后一行)*/
IF v_amt_tran <> 0 THEN
--获取需求运费和多余运费
OPEN cur_list;
FETCH cur_list BULK COLLECT
INTO v_list;
v_cnt := v_list.count;
IF v_list.count >= 2 THEN
v_mod_amt_tran := v_amt_tran; --起始剩余运费
--设置多行行明细运费
FOR idx IN 1 .. v_list.count - 1 LOOP
SELECT ((v_amt_tran * mspi.tot_amtout_actual) /
v_tot_amtout_actual)
INTO v_avg_amt_tran
FROM m_sale_pckitem mspi
WHERE mspi.id = v_list(idx);
UPDATE m_saleitem msi
SET msi.amt_tran = v_avg_amt_tran
WHERE msi.id = v_list(idx);
--剩余运费
v_mod_amt_tran := v_mod_amt_tran - v_avg_amt_tran;
END LOOP;
IF v_mod_amt_tran > 0 THEN
--设置最后一行明细运费
UPDATE m_saleitem msi
SET msi.amt_tran = v_mod_amt_tran
WHERE msi.id = v_list(v_cnt);
END IF;
ELSIF v_list.count = 1 THEN
--设置单行明细运费
UPDATE m_saleitem msi
SET msi.amt_tran = v_amt_tran
WHERE msi.m_sale_id = v_m_sale_id;
END IF;
CLOSE cur_list;
END IF;
r_code := 1;
r_message := '平摊运费成功!!';
END;
--凰艮:商品销售排行榜报表procedure:
CREATE OR REPLACE PROCEDURE rp_retail_order_generate(p_pi_id NUMBER) IS
/*Version date name reason
0.0 20091222 eiffie created*/
--1.Author:zxx
--Date:20161117
--Modification:取值查询条件的库存店仓,已做单未出库的数量之和(别人发货但还没有出库的数量统计。例如发货店仓是A,做10件销售单已提交未出库,收货店仓B的在单数量为10。单据包含销售单,销售退货单,调拨单)
---------------------------------------------------
--2: author:xuyang
--date:20180608
--modification:
/*
在途库存:取值该店仓、该条码在[库存查询 V_FA_STORAGE]中的在途数量。
预计库存:在途库存+库存数量。
*/
---------------------------------------------------
v_userid NUMBER(10);
v_date VARCHAR2(80);
v_datebegin NUMBER(8);
v_dateend NUMBER(8);
v_sql1 VARCHAR2(4000);
v_sql2 VARCHAR2(4000);
v_cnt NUMBER(10);
r_store r_tabid := r_tabid(); --记录店仓id集合
r_product r_tabid := r_tabid(); --记录款号单id集合
r_qtystore r_tabid := r_tabid(); --记录库存店仓id集合
BEGIN
EXECUTE IMMEDIATE ('truncate TABLE rp_retail_order');
-- raise_application_error(-20201, p_pi_id);
--定义公共sql
v_sql1 := 'SELECT t.info
FROM ad_pinstance_para t
WHERE t.name = :name AND t.ad_pinstance_id = :p_pi_id';
SELECT t.modifierid
INTO v_userid
FROM ad_pinstance t
WHERE t.id = p_pi_id;
--依次获取界面查询条件参数
EXECUTE IMMEDIATE v_sql1
INTO v_date
USING '日期', p_pi_id;
IF v_date IS NULL THEN
--如开始日期和结束日期都没有选择,则查询所有日期范围内数据
v_datebegin := 0;
v_dateend := 20991231;
ELSE
IF instr(v_date, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为20991231
v_dateend := 20991231;
SELECT substr(v_date, 7, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin
FROM dual;
ELSIF instr(v_date, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为0
v_datebegin := 0;
SELECT substr(v_date, 7, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend
FROM dual;
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取
SELECT substr(v_date, 15, 8), substr(v_date, 28, 8) --注意这里是不是分别从17,30开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin, v_dateend
FROM dual;
END IF;
END IF;
EXECUTE IMMEDIATE v_sql1
INTO v_sql2
USING '店仓', p_pi_id;
r_store := f_fast_table(v_sql2);
EXECUTE IMMEDIATE v_sql1
INTO v_sql2
USING '商品', p_pi_id;
r_product := f_fast_table(v_sql2);
EXECUTE IMMEDIATE v_sql1
INTO v_sql2
USING '库存店仓', p_pi_id;
r_qtystore := f_fast_table(v_sql2);
INSERT INTO rp_retail_order
(id, ad_client_id, ad_org_id, m_product_id, qty, tot_amt_actual,
ownerid, modifierid, creationdate, modifieddate, isactive, ad_pi_id)
SELECT get_sequences('RP_RETAIL_ORDER'), a.ad_client_id, a.ad_org_id,
b.m_product_id, SUM(b.qty) qty, SUM(b.tot_amt_actual) amt_actual,
v_userid, v_userid, SYSDATE, SYSDATE, 'Y', p_pi_id
FROM m_retail a, m_retailitem b, TABLE(r_store) rs, TABLE(r_product) rp
WHERE a.id = b.m_retail_id
AND a.c_store_id = rs.id
AND b.m_product_id = rp.id
AND a.status = 2
AND a.billdate BETWEEN v_datebegin AND v_dateend
GROUP BY a.ad_client_id, a.ad_org_id, b.m_product_id;
--begin modification by xuyang 20180608
/*更新以下两字段:
在途库存prein_qty:取值该店仓、该条码在[库存查询 V_FA_STORAGE]中的在途数量。
预计库存pre_qty:在途库存+库存数量。*/
MERGE INTO rp_retail_order g
USING (SELECT c.ad_client_id, c.ad_org_id, c.m_product_id,
SUM(c.qty) qty_storage, SUM(c.qtyprein) qtyprein
FROM fa_storage c, TABLE(r_product) rp, TABLE(r_qtystore) rq
WHERE c.c_store_id = rq.id
AND c.m_product_id = rp.id
GROUP BY c.ad_client_id, c.ad_org_id, c.m_product_id) w
ON (g.m_product_id = w.m_product_id AND g.ad_client_id = w.ad_client_id AND g.ad_org_id = w.ad_org_id AND g.ad_pi_id = p_pi_id)
WHEN MATCHED THEN
UPDATE
SET g.qty_storage = nvl(g.qty_storage, 0) + w.qty_storage,
g.prein_qty = w.qtyprein,
--added by xuyang
g.pre_qty = nvl(g.qty_storage, 0) + w.qty_storage + w.qtyprein --added by xuyang
WHEN NOT MATCHED THEN
INSERT
(id, ad_client_id, ad_org_id, ownerid, modifierid, creationdate,
modifieddate, isactive, ad_pi_id, m_product_id, qty_storage,
prein_qty, pre_qty)
VALUES
(get_sequences('RP_RETAIL_ORDER'), w.ad_client_id, w.ad_org_id,
v_userid, v_userid, SYSDATE, SYSDATE, 'Y', p_pi_id, w.m_product_id,
w.qty_storage, w.qtyprein, (w.qtyprein + w.qty_storage)); --added by xuyang
--end modification by xuyang 20180608
--add by zxx 20161117 在单数量2
MERGE INTO rp_retail_order a
USING (SELECT nvl(SUM(g.qtypreout), 0) AS qtypreout, /* g.c_store_id,*/
g.m_product_id
FROM (SELECT nvl(SUM(mi.qty), 0) AS qtypreout,
/* m.c_dest_id AS c_store_id, */ mi.m_product_id
FROM m_sale m, TABLE(r_qtystore) rs, TABLE(r_product) rp,
m_saleitem mi
WHERE m.c_dest_id = rs.id
AND mi.m_sale_id = m.id
AND mi.m_product_id = rp.id
AND m.status = 2
AND m.out_status = 1
GROUP BY /*m.c_dest_id,*/ mi.m_product_id
UNION ALL
SELECT nvl(SUM(mri.qty), 0) AS qtypreout,
/* mr.c_store_id AS c_store_id,*/ mri.m_product_id
FROM m_ret_sale mr, TABLE(r_qtystore) rs, TABLE(r_product) rp,
m_ret_saleitem mri
WHERE mr.c_store_id = rs.id
AND mri.m_ret_sale_id = mr.id
AND mri.m_product_id = rp.id
AND mr.status = 2
AND mr.out_status = 1
GROUP BY /* mr.c_store_id,*/ mri.m_product_id
UNION ALL
SELECT nvl(SUM(mti.qty), 0) AS qtypreout,
/* mt.c_dest_id AS c_store_id,*/ mti.m_product_id
FROM m_transfer mt, TABLE(r_qtystore) rs, TABLE(r_product) rp,
m_transferitem mti
WHERE mt.c_dest_id = rs.id
AND mti.m_product_id = rp.id
AND mti.m_transfer_id = mt.id
AND mt.status = 2
AND mt.out_status = 1
GROUP BY /*mt.c_dest_id,*/ mti.m_product_id) g
GROUP BY /* g.c_store_id,*/ g.m_product_id) tt
ON ( /*a.c_store_id = tt.c_store_id AND */
a.m_product_id = tt.m_product_id)
WHEN MATCHED THEN
UPDATE
SET a.qtypreout2 = tt.qtypreout;
--end by zxx 20161117
UPDATE rp_retail_order g
SET pricelist = (SELECT pricelist
FROM m_product a
WHERE a.id = g.m_product_id)
WHERE g.ad_pi_id = p_pi_id;
UPDATE rp_retail_order g
SET rateamt = (SELECT decode(SUM(a.tot_amt_actual), 0, 0,
g.tot_amt_actual / SUM(a.tot_amt_actual))
FROM rp_retail_order a
WHERE a.ad_pi_id = p_pi_id);
SELECT length(COUNT(1))
INTO v_cnt
FROM rp_retail_order t
WHERE t.ad_pi_id = p_pi_id;
UPDATE rp_retail_order g
SET n = (SELECT substr('00000000000' || n, -v_cnt, v_cnt)
FROM (SELECT id,
rank() over(PARTITION BY ad_client_id, ad_org_id ORDER BY nvl(qty, 0) DESC) n
FROM rp_retail_order a
WHERE a.ad_pi_id = p_pi_id) w
WHERE w.id = g.id)
WHERE EXISTS (SELECT 1
FROM rp_retail_order a
WHERE g.id = a.id)
AND g.ad_pi_id = p_pi_id;
END; /* edit by shizhishu 2016/11/18 16:39:15 */
--MY FIRST REPORT TABLE MODEL
CREATE OR REPLACE PROCEDURE rp_o2o_salesources_gen(p_pi_id NUMBER) IS
---------------------------------------------------
--Author:xuyang
-- Date:20180615
-- Author :xuyang
-- Description :
/*
查询条件:单据日期(日期范围、必填) 、订单来源(下拉框选项:EBSOURCE,非必填)
查询逻辑:
取查询单据日期在查询条件的开始日期和结束日期内、
订单来源为查询条件的订单来源、 已提交、未结案、可用的 【云仓订单】的数据。
(--PS: 控制查询条件的结束日期-开始日期=6,如果不等于6,则报错‘该报表为周报表,请以7天为一个周期’)
查询结果:
行定义:
序号:显示1,2,3,4……。
渠道:取值符合条件的云仓订单主表的【接口订单类型】。
订单来源:取值符合条件的云仓订单主表的【订单来源】。
汇总字段:
销量:取值符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单数量】的汇总。
销售额(万元):取值符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单成交金额】/10000,四舍五入取整。
销量占比(%):取值(本条记录的销量/所有订单来源销量之和 )*100,百分比格式,百分比之后显示两位小数。
销售额占比(%):取值(本条记录的销售额(万元) / 所有订单来源销售额之和)*100,百分比格式,百分比之后显示两位小数。
销量周环比(%):取值[(本条记录的销量-上周销量)/上周销量]*100,本周为查询日期选择的起始日期和结束日期,上周为本周的上一个7天作为一周;百分比格式,百分比之后显示两位小数。
销售额周环比(%):取值[(本条记录的销售额(万元)-上周销售额(万元))/上周销售额(万元)]*100,本周为查询日期选择的起始日期和结束日期,上周为本周的上一个7天作为一周;百分比格式,百分比之后显示两位小数。
件单价(元) :销售额(万元)*10000/ 销量,四舍五入取整。
成交折扣:取值本记录的销售额(万元)*10000/ 符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单标准金额】,小数点后面两位。
--PS:销量占比(%)、销售额占比(%)、销量周环比(%)、销售额周环比(%)、件单价、成交折扣合计时,取平均数。
*/
---------------------------------------------------
v_userid NUMBER(10);
v_date VARCHAR2(80);
v_datebegin VARCHAR2(8);
v_dateend VARCHAR2(8);
v_sql1 VARCHAR2(4000);
--v_sql2 VARCHAR2(4000);
v_source rp_o2o_salesources.source%TYPE; --订单来源
v_tmp_source rp_o2o_salesources.source%TYPE;
v_loc1 NUMBER(10); --订单来源字符解析位置1
v_loc2 NUMBER(10); --订单来源字符解析位置2
v_days NUMBER(10);
v_all_tot_num rp_o2o_salesources.num%TYPE; --所有订单来源销量之和
v_all_tot_amt rp_o2o_salesources.tot_amt_actual%TYPE; --所有订单来源销售额之和
--v_sales_last rp_o2o_salesources.num%TYPE; --上周销量
--v_sales_amt_last rp_o2o_salesources.tot_amt_actual%TYPE; --上周销售额
BEGIN
EXECUTE IMMEDIATE ('truncate TABLE RP_O2O_SALESOURCES');
-- raise_application_error(-20201, p_pi_id);
--定义公共sql
v_sql1 := 'SELECT t.info
FROM ad_pinstance_para t
WHERE t.name = :name AND t.ad_pinstance_id = :p_pi_id';
SELECT t.modifierid
INTO v_userid
FROM ad_pinstance t
WHERE t.id = p_pi_id;
--依次获取界面查询条件参数
EXECUTE IMMEDIATE v_sql1
INTO v_date
USING 'BILLDATE', p_pi_id;
--raise_application_error(-20201, 'debug:' || v_date);
-- debug: (BILLDATE>=20180605)
IF v_date IS NULL THEN
--如开始日期和结束日期都没有选择,
raise_application_error(-20201, '请选择日期范围!');
ELSE
IF instr(v_date, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为开始日后六天
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin
FROM dual;
--raise_application_error(-20201, 'debug: ' || v_datebegin);
--结束日期默认为开始日后六天
v_dateend := to_char(to_date(v_datebegin, 'yyyymmdd') + 6,
'yyyymmdd');
ELSIF instr(v_date, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为前六天BILLDATE<=20180615
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend
FROM dual;
--开始日期默认为前六天
v_datebegin := to_char(to_date(v_dateend, 'yyyymmdd') - 6,
'yyyymmdd');
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取debug: ( BILLDATE BETWEEN 20180605 AND 20180615)
--raise_application_error(-20201, 'debug:' || v_date);
SELECT substr(v_date, 21, 8), substr(v_date, 34, 8) --注意这里是不是分别从20,33开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin, v_dateend
FROM dual;
/*raise_application_error(-20201,
'debug:' || v_datebegin || '--' ||
v_dateend);*/
SELECT to_date(v_dateend, 'yyyymmdd') -
to_date(v_datebegin, 'yyyymmdd')
INTO v_days
FROM dual;
--raise_application_error(-20201, 'debug:' || v_days);
IF v_days <> 6 THEN
raise_application_error(-20201, '该报表为周报表,请以7天为一个周期!');
END IF;
END IF;
END IF;
--获取订单来源
EXECUTE IMMEDIATE v_sql1
INTO v_tmp_source
USING 'SOURCE', p_pi_id;
--raise_application_error(-20201, 'debug:' || v_days);
--debug: (SOURCE LIKE '%0%')
--debug: (SOURCE = 'taobao')
--debug: (SOURCE = 'HAND')
--debug: (SOURCE = 'WEB')
--未选择订单来源,则给予提示
IF v_tmp_source IS NULL THEN
raise_application_error(-20201, '请选择订单来源!');
END IF;
--订单来源为查询条件的订单来源、 已提交、未结案、可用的 【云仓订单】的数据。
/*
销量:取值符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单数量】的汇总。
销售额(万元):取值符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单成交金额】/10000,四舍五入取整。
销量占比(%):取值(本条记录的销量/所有订单来源销量之和 )*100,百分比格式,百分比之后显示两位小数。
销售额占比(%):取值(本条记录的销售额(万元) / 所有订单来源销售额之和)*100,百分比格式,百分比之后显示两位小数。
件单价(元) :销售额(万元)*10000/ 销量,四舍五入取整。
成交折扣:取值本记录的销售额(万元)*10000/ 符合查询条件的、该渠道、该订单来源对应的云仓订单主表【订单标准金额】,小数点后面两位。
--PS:销量占比(%)、销售额占比(%)、销量周环比(%)、销售额周环比(%)、件单价、成交折扣合计时,取平均数。
*/
--获取所有订单销量和销售额之和
SELECT nvl(SUM(os.tot_amt_actual), 0), nvl(SUM(os.num), 0)
INTO v_all_tot_amt, v_all_tot_num
FROM o2o_so os;
IF instr(v_tmp_source, '=') > 0 THEN
--获取字符‘位置
v_loc1 := instr(v_tmp_source, '''');
v_loc2 := instr(v_tmp_source, '''', v_loc1 + 1);
--raise_application_error(-20201, 'debug:' || v_loc1 || '---' || v_loc2);
--获取到订单来源
v_source := substr(v_tmp_source, v_loc1 + 1, v_loc2 - v_loc1 - 1);
--临时表插入数据
INSERT INTO rp_o2o_salesources
(id, ad_client_id, ad_org_id, interface_type, SOURCE, num,
tot_amt_actual, price, deal_discount, ownerid, modifierid,
creationdate, modifieddate, isactive, ad_pi_id, no, sales_rate,
sales_amt_rate)
SELECT get_sequences('rp_o2o_salesources'), a.ad_client_id,
a.ad_org_id, a.interface_type, a.source, SUM(a.num),
round(SUM(a.tot_amt_actual) / 10000),
round(((round(SUM(a.tot_amt_actual) / 10000)) * 10000) /
SUM(a.num)),
trunc((((round(SUM(a.tot_amt_actual) / 10000)) * 10000) /
SUM(a.tot_amt_list)), 2), v_userid, v_userid, SYSDATE,
SYSDATE, 'Y', p_pi_id,
dense_rank() over(PARTITION BY NULL ORDER BY SUM(a.tot_amt_actual)),
trunc((SUM(a.num) / v_all_tot_num) * 100, 2),
trunc((SUM(tot_amt_actual) / v_all_tot_amt) * 100, 2)
FROM o2o_so a
WHERE a.status = 2
AND a.isactive = 'Y'
AND a.close_status = 1
AND a.source = v_source
AND to_date(a.billdate, 'yyyymmdd') BETWEEN
to_date(v_datebegin, 'yyyymmdd') AND
to_date(v_dateend, 'yyyymmdd')
GROUP BY a.ad_client_id, a.ad_org_id, a.interface_type, a.source
ORDER BY SUM(a.num);
ELSIF instr(v_tmp_source, 'LIKE') > 0 THEN
INSERT INTO rp_o2o_salesources
(id, ad_client_id, ad_org_id, interface_type, SOURCE, num,
tot_amt_actual, price, deal_discount, ownerid, modifierid,
creationdate, modifieddate, isactive, ad_pi_id, no, sales_rate,
sales_amt_rate)
SELECT get_sequences('rp_o2o_salesources'), a.ad_client_id,
a.ad_org_id, a.interface_type, a.source, SUM(a.num),
round(SUM(a.tot_amt_actual) / 10000),
round(((round(SUM(a.tot_amt_actual) / 10000)) * 10000) /
SUM(a.num)),
trunc((((round(SUM(a.tot_amt_actual) / 10000)) * 10000) /
SUM(a.tot_amt_list)), 2), v_userid, v_userid, SYSDATE,
SYSDATE, 'Y', p_pi_id,
dense_rank() over(PARTITION BY NULL ORDER BY SUM(a.tot_amt_actual)),
trunc((SUM(a.num) / v_all_tot_num) * 100, 2),
trunc((SUM(tot_amt_actual) / v_all_tot_amt) * 100, 2)
FROM o2o_so a
WHERE a.status = 2
AND a.isactive = 'Y'
AND a.close_status = 1
AND to_date(a.billdate, 'yyyymmdd') BETWEEN
to_date(v_datebegin, 'yyyymmdd') AND
to_date(v_dateend, 'yyyymmdd')
GROUP BY a.ad_client_id, a.ad_org_id, a.interface_type, a.source
ORDER BY SUM(a.num);
END IF;
/*
销量周环比(%):取值[(本条记录的销量-上周销量)/上周销量]*100,本周为查询日期选择的起始日期和结束日期,上周为本周的上一个7天作为一周;百分比格式,百分比之后显示两位小数。
销售额周环比(%):取值[(本条记录的销售额(万元)-上周销售额(万元))/上周销售额(万元)]*100,本周为查询日期选择的起始日期和结束日期,上周为本周的上一个7天作为一周;百分比格式,百分比之后显示两位小数。
*/
MERGE INTO rp_o2o_salesources rps
USING (SELECT os.interface_type interface_type, os.source SOURCE,
SUM(os.num) tot_num_last, SUM(os.tot_amt_actual) tot_amt_last
FROM o2o_so os
WHERE to_date(os.billdate, 'yyyymmdd') BETWEEN
to_date(v_datebegin, 'yyyymmdd') - 6 AND
to_date(v_dateend, 'yyyymmdd') - 6
GROUP BY os.interface_type, os.source) rs
ON (rps.interface_type = rs.interface_type AND rps.source = rs.source)
WHEN MATCHED THEN
UPDATE
SET rps.sales_week_rate = trunc(((rps.num - rs.tot_num_last) /
rs.tot_num_last) * 100, 2),
rps.sales_amtweek_rate = trunc(((rps.tot_amt_actual -
rs.tot_amt_last) / rs.tot_amt_last) * 100,
2);
END;
---V1.0-20180608-06全渠道各渠道TOP10销售分析报表存储过程
CREATE OR REPLACE PROCEDURE rp_o2o_salesources10_gen(p_pi_id NUMBER) IS
---------------------------------------------------
--Author:xuyang
-- Date:20180616
-- Author :xuyang
-- Description :
/*
查询条件:单据日期(日期范围、必填) 、订单来源(下拉框选项:EBSOURCE,非必填)
查询逻辑:
查询逻辑:取查询单据日期在查询条件的开始日期和结束日期内、订单来源为查询条件的订单来源、 已提交、未结案、可用的 【云仓订单】的数据
(--PS: 控制查询条件的结束日期-开始日期=6,如果不等于6,则报错‘该报表为周报表,请以7天为一个周期’)
查询结果:
行定义:
序号:显示1,2,3,4……按照本订单来源的销量降序,取前十名。--即:每个订单来源只统计【销量】排行前十的款号
订单来源:取值符合条件的云仓订单主表的【订单来源】。
款号:取值符合条件的云仓订单明细的【款号】。
汇总字段:
销量:取值符合查询条件的、该订单来源、该款号对应的云仓订单明细的【订单数量】的汇总。
销售额(元):取值符合查询条件的、该订单来源、该款号对应的云仓订单明细的【订单成交金额】的汇总,四舍五入取整。
销量占比(%):取值(本条记录的销量/所有订单来源销量之和 )*100,百分比格式,百分比之后显示两位小数。
销售额占比(%):取值(本条记录的销售额(元) / 所有订单来源销售额之和)*100,百分比格式,百分比之后显示两位小数。
*/
---------------------------------------------------
v_userid NUMBER(10);
v_date VARCHAR2(80);
v_datebegin VARCHAR2(8);
v_dateend VARCHAR2(8);
v_sql1 VARCHAR2(4000);
v_source rp_o2o_salesources10.source%TYPE; --订单来源
v_tmp_source rp_o2o_salesources10.source%TYPE;
v_loc1 NUMBER(10); --订单来源字符解析位置1
v_loc2 NUMBER(10); --订单来源字符解析位置2
v_all_tot_num rp_o2o_salesources10.num%TYPE; --所有订单来源销量之和
v_all_tot_amt rp_o2o_salesources10.tot_amt_actual%TYPE; --所有订单来源销售额之和
BEGIN
EXECUTE IMMEDIATE ('truncate TABLE RP_O2O_SALESOURCES');
-- raise_application_error(-20201, p_pi_id);
--定义公共sql
v_sql1 := 'SELECT t.info
FROM ad_pinstance_para t
WHERE t.name = :name AND t.ad_pinstance_id = :p_pi_id';
SELECT t.modifierid
INTO v_userid
FROM ad_pinstance t
WHERE t.id = p_pi_id;
--依次获取界面查询条件参数
EXECUTE IMMEDIATE v_sql1
INTO v_date
USING 'BILLDATE', p_pi_id;
--raise_application_error(-20201, 'debug:' || v_date);
-- debug: (BILLDATE>=20180605)
IF v_date IS NULL THEN
--如开始日期和结束日期都没有选择,
raise_application_error(-20201, '请选择日期范围!');
ELSE
IF instr(v_date, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为开始日后六天
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_datebegin
FROM dual;
--raise_application_error(-20201, 'debug: ' || v_datebegin);
--结束日期默认为开始日后六天
v_dateend := to_char(to_date(v_datebegin, 'yyyymmdd') + 6,
'yyyymmdd');
ELSIF instr(v_date, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认为前六天BILLDATE<=20180615
SELECT substr(v_date, 13, 8) --注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
INTO v_dateend
FROM dual;
--开始日期默认为前六天
v_datebegin := to_char(to_date(v_dateend, 'yyyymmdd') - 6,
'yyyymmdd');
ELSE
--如开始日期和结束日期都进行了选择,则均从参数值获取debug: ( BILLDATE BETWEEN 20180605 AND 20180615)
--raise_application_error(-20201, 'debug:' || v_date);
SELECT substr(v_date, 21, 8), substr(v_date, 34, 8) --注意这里是不是分别从20,33开始,也是取决于日期参数定义,,例如日期参数名定义为DATE,则此处为17、30,如定义为BILLDATE,此处为21、34,以此类推
INTO v_datebegin, v_dateend
FROM dual;
END IF;
END IF;
--获取订单来源
EXECUTE IMMEDIATE v_sql1
INTO v_tmp_source
USING 'SOURCE', p_pi_id;
--raise_application_error(-20201, 'debug:' || v_days);
--未选择订单来源,则给予提示
IF v_tmp_source IS NULL THEN
raise_application_error(-20201, '请选择订单来源!');
END IF;
--订单来源为查询条件的订单来源、 已提交、未结案、可用的 【云仓订单】的数据。
/*
销量:取值符合查询条件的、该订单来源、该款号对应的云仓订单明细的【订单数量】的汇总。
销售额(元):取值符合查询条件的、该订单来源、该款号对应的云仓订单明细的【订单成交金额】的汇总,四舍五入取整。
销量占比(%):取值(本条记录的销量/所有订单来源销量之和 )*100,百分比格式,百分比之后显示两位小数。
销售额占比(%):取值(本条记录的销售额(元) / 所有订单来源销售额之和)*100,百分比格式,百分比之后显示两位小数。
*/
--获取所有订单销量和销售额之和
SELECT nvl(SUM(os.tot_amt_actual), 0), nvl(SUM(os.num), 0)
INTO v_all_tot_amt, v_all_tot_num
FROM o2o_so os;
IF instr(v_tmp_source, '=') > 0 THEN
--获取字符‘位置
v_loc1 := instr(v_tmp_source, '''');
v_loc2 := instr(v_tmp_source, '''', v_loc1 + 1);
--获取到订单来源
v_source := substr(v_tmp_source, v_loc1 + 1, v_loc2 - v_loc1 - 1);
--临时表插入数据,插入指定订单来源的数据
INSERT INTO rp_o2o_salesources10
(id, ad_client_id, ad_org_id, SOURCE, num, tot_amt_actual, ownerid,
modifierid, creationdate, modifieddate, isactive, ad_pi_id,
sales_rate, sales_amt_rate, m_product_id, no)
SELECT ab.id, ab.ad_clien_id, ab.ad_org_id, ab.source, ab.tot_qty,
ab.tot_amt, v_userid, v_userid, SYSDATE, SYSDATE, 'Y',
p_pi_id, ab.sales_rate, ab.sales_amt_rate, ab.m_product_id,
dense_rank() over(PARTITION BY NULL ORDER BY ab.tot_qty DESC)
FROM (SELECT get_sequences('rp_o2o_salesources') id,
a.ad_client_id ad_clien_id, a.ad_org_id ad_org_id,
a.source SOURCE, SUM(osi.qty) tot_qty,
round(SUM(osi.tot_amt_actual)) tot_amt,
dense_rank() over(PARTITION BY a.source ORDER BY SUM(osi.qty) DESC) ct,
trunc((SUM(osi.qty) / v_all_tot_num) * 100, 2) sales_rate,
trunc((SUM(osi.tot_amt_actual) / v_all_tot_amt) * 100, 2) sales_amt_rate,
osi.m_product_id m_product_id
FROM o2o_so a
JOIN o2o_soitem osi
ON (osi.eb_orderso_id = a.id)
WHERE a.status = 2
AND a.isactive = 'Y'
AND a.close_status = 1
AND a.source = v_source
AND to_date(a.billdate, 'yyyymmdd') BETWEEN
to_date(v_datebegin, 'yyyymmdd') AND
to_date(v_dateend, 'yyyymmdd')
GROUP BY a.ad_client_id, a.ad_org_id, a.source,
osi.m_product_id
ORDER BY SUM(osi.qty) DESC) ab
WHERE ab.ct <= 10;
ELSIF instr(v_tmp_source, 'LIKE') > 0 THEN
--插入所有符合条件的订单来源数据
INSERT INTO rp_o2o_salesources10
(id, ad_client_id, ad_org_id, SOURCE, num, tot_amt_actual, ownerid,
modifierid, creationdate, modifieddate, isactive, ad_pi_id,
sales_rate, sales_amt_rate, m_product_id, no)
SELECT ab.id, ab.ad_clien_id, ab.ad_org_id, ab.source, ab.tot_qty,
ab.tot_amt, v_userid, v_userid, SYSDATE, SYSDATE, 'Y',
p_pi_id, ab.sales_rate, ab.sales_amt_rate, ab.m_product_id,
dense_rank() over(ORDER BY ab.tot_qty DESC)
FROM (SELECT get_sequences('rp_o2o_salesources') id,
a.ad_client_id ad_clien_id, a.ad_org_id ad_org_id,
a.source SOURCE, SUM(osi.qty) tot_qty,
round(SUM(osi.tot_amt_actual)) tot_amt,
dense_rank() over(PARTITION BY a.source ORDER BY SUM(osi.qty) DESC) ct,
trunc((SUM(osi.qty) / v_all_tot_num) * 100, 2) sales_rate,
trunc((SUM(osi.tot_amt_actual) / v_all_tot_amt) * 100, 2) sales_amt_rate,
osi.m_product_id m_product_id
FROM o2o_so a
JOIN o2o_soitem osi
ON (osi.eb_orderso_id = a.id)
WHERE a.status = 2
AND a.isactive = 'Y'
AND a.close_status = 1
AND to_date(a.billdate, 'yyyymmdd') BETWEEN
to_date(v_datebegin, 'yyyymmdd') AND
to_date(v_dateend, 'yyyymmdd')
GROUP BY a.ad_client_id, a.ad_org_id, a.source,
osi.m_product_id
ORDER BY SUM(osi.qty) DESC) ab
WHERE ab.ct <= 10;
END IF;
END;
--------------------------------------------
--解析Json数据
CREATE OR REPLACE PROCEDURE test_proc(p1 VARCHAR2) AS v_json_varchar2 VARCHAR2(4000);
injson json;
paramlist json_list;
onejson json;
--第一层
v_marketcode VARCHAR2(8);
v_marketname VARCHAR2(64);
v_address VARCHAR2(64);
v_tel VARCHAR2(11);
--第二层
v_name VARCHAR2(64);
v_fruitcode VARCHAR2(8);
BEGIN
--定义json数据,当然json数据也可从参数中传来
v_json_varchar2 := '{
"marketcode": "123456",
"marketname": "好吃的水果店",
"address": "一个好地方",
"tel": "12345678901",
"fruitlist": {
"name": "apple",
"fruitcode": "223344",
"applelist": [
{
"applename": "redapple ",
"applecode": "111000",
"price": "10"
},
{
"applename": "greenapple ",
"applecode": "111111",
"price": "12"
},
{
"applename": "yellowapple ",
"applecode": "111222",
"price": "8"
}
]
}
}';
injson := json(v_json_varchar2);
--获取第一层json值
v_marketcode := json_ext.get_string(injson, 'marketcode');
v_marketname := json_ext.get_string(injson, 'marketname');
v_address := json_ext.get_string(injson, 'address');
v_tel := json_ext.get_string(injson, 'tel');
--第二层
v_name := json_ext.get_string(injson, 'fruitlist.name');
v_fruitcode := json_ext.get_string(injson, 'fruitlist.fruitcode');
--接下来获取第三层,使用json_list来存放json列表
paramlist := json_list();
onejson := json();
paramlist := json_ext.get_json_list(injson, 'fruitlist.applelist');
--使用循环返回每个json部分的值
FOR i IN 1 .. paramlist.count LOOP
--读取每个品种具体信息
onejson := json(paramlist.get_elem(i));
dbms_output.put_line(json_ext.get_string(onejson, 'applename'));
dbms_output.put_line(json_ext.get_string(onejson, 'applecode'));
dbms_output.put_line(json_ext.get_string(onejson, 'price'));
END LOOP;
END;
-----------------------------------------------------------------------------------
注:将clob类型字段读取出来到变量,需dbms_lob.substr(xms.param)转化为varchar2类型
CREATE OR REPLACE PROCEDURE xq_midso_gen AS
----------------------------------------------------------
--author:xuyang
--date:20180627
--description:
/*
FOR (查询实际表[订单接口 XQ_MIDSO]中的[是否生成订单]为Y的记录) LOOP
根据接口信息的json信息生成未提交的发货订单。
生成发货订单头表:
单据日期取SYSDATE。
订单类型取新货订单。
发货店仓取总部店仓。
收货店仓取接口中的customer_name对应的经销商下的任一店仓(根据名称匹配)。
鲜桥订单编码取接口中的ordercode。
备注:由鲜桥接口自动生成!
调用存储过程:B_SO_AC。
生成发货订单明细:
条码、款号、ASI取接口中的product_name对应条码的值。
数量取接口中的amount。
调用存储过程:B_SOITEM_ACM。
调用存储过程:B_SO_AM。
END LOOP;
*/
/*
*/
----------------------------------------------------------
v_injson json; --用于将接口信息转换为json格式
--v_ordercode b_so.xq_ordercode%TYPE; --发货订单鲜桥订单编码
--v_customer_name c_customer.name%TYPE; --订单头信息中的经销商名称
v_delivery_time VARCHAR2(20); --配送时间(发货日期)
--v_delivery_address b_so.dest_address%TYPE; --收货地址
v_clob_varchar2 VARCHAR2(4000);
BEGIN
--查询实际表[订单接口 XQ_MIDSO]中的[是否生成订单]为Y的记录
FOR v_list IN (SELECT xms.id, xms.ad_client_id, xms.ad_org_id,
xms.creationdate, xms.ownerid, xms.errormeg
FROM xq_midso xms
WHERE xms.is_so = 'Y') LOOP
SELECT dbms_lob.substr(xms.param)
INTO v_clob_varchar2
FROM xq_midso xms
WHERE xms.id = v_list.id;
v_injson := json(v_clob_varchar2);
--获取headerlist:orderHeader
--v_id := json_ext.get_string(v_injson, 'CallInfo.orderHeader.id');
--v_ordercode := json_ext.get_string(v_injson,
--'CallInfo.orderHeader.ordercode');
--v_customer_name := json_ext.get_string(v_injson,'CallInfo.orderHeader.customer_name');
v_delivery_time := substr(json_ext.get_string(v_injson,
'CallInfo.orderHeader.delivery_time'),
1, 10);
dbms_output.put_line('v_delivery_time:' ||
to_number(REPLACE(v_delivery_time, '-', '')));
END LOOP;
END;
------------------------------------------------------------
*************解析json格式数据实例*******************
--新骏:订单接口,生成发货订单(自动任务:每5分钟运行一次)mantis:0029682
CREATE OR REPLACE PROCEDURE xq_midso_gen(p_id IN NUMBER) AS
----------------------------------------------------------
--author:xuyang
--date:20180627
--description:
/*
FOR (查询实际表[订单接口 XQ_MIDSO]中的[是否生成订单]为Y的记录) LOOP
根据接口信息的json信息生成未提交的发货订单。
生成发货订单头表:
单据日期取SYSDATE。
订单类型取新货订单。
发货店仓取总部店仓。
收货店仓取接口中的customer_name对应的经销商下的任一店仓(根据名称匹配)。
鲜桥订单编码取接口中的ordercode。
备注:由鲜桥接口自动生成!
调用存储过程:B_SO_AC。
生成发货订单明细:
条码、款号、ASI取接口中的product_name对应条码的值。
数量取接口中的amount。
调用存储过程:B_SOITEM_ACM。
调用存储过程:B_SO_AM。
END LOOP;
*/
/*
*/
----------------------------------------------------------
v_injson json; --用于将接口信息转换为json格式
v_b_so_id b_so.id%TYPE; --要使用的发货订单ID
v_b_so_docno b_so.docno%TYPE; --发货订单据编号
v_table_id ad_table.id%TYPE; --发货订单m_agtpur表的id
v_ordercode b_so.xq_ordercode%TYPE; --发货订单鲜桥订单编码
v_c_store_id c_store.id%TYPE; --总部店仓ID
v_customer_name c_customer.name%TYPE; --订单头信息中的经销商名称
v_cc_store_id c_store.id%TYPE; --经销商下任一id
v_delivery_time VARCHAR2(20); --配送时间(发货日期)
v_delivery_time1 NUMBER(8); --配送时间(发货日期)
v_delivery_address b_so.dest_address%TYPE; --收货地址
v_amount b_soitem.qty%TYPE; --数量
v_bodylist json_list; --订单明细信息列表
v_onejson json; --用于解析每一个明细数据
v_m_product_id m_product.id%TYPE; --款号
v_m_productalias_name m_product_alias.no%TYPE; --条码名
v_m_productalias_id m_product_alias.id%TYPE; --条码id
v_asi b_soitem.m_attributesetinstance_id%TYPE; --asi
v_b_soitem_id b_soitem.id%TYPE; --发货订单明细id
v_code NUMBER(3);
v_message VARCHAR2(500);
v_clob_varchar2 VARCHAR2(4000);
BEGIN
--查询实际表[订单接口 XQ_MIDSO]中的[是否生成订单]为Y的记录
FOR v_list IN (SELECT xms.id, xms.ad_client_id, xms.ad_org_id,
xms.creationdate, xms.ownerid, xms.errormeg
FROM xq_midso xms
WHERE xms.is_so = 'Y') LOOP
BEGIN
--获取接口信息
SELECT dbms_lob.substr(xms.param)
INTO v_clob_varchar2
FROM xq_midso xms
WHERE xms.id = v_list.id;
v_injson := json(v_clob_varchar2);
--获取headerlist:orderHeader
--v_id := json_ext.get_string(v_injson, 'CallInfo.orderHeader.id');
v_ordercode := json_ext.get_string(v_injson,
'CallInfo.orderHeader.ordercode');
v_customer_name := json_ext.get_string(v_injson,
'CallInfo.orderHeader.customer_name');
v_delivery_time := substr(json_ext.get_string(v_injson,
'CallInfo.orderHeader.delivery_time'),
1, 10);
v_delivery_time1 := to_number(REPLACE(v_delivery_time, '-', ''));
v_delivery_address := json_ext.get_string(v_injson,
'CallInfo.orderHeader.delivery_address');
--获取表b_so的id
SELECT id
INTO v_table_id
FROM ad_table
WHERE NAME = upper('b_so');
--自动生成单据编号
SELECT t.sequencename
INTO v_b_so_docno
FROM ad_column t
WHERE t.ad_table_id = v_table_id
AND t.dbname = 'DOCNO';
v_b_so_docno := get_sequenceno(v_b_so_docno, v_list.ad_client_id);
--获取要使用的发货订单id
v_b_so_id := get_sequences('B_SO');
--获取总部店仓ID
SELECT cs.id
INTO v_c_store_id
FROM c_store cs
WHERE cs.name = '总部仓库'
AND cs.ad_client_id = v_list.ad_client_id;
BEGIN
--获取对应经销商下任一店仓ID:v_cc_store_id
SELECT nvl(cs.id, 0)
INTO v_cc_store_id
FROM c_store cs
JOIN c_customer ccu
ON (cs.c_customer_id = ccu.id AND ccu.name = v_customer_name)
WHERE rownum <= 1;
EXCEPTION
WHEN no_data_found THEN
v_cc_store_id := NULL;
END;
/*
生成发货订单头表:
单据日期取SYSDATE。
订单类型取新货订单。
发货店仓取总部店仓。
收货店仓取接口中的customer_name对应的经销商下的任一店仓(根据名称匹配)。
鲜桥订单编码取接口中的ordercode。
备注:由鲜桥接口自动生成!
调用存储过程:B_SO_AC。
*/
--dbms_output.put_line('xuyang123:v_b_so_docno:' || v_b_so_docno);
BEGIN
INSERT INTO b_so
(id, billdate, docno, doctype, c_store_id, c_dest_id,
xq_ordercode, predateout, dest_address, description,
ad_client_id, ad_org_id, ownerid, creationdate, status,
isactive)
VALUES
(v_b_so_id, to_number(to_char(SYSDATE, 'yyyymmdd')),
v_b_so_docno, 'FWD', v_c_store_id, v_cc_store_id,
v_ordercode, v_delivery_time1, v_delivery_address,
'由鲜桥接口自动生成!', v_list.ad_client_id, v_list.ad_org_id,
v_list.ownerid, SYSDATE, 1, 'Y');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('(debug)订单接口记录id:' || v_list.id ||
',生成发货订单发生异常:' || SQLERRM);
CONTINUE;
END;
--调用存储过程:B_SO_AC。
BEGIN
b_so_ac(v_b_so_id);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('发货订单记录id:' || v_b_so_id ||
',调用发货订单ac程序b_so_ac发生异常:' || SQLERRM);
END;
/*获取明细数据,插入到发货订单明细表*/
/*
生成发货订单明细:
条码、款号、ASI取接口中的product_name对应条码的值。
数量取接口中的amount。
调用存储过程:B_SOITEM_ACM。
调用存储过程:B_SO_AM。
*/
v_bodylist := json_list();
v_onejson := json();
--获取body:orderBody
v_bodylist := json_ext.get_json_list(v_injson, 'CallInfo.orderBody');
--循环获取明细数据,并插入数据库中
FOR idx IN 1 .. v_bodylist.count LOOP
--读取每个明细信息
v_onejson := json(v_bodylist.get_elem(idx));
v_m_productalias_name := json_ext.get_string(v_onejson,
'product_name');
v_amount := to_number(json_ext.get_string(v_onejson, 'amount'));
--获取品名对应的款号,条码,asi
BEGIN
SELECT mpa.id, mpa.m_product_id,
mpa.m_attributesetinstance_id
INTO v_m_productalias_id, v_m_product_id, v_asi
FROM m_product_alias mpa
WHERE mpa.no = v_m_productalias_name;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('条码:' || v_m_productalias_name ||
',在条码档案中不存在!');
CONTINUE;
END;
--获取即将使用的发货订单明细记录id
v_b_soitem_id := get_sequences('bo_soitem');
--插入发货订单明细表
INSERT INTO b_soitem
(id, b_so_id, m_productalias_id, m_product_id,
m_attributesetinstance_id, qty)
VALUES
(v_b_soitem_id, v_b_so_id, v_m_productalias_id,
v_m_product_id, v_asi, v_amount);
--调用存储过程:B_SOITEM_ACM
BEGIN
b_soitem_acm(v_b_soitem_id);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('发货订单明细记录id:' || v_b_soitem_id ||
',调用发货订单明细acm程序b_soitem_acm发生异常:' ||
SQLERRM);
END;
--调用存储过程:B_SO_AM
BEGIN
b_so_am(v_b_so_id, v_code, v_message);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('发货订单记录id:' || v_b_so_id ||
',调用发货订单am程序B_SO_AM发生异常:' ||
SQLERRM);
END;
END LOOP;
--生成发货订单后,更新订单接口xq_midso当前记录is_so为‘N’
UPDATE xq_midso xms
SET xms.is_so = 'N'
WHERE xms.id = v_list.id;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('订单接口记录id:' || v_list.id ||
',生成发货订单发生异常:' || SQLERRM);
END;
END LOOP;
END;
----用于自动生成单据编号
CREATE OR REPLACE FUNCTION get_sequenceno(p_seqname IN VARCHAR2,
p_clientid IN NUMBER) RETURN VARCHAR2 AS
PRAGMA AUTONOMOUS_TRANSACTION;
v_prefix VARCHAR2(30);
v_postfix VARCHAR2(30);
v_format VARCHAR2(120);
v_currentnext NUMBER(10);
v_id NUMBER(10);
v_lastdate DATE;
v_no VARCHAR2(255);
v_cycletype CHAR(1);
v_incrementno NUMBER(10);
v_sql VARCHAR2(400);
pctx plog.log_ctx := plog.init('Get_SequenceNo', plog.linfo);
/**
* 根据ad_table定义的ad_sequence的名字
* vFormat 中含有生成的序列的规则, 最终的编号规则是
* prefix + vFormat + postfix
* vFormat 中 yy/mm/dd 表示年,9999表示按日循环递增,0000表示无循环递增
* @param p_seqName 是 ad_sequence 表的name 字段的值
*/
BEGIN
SELECT id, nvl(prefix, ''), nvl(suffix, ''), vformat, currentnext,
to_date(to_char(lastdate), 'YYYYMMDD'), cycletype,
nvl(incrementno, 1)
INTO v_id, v_prefix, v_postfix, v_format, v_currentnext, v_lastdate,
v_cycletype, v_incrementno
FROM ad_sequence
WHERE NAME = upper(TRIM(p_seqname))
AND ad_client_id = p_clientid
FOR UPDATE;
IF v_cycletype = 'D' THEN
-- cycle by day
IF to_char(v_lastdate, 'yyyymmdd') <> to_char(SYSDATE, 'yyyymmdd') THEN
v_currentnext := 0;
END IF;
ELSIF v_cycletype = 'M' THEN
-- cycle by month
IF to_char(v_lastdate, 'yyyymm') <> to_char(SYSDATE, 'yyyymm') THEN
v_currentnext := 0;
END IF;
ELSIF v_cycletype = 'Y' THEN
-- cycle by year
IF to_char(v_lastdate, 'yyyy') <> to_char(SYSDATE, 'yyyy') THEN
v_currentnext := 0;
END IF;
END IF;
v_currentnext := v_currentnext + v_incrementno;
UPDATE ad_sequence
SET lastdate = to_number(to_char(SYSDATE, 'YYYYMMDD')),
currentnext = v_currentnext
WHERE id = v_id;
v_sql := 'select ' ||
REPLACE(v_format, '$nextval', ltrim(to_char(v_currentnext))) ||
' from dual ';
EXECUTE IMMEDIATE v_sql
INTO v_no;
COMMIT;
plog.info(pctx,
'p_seqName=' || p_seqname || ', CURRENTNEXT=' || v_currentnext ||
', v_lastdate=' || v_lastdate);
COMMIT;
RETURN v_prefix || v_no || v_postfix;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
plog.error(pctx,
'Error for Get_SequenceNo(' || p_seqname || ',' ||
p_clientid || '):code=' || SQLCODE || ', err=' || SQLERRM);
COMMIT;
raise_application_error(-20201, '无法生成名称为 ' || p_seqname || ' 的单据号!');
END;
---------------------------------------------------------------
报表
----0030525: 一、20180727-V1.0-凰艮项目20180717-云仓订单信息汇总表 4h
CREATE OR REPLACE PROCEDURE rp_o2oinfo_generate(p_pi_id NUMBER) IS
---------------------------------------------------
--Author:xy
-- Date:20180721
-- Description :
-- 查询单据日期在查询条件的单据日期范围内、 下单店仓与查询条件的店仓一致、并且已提交的、未结案、可用的云仓订单
---------------------------------------------------
v_userid NUMBER(10);
v_date VARCHAR2(80);
v_datebegin NUMBER(8); --开始日期
v_dateend NUMBER(8); --结束日期
v_c_store_ids r_tabid := r_tabid(); --下单店仓id集合
v_sql1 VARCHAR2(4000);
BEGIN
-- raise_application_error(-20201, p_pi_id);
EXECUTE IMMEDIATE ('truncate TABLE RP_O2OINFO');
--定义公共sql
v_sql1 := 'SELECT t.info
FROM ad_pinstance_para t
WHERE t.name = :name AND t.ad_pinstance_id = :p_pi_id';
SELECT t.modifierid
INTO v_userid
FROM ad_pinstance t
WHERE t.id = p_pi_id;
--依次获取界面查询条件参数
EXECUTE IMMEDIATE v_sql1
INTO v_date
USING 'BILLDATE', p_pi_id;
IF v_date IS NULL THEN
--如开始日期和结束日期都没有选择,
raise_application_error(-20201, '请选择单据日期范围!');
ELSE
IF instr(v_date, '>=') > 0 THEN
--如只选择了开始日期,则结束日期默认为当前时间
--注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
v_datebegin := substr(v_date, 13, 8);
--结束日期默认为当前日期
v_dateend := to_char(SYSDATE, 'yyyymmdd');
ELSIF instr(v_date, '<=') > 0 THEN
--如只选择了结束日期,则开始日期默认18400101
--注意这里是不是从9开始,取决于日期参数定义,例如日期参数名定义为DATE,则此处为9,如定义为BILLDATE,此处为13,以此类推
v_dateend := substr(v_date, 13, 8);
v_datebegin := 18400101;
ELSE
v_datebegin := substr(v_date, 21, 8);
v_dateend := substr(v_date, 34, 8);
END IF;
END IF;
--获取下单店仓id集合
EXECUTE IMMEDIATE v_sql1
INTO v_sql1
USING 'C_STORE_ID', p_pi_id;
v_c_store_ids := f_fast_table(v_sql1);
IF v_c_store_ids.COUNT = 0 THEN
v_sql1 := 'SELECT CS.ID FROM C_STORE CS WHERE CS.ISACTIVE = ''Y''';
v_c_store_ids := f_fast_table(v_sql1);
END IF;
--下单次数:单据日期等于行定义单据日期,下单店仓等于行定义店铺,已提交的可用的云仓订单的个数
INSERT INTO rp_o2oinfo
(id, ad_client_id, ad_org_id, billdate, yearmonth, c_store_id, ownerid,
isactive, ordernum, ad_pi_id)
SELECT get_sequences('RP_O2OINFO'), os.ad_client_id, os.ad_org_id,
os.billdate, substr(os.billdate, 1, 6), os.c_store_id, os.ownerid,
'Y', COUNT(1), p_pi_id
FROM o2o_so os, TABLE(v_c_store_ids) vs
WHERE os.isactive = 'Y'
AND os.status = 2
AND os.close_status = 1
AND os.billdate BETWEEN v_datebegin AND v_dateend
AND os.c_store_id = vs.id
GROUP BY os.ad_client_id, os.ad_org_id, os.billdate, os.c_store_id,
os.ownerid;
--发货次数:发货日期等于行定义的单据日期,发货店仓等于行定义店铺,发货状态为已提交的云仓订单的个数
--快递费用:发货时间的日期等于行定义单据日期,发货店仓等于行定义店铺,发货状态为已提交的云仓订单中快递费用/元的和
MERGE INTO rp_o2oinfo rp
USING (SELECT os.dateoutin, os.c_orig_id, COUNT(os.id) AS cnt,
SUM(os.deliverycosts) AS tot_exp_fee
FROM o2o_so os, TABLE(v_c_store_ids) vs
WHERE os.isactive = 'Y'
AND os.out_status = 2
AND os.status = 2
AND os.close_status = 1
AND os.dateoutin BETWEEN v_datebegin AND v_dateend
AND os.c_orig_id = vs.id
GROUP BY os.dateoutin, os.c_orig_id) tp
ON (rp.c_store_id = tp.c_orig_id AND rp.billdate = tp.dateoutin)
WHEN MATCHED THEN
UPDATE
SET rp.deliverynum = tp.cnt, rp.express_fee = tp.tot_exp_fee;
--客诉:单据日期等于行定义单据日期,发货店仓等于行定义店铺,已提交的客诉申请单的的个数。
MERGE INTO rp_o2oinfo rp
USING (SELECT cc.billdate, cc.c_orig_id, COUNT(cc.id) AS cnt
FROM c_complain cc, TABLE(v_c_store_ids) vs
WHERE cc.status = 2
AND cc.billdate BETWEEN v_datebegin AND v_dateend
AND cc.c_orig_id = vs.id
GROUP BY cc.billdate, cc.c_orig_id) tp
ON (rp.c_store_id = tp.c_orig_id AND rp.billdate = tp.billdate)
WHEN MATCHED THEN
UPDATE
SET rp.complain_num = tp.cnt;
--拒单次数:变更时间的日期等于行定义单据日期,店仓等于行定义店铺,
--重新指派原因或者退回原因不为空的表【派单日志O2O_SOSPLIT_LOG】的记录的条数。
MERGE INTO rp_o2oinfo rp
USING (SELECT to_number(to_char(osl.changetime, 'YYYYMMDD')) AS changedate,
osl.c_store_id, COUNT(osl.id) AS cnt
FROM o2o_sosplit_log osl, TABLE(v_c_store_ids) vs
WHERE to_number(to_char(osl.changetime, 'YYYYMMDD')) BETWEEN
v_datebegin AND v_dateend
AND (osl.o2o_assignorig_reason_id IS NOT NULL OR
osl.o2o_back_reason_id IS NOT NULL)
AND osl.c_store_id = vs.id
GROUP BY to_number(to_char(osl.changetime, 'YYYYMMDD')),
osl.c_store_id) tp
ON (rp.billdate = tp.changedate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.reject_ordernum = tp.cnt;
--次品拒单:变更时间的日期等于行定义单据日期,店仓等于行定义店铺,
--退回原因O2O_BACK_REASON_ID等于表【退回原因O2O_BACK_REASON】中描述=“货品残次”;表【派单日志O2O_SOSPLIT_LOG】的记录的条数。
MERGE INTO rp_o2oinfo rp
USING (SELECT to_number(to_char(osl.changetime, 'YYYYMMDD')) AS changedate,
osl.c_store_id, COUNT(osl.id) AS cnt
FROM o2o_sosplit_log osl, o2o_back_reason obr, TABLE(v_c_store_ids) vs
WHERE to_number(to_char(osl.changetime, 'YYYYMMDD')) BETWEEN
v_datebegin AND v_dateend
AND obr.id = osl.o2o_back_reason_id
AND obr.NAME = '货品残次'
AND osl.c_store_id = vs.id
GROUP BY to_number(to_char(osl.changetime, 'YYYYMMDD')),
osl.c_store_id) tp
ON (rp.billdate = tp.changedate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.reject_defectnum = tp.cnt;
--无实货拒单:变更时间的日期等于行定义单据日期,店仓等于行定义店铺,
--退回原因O2O_BACK_REASON_ID等于表【退回原因O2O_BACK_REASON】中描述=“库存不足”;表【派单日志O2O_SOSPLIT_LOG】的记录的条数。
MERGE INTO rp_o2oinfo rp
USING (SELECT to_number(to_char(osl.changetime, 'YYYYMMDD')) AS changedate,
osl.c_store_id, COUNT(osl.id) AS cnt
FROM o2o_sosplit_log osl, o2o_back_reason obr, TABLE(v_c_store_ids) vs
WHERE to_number(to_char(osl.changetime, 'YYYYMMDD')) BETWEEN
v_datebegin AND v_dateend
AND obr.id = osl.o2o_back_reason_id
AND obr.NAME = '库存不足'
AND osl.c_store_id = vs.id
GROUP BY to_number(to_char(osl.changetime, 'YYYYMMDD')),
osl.c_store_id) tp
ON (rp.billdate = tp.changedate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.rejet_nogoods_num = tp.cnt;
--超时转单次数:变更时间的日期等于行定义单据日期,店仓等于行定义店铺,
--退回原因O2O_BACK_REASON_ID等于表【退回原因O2O_BACK_REASON】中描述=“系统退回”;表【派单日志O2O_SOSPLIT_LOG】的记录的条数。
MERGE INTO rp_o2oinfo rp
USING (SELECT to_number(to_char(osl.changetime, 'YYYYMMDD')) AS changedate,
osl.c_store_id, COUNT(osl.id) AS cnt
FROM o2o_sosplit_log osl, o2o_back_reason obr, TABLE(v_c_store_ids) vs
WHERE to_number(to_char(osl.changetime, 'YYYYMMDD')) BETWEEN
v_datebegin AND v_dateend
AND obr.id = osl.o2o_back_reason_id
AND obr.NAME = '系统退回'
AND osl.c_store_id = vs.id
GROUP BY to_number(to_char(osl.changetime, 'YYYYMMDD')),
osl.c_store_id) tp
ON (rp.billdate = tp.changedate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.overtime_ordernum = tp.cnt;
--所得奖励:激励时间的日期等于行定义单据日期,店铺等于行定义店铺,表【店铺激励明细表】中激励金额的和。
MERGE INTO rp_o2oinfo rp
USING (SELECT to_number(to_char(cso.supdate, 'YYYYMMDD')) AS supdate,
cso.c_store_id, SUM(cso.supamt) AS tot_supamt
FROM c_storesup_o2o cso, TABLE(v_c_store_ids) vs
WHERE to_number(to_char(cso.supdate, 'YYYYMMDD')) BETWEEN v_datebegin AND
v_dateend
AND cso.c_store_id = vs.id
GROUP BY to_number(to_char(cso.supdate, 'YYYYMMDD')), cso.c_store_id) tp
ON (rp.billdate = tp.supdate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.reward = tp.tot_supamt;
--信用分:变动日期等于行定义单据日期,店仓等于行定义店仓,表【店仓信用流水账】中信用额度的和。
MERGE INTO rp_o2oinfo rp
USING (SELECT fsf.c_store_id, fsf.changedate,
SUM(fsf.credit_quota) AS tot_cred_quota
FROM fa_storecredit_ftp fsf, TABLE(v_c_store_ids) vs
WHERE fsf.changedate BETWEEN v_datebegin AND v_dateend
AND fsf.c_store_id = vs.id
GROUP BY fsf.changedate, fsf.c_store_id) tp
ON (rp.billdate = tp.changedate AND rp.c_store_id = tp.c_store_id)
WHEN MATCHED THEN
UPDATE
SET rp.credit_score = tp.tot_cred_quota;
END;
----------------------------------------------------------------------------
--美邦:期货销售合同中的’预配‘动作定义
CREATE OR REPLACE PROCEDURE b_perallot_gen(p_user_id IN NUMBER,
p_query IN VARCHAR2,
r_code OUT NUMBER,
r_message OUT VARCHAR2) AS
---------------------------------------------------------
--author: xy
--date: 20180725
--并发控制。
--增加控制:如果单据未提交,不允许。
--增加控制:如果系统中存在期货合同编号为本单的期货订货单或期货配差单,不允许。
--增加控制:如果期货销售合同在中间表中已经存在,不允许再次传入(用合同编号判断)。
--将本单期货销售合同头表信息传入中间表[UNI_FIRSO]、期货销售合同明细信息传入中间表[UNI_FIRSOITEM]
--传入中间表后,更新单据的[预配是否传入中间表]为Y
---------------------------------------------------------
--声明用于从p_query解析参数获得单据ID的相关记录和变量
TYPE t_queryobj IS RECORD(
"table" VARCHAR2(255),
query VARCHAR2(32676),
id VARCHAR2(10));
v_queryobj t_queryobj;
TYPE t_selection IS TABLE OF NUMBER(10) INDEX BY BINARY_INTEGER;
v_selection t_selection;
st_xml VARCHAR2(32676);
v_xml xmltype;
p_id NUMBER(10); --单据ID
--其他变量定义
v_status b_fir_so.status%TYPE; --单据状态
v_docno b_fir_so.docno%TYPE; --单据编号
v_cnt NUMBER(10);
v_cnt1 NUMBER(10);
BEGIN
--从p_query解析参数
st_xml := '<data>' || p_query || '</data>';
v_xml := xmltype(st_xml);
SELECT extractvalue(VALUE(t), '/data/table'),
extractvalue(VALUE(t), '/data/query'),
extractvalue(VALUE(t), '/data/id')
INTO v_queryobj
FROM TABLE(xmlsequence(extract(v_xml, '/data'))) t;
SELECT extractvalue(VALUE(t), '/selection')
BULK COLLECT
INTO v_selection
FROM TABLE(xmlsequence(extract(v_xml, '/data/selection'))) t;
p_id := v_queryobj.id;
--end 解析参数
--并发控制
BEGIN
EXECUTE IMMEDIATE 'select 1 from b_fir_so t where t.id=' || p_id ||
' for update nowait';
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20201, SQLERRM);
END;
--获取提交状态,单据编号
SELECT bfs.status, bfs.docno
INTO v_status, v_docno
FROM b_fir_so bfs
WHERE bfs.id = p_id;
--如果单据未提交,不允许
IF v_status = 1 THEN
raise_application_error(-20201, '单据未提交,不允许!');
END IF;
--如果系统中存在期货合同编号为本单的期货订货单或期货配差单,不允许
SELECT nvl(COUNT(1), 0)
INTO v_cnt
FROM b_fwdso bfw
WHERE bfw.b_fir_so_id = p_id;
SELECT nvl(COUNT(1), 0)
INTO v_cnt1
FROM b_fwdtocan bfw
WHERE bfw.b_fir_so_id = p_id;
IF v_cnt <> 0 OR v_cnt1 <> 0 THEN
raise_application_error(-20201, '系统中存在期货合同编号为本单的期货订货单或期货配差单,不允许!');
END IF;
--如果期货销售合同在中间表中已经存在,不允许再次传入(用合同编号判断)
SELECT nvl(COUNT(id), 0)
INTO v_cnt
FROM uni_firso uf
WHERE uf.code = v_docno;
IF v_cnt <> 0 THEN
raise_application_error(-20201,
'期货销售合同:' || v_docno || '在中间表中已经存在,不允许再次传入!');
END IF;
--将本单期货销售合同头表信息传入中间表[UNI_FIRSO]、期货销售合同明细信息传入中间表[UNI_FIRSOITEM]
INSERT INTO uni_firso
(id, ad_client_id, ad_org_id, code, vender_code, vendee_code, doc_date,
shop_code, rcv_wareh_code, is_assign_wareh, assign_wareh_code,
order_qty, audit_date, require_date, brand_code, remark, ediflag,
ownerid, modifierid, creationdate, modifieddate, isactive)
SELECT bfs.id, bfs.ad_client_id, bfs.ad_org_id, bfs.docno, gc.code,
gc1.code, bfs.billdate, cs.code,
decode(bfs.protype, 1, cs1.code, 2, cs2.code),
decode(bfs.is_origstore, 'Y', 'T', 'N', 'F'), cs3.code,
bfs.tot_qty, bfs.statustime, bfs.perdate, md.attribcode,
bfs.description, 80, p_user_id, p_user_id, SYSDATE, SYSDATE, 'Y'
FROM b_fir_so bfs
LEFT JOIN g_company gc
ON (gc.id = bfs.g_company_id)
LEFT JOIN g_company gc1
ON (gc1.id = bfs.g_destpany_id)
LEFT JOIN c_store cs
ON (cs.id = bfs.c_dest_id)
LEFT JOIN c_store cs1
ON (cs1.id = cs.c_spstore_id)
LEFT JOIN c_store cs2
ON (cs2.id = cs.c_flstore_id)
LEFT JOIN c_store cs3
ON (cs3.id = bfs.c_store_id)
LEFT JOIN m_dim md
ON (md.id = bfs.m_dim1_id)
WHERE bfs.id = p_id;
INSERT INTO uni_firsoitem
(id, ad_client_id, ad_org_id, fuc_code, prod_code, order_qty, ediflag,
ownerid, modifierid, creationdate, modifieddate, isactive)
SELECT bfi.id, bfi.ad_client_id, bfi.ad_org_id, v_docno, mpa.no, bfi.qty,
80, p_user_id, p_user_id, SYSDATE, SYSDATE, 'Y'
FROM b_fir_soitem bfi
JOIN m_product_alias mpa
ON (mpa.id = bfi.m_productalias_id)
WHERE bfi.b_fir_so_id = p_id;
--传入中间表后,更新单据的[预配是否传入中间表]
UPDATE b_fir_so bfs
SET bfs.is_pretouni = 'Y'
WHERE bfs.id = p_id;
r_code := 1;
r_message := '预配成功!!';
END;
---------------------------------------------------------------------------------
--从界面端clob字段获取对应sql语句
CREATE OR REPLACE FUNCTION get_fitler_sql(p_str IN CLOB) RETURN CLOB IS
v_xml xmltype;
myresult CLOB;
BEGIN
--edit by robin 解决超过4000个字符问题
if p_str is null then
return null;
end if;
begin
v_xml:=xmltype(p_str);
SELECT extractvalue(VALUE(t), '/filter/sql')
INTO myresult
FROM TABLE(xmlsequence(extract(v_xml, '/filter'))) t;
exception
when others then
myresult := clobTransXml(clobSubStr(p_str, '<sql>', '</sql>'));
end;
RETURN myresult;
END get_fitler_sql;
----------------------------------------------------------------------------
--获取对应记录id集合
create or replace function f_fast_table(v_sql in varchar2) return r_tabid as
v_test r_tabid := r_tabid();
type t_type1 is table of number(10) index by binary_integer;
p_id t_type1;
begin
execute immediate v_sql bulk collect into p_id;
if p_id.count != 0 then
for i in 1 .. p_id.last loop
v_test.extend();
v_test(v_test.count) := r_id(p_id(i));
end loop;
else
v_test.extend();
v_test(1) := r_id(0);
end if;
return v_test;
end ;
-------------------------------------------------------------------------
--获取指定单据编号
CREATE OR REPLACE FUNCTION get_sequenceno(p_seqname IN VARCHAR2,
p_clientid IN NUMBER) RETURN VARCHAR2 AS
PRAGMA AUTONOMOUS_TRANSACTION;
v_prefix VARCHAR2(30);
v_postfix VARCHAR2(30);
v_format VARCHAR2(120);
v_currentnext NUMBER(10);
v_id NUMBER(10);
v_lastdate DATE;
v_no VARCHAR2(255);
v_cycletype CHAR(1);
v_incrementno NUMBER(10);
v_sql VARCHAR2(400);
pctx plog.log_ctx := plog.init('Get_SequenceNo', plog.linfo);
/**
* 根据ad_table定义的ad_sequence的名字
* vFormat 中含有生成的序列的规则, 最终的编号规则是
* prefix + vFormat + postfix
* vFormat 中 yy/mm/dd 表示年,9999表示按日循环递增,0000表示无循环递增
* @param p_seqName 是 ad_sequence 表的name 字段的值
*/
BEGIN
SELECT id, nvl(prefix, ''), nvl(suffix, ''), vformat, currentnext,
to_date(to_char(lastdate), 'YYYYMMDD'), cycletype,
nvl(incrementno, 1)
INTO v_id, v_prefix, v_postfix, v_format, v_currentnext, v_lastdate,
v_cycletype, v_incrementno
FROM ad_sequence
WHERE NAME = upper(TRIM(p_seqname))
AND ad_client_id = p_clientid
FOR UPDATE;
IF v_cycletype = 'D' THEN
-- cycle by day
IF to_char(v_lastdate, 'yyyymmdd') <> to_char(SYSDATE, 'yyyymmdd') THEN
v_currentnext := 0;
END IF;
ELSIF v_cycletype = 'M' THEN
-- cycle by month
IF to_char(v_lastdate, 'yyyymm') <> to_char(SYSDATE, 'yyyymm') THEN
v_currentnext := 0;
END IF;
ELSIF v_cycletype = 'Y' THEN
-- cycle by year
IF to_char(v_lastdate, 'yyyy') <> to_char(SYSDATE, 'yyyy') THEN
v_currentnext := 0;
END IF;
END IF;
v_currentnext := v_currentnext + v_incrementno;
UPDATE ad_sequence
SET lastdate = to_number(to_char(SYSDATE, 'YYYYMMDD')),
currentnext = v_currentnext
WHERE id = v_id;
v_sql := 'select ' ||
REPLACE(v_format, '$nextval', ltrim(to_char(v_currentnext))) ||
' from dual ';
EXECUTE IMMEDIATE v_sql
INTO v_no;
COMMIT;
plog.info(pctx,
'p_seqName=' || p_seqname || ', CURRENTNEXT=' || v_currentnext ||
', v_lastdate=' || v_lastdate);
COMMIT;
RETURN v_prefix || v_no || v_postfix;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
plog.error(pctx,
'Error for Get_SequenceNo(' || p_seqname || ',' ||
p_clientid || '):code=' || SQLCODE || ', err=' || SQLERRM);
COMMIT;
raise_application_error(-20201, '无法生成名称为 ' || p_seqname || ' 的单据号!');
END;
------
(美邦)存储过程:MATMULTI_INVENTORY
--弹出一个对话框,并且在关闭时刷新后面的那张网页
SELECT to_char(id)
INTO t_id
FROM ad_table
WHERE NAME = 'M_MATMULTI_INVENTORY';
r_code := 5;
r_message := 'showDialog("/html/nds/object/object.jsp?table=' || t_id ||
'&fixedcolumns=&id=' || v_m_matmulti_inventory_id ||
'",940, 530,true)';
-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 输入的数据已存在ID: SELECT MAX(ID) FROM AD_COLUMN; 根据max(ID)设置序列SEQ_AD_COLUMN的下一个值 -->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

浙公网安备 33010602011771号