create or replace procedure PRE_BOOKTICKET_SEND(TICKETID VARCHAR2, PHONES tab_array,message varchar2) is --handel utl_file.file_type; -- 定义处理文件对象 v_phonenumber varchar2(1024); -- 手机号码 Type ticketModel Is Record -- 书券记录 (id con_ticketinfo.id%type, -- 书券ID price con_ticketinfo.price%type, -- 书券单价 consumetime con_ticketinfo.consumetime%type, -- 消费时长 consumetype con_ticketinfo.consumetype%type, -- 书券类型 1:领取后定时消费 2:定日期消费 consumebegin con_ticketinfo.consumebegintime%type, -- 书券消费开始日期 consumeend con_ticketinfo.consumeendtime%type); -- 书券消费结束时间 type us_ticketModel is record -- 用户书券总表记录 (totalamount us_ticketinfo.totalamount%type, earliestprice us_ticketinfo.earliestprice%type, earliesttime us_ticketinfo.earliesttime%type, useableamount us_ticketinfo.useableamount%type, earlieststarttime us_ticketinfo.earlieststarttime%type); v_ticket ticketModel; --v_sendinto con_ticket_sendinfo.sendmessage%type; -- 书券消息内容 v_usinfo us_ticketModel; v_begindate date; v_enddate date; v_begindate_var varchar2(20); -- var类型开始发放时间/存放临时日期 v_enddate_var varchar2(20); -- var类型解释发放时间/存放临时日期 v_sql varchar2(1000); -- 执行SQL v_all_phone number(20) := 0; -- 总发送数 v_s_phone number(20) := 0; -- 成功发送数 v_f_phone number(20) := 0; -- 失败发生数 v_sdate varchar2(20); v_edate varchar2(20); dt_sysdate date; -- 系统时间 dt_sysdate_var varchar2(20); -- 系统时间 --v_tmp_date varchar2(20); -- 临时日期变量 --v_all_balance us_ticketinfo.totalamount%type; --v_use_balance us_ticketinfo.useableamount%type; begin --dbms_output.put_line(to_char(sysdate,'yyyy-MM-dd HH24:mi:ss')); -- 1.查询书券的基本信息 begin select t.id ,t.price ,t.consumetime ,t.consumetype ,t.consumebegintime , t.consumeendtime into v_ticket from con_ticketinfo t where t.id = TICKETID; --select h.sendmessage into v_sendinto from con_ticket_sendinfo h where h.id = TICKETID; end; -- 2.判读书券类型 --if v_ticket.consumetype = 1 then -- v_begindate := sysdate; -- v_enddate := v_begindate + v_ticket.consumetime/24; -- v_sql := 'update con_ticketinfo set consumebegintime = sysdate , consumeendtime = sysdate + '||v_ticket.consumetime/24||' where id = '||TICKETID; --execute immediate v_sql; -- commit; --else v_begindate := v_ticket.consumebegin; v_enddate := v_ticket.consumeend; --end if; if v_begindate is not null and v_enddate is not null then v_begindate_var := to_char(v_begindate,'yyyy-MM-dd HH24:mi:ss'); v_enddate_var := to_char(v_enddate,'yyyy-MM-dd HH24:mi:ss'); end if; -- 3.循环查询书券 -- handel := utl_file.fopen(FILE_DIR,FILE_NAME,'r'); --loop for i in 1 .. PHONES.count loop begin -- 读取文件 --utl_file.get_line(handel,v_phonenumber); v_phonenumber := PHONES(i); -- 手机号码 v_phonenumber := substr(v_phonenumber,1,11); v_all_phone := v_all_phone+1; -- 总数+1 -- 若是定时长的话,领取时间就是消费开始时间, -- 若是消费时间短的话,就是系统时间 dt_sysdate := sysdate; if v_ticket.consumetype = 1 then v_begindate := dt_sysdate; v_enddate := v_begindate + v_ticket.consumetime/24; v_begindate_var := to_char(v_begindate,'yyyy-MM-dd HH24:mi:ss'); v_enddate_var := to_char(v_enddate,'yyyy-MM-dd HH24:mi:ss'); end if; dt_sysdate_var := to_char(dt_sysdate,'yyyy-MM-dd HH24:mi:ss'); -- 插入详表信息 v_sql := 'insert into us_ticketinfo_detail values('||v_phonenumber||', '||TICKETID||', to_date('''||dt_sysdate_var||''',''yyyy-MM-dd HH24:mi:ss''), to_date('''||v_begindate_var||''',''yyyy-MM-dd HH24:mi:ss''), to_date('''||v_enddate_var||''',''yyyy-MM-dd HH24:mi:ss''), '||v_ticket.price||', '||v_ticket.price||', to_date(to_char(sysdate,''yyyy-MM-dd HH24:mi:ss''),''yyyy-MM-dd HH24:mi:ss''), '||seq_us_ticketinfo_detail.nextval||')'; execute immediate v_sql; begin -- 查看用户书券总表 select totalamount,earliestprice,earliesttime,useableamount,earlieststarttime into v_usinfo from us_ticketinfo where msisdn = trim(v_phonenumber); --dbms_output.put_line(); -- 总的余额 v_usinfo.totalamount := v_ticket.price + v_usinfo.totalamount; if (v_begindate <= sysdate) then v_usinfo.useableamount := v_ticket.price + v_usinfo.useableamount; end if; -- 书券开始时间大于用户即将开始使用的消费券时间并且 书券开始时间大于当前时间 if v_begindate < v_usinfo.earlieststarttime and v_begindate > sysdate then v_usinfo.earlieststarttime := v_begindate; end if; -- 如果书券结束时间小于即将过期时间 if v_enddate < v_usinfo.earliesttime and v_enddate > sysdate and v_begindate <= sysdate then v_usinfo.earliesttime := v_enddate; v_usinfo.earliestprice := v_ticket.price; -- 如果书券结束时间等于即将过期时间 elsif v_enddate = v_usinfo.earliesttime then v_usinfo.earliestprice := v_ticket.price + v_usinfo.earliestprice; end if; --v_begindate_var := to_char(v_usinfo.earlieststarttime,'yyyy-MM-dd HH24:mi:ss'); --v_enddate_var := to_char(v_usinfo.earliesttime,'yyyy-MM-dd HH24:mi:ss'); v_sdate := to_char(v_usinfo.earlieststarttime,'yyyy-MM-dd HH24:mi:ss'); v_edate := to_char(v_usinfo.earliesttime,'yyyy-MM-dd HH24:mi:ss'); -- 更新书券表 v_sql := 'update us_ticketinfo set totalamount = '||v_usinfo.totalamount||', earliestprice = '||v_usinfo.earliestprice||', earliesttime = to_date('''||v_edate||''',''yyyy-MM-dd HH24:mi:ss''), lastmodifytime = to_date(to_char(sysdate,''yyyy-MM-dd HH24:mi:ss''),''yyyy-MM-dd HH24:mi:ss''), useableamount = '||v_usinfo.useableamount||', earlieststarttime = to_date('''||v_sdate||''',''yyyy-MM-dd HH24:mi:ss'') where MSISDN = '||v_phonenumber; dbms_output.put_line(v_sql); execute immediate v_sql; exception -- 若是记录不存在 when no_data_found then begin -- 若是定时长 if v_ticket.consumetype = 1 then v_sdate := to_char(v_begindate,'yyyy-MM-dd HH24:mi:ss'); v_edate := to_char(v_enddate,'yyyy-MM-dd HH24:mi:ss'); else -- 转化日期格式 v_sdate := to_char(v_ticket.consumebegin,'yyyy-MM-dd HH24:mi:ss'); v_edate := to_char(v_ticket.consumeend,'yyyy-MM-dd HH24:mi:ss'); end if; -- 消费开始时间小于等于当前时间 if v_begindate <= sysdate then v_sql := 'insert into us_ticketinfo values('||v_phonenumber||','||v_ticket.price||','||v_ticket.price||',to_date('''||v_edate||''',''yyyy-MM-dd HH24:mi:ss''),to_date(to_char(sysdate,''yyyy-MM-dd HH24:mi:ss''),''yyyy-MM-dd HH24:mi:ss''),'||v_ticket.price||',to_date(''2999-12-31 00:00:00'',''yyyy-MM-dd HH24:mi:ss''))'; else v_sql := 'insert into us_ticketinfo values('||v_phonenumber||','||v_ticket.price||',0,to_date(''2999-12-31 00:00:00'',''yyyy-MM-dd HH24:mi:ss''),to_date(to_char(sysdate,''yyyy-MM-dd HH24:mi:ss''),''yyyy-MM-dd HH24:mi:ss''),0,to_date('''||v_sdate||''',''yyyy-MM-dd HH24:mi:ss''))'; end if; --dbms_output.put_line(v_sql); execute immediate v_sql; exception when others then rollback; end; when others then rollback; end; -- 发送站内消息 v_sql := 'insert into us_internalinfo(msgid,recmsisdn,sendmsisdn,type,isread,sendtime,message,title) values(S_SERVER_US_INTERNALINFO_SEQ.NEXTVAL,'||v_phonenumber||',12345678900,1,0,to_date(to_char(sysdate,''yyyy-MM-dd HH24:mi:ss''),''yyyy-MM-dd HH24:mi:ss''),'''||message||''',''获得书券'')'; --dbms_output.put_line(v_sql); execute immediate v_sql; v_s_phone := v_s_phone+1; -- 成功发送数 exception when no_data_found then exit; when others then -- 若是执行数据失败,则回滚记录 v_f_phone := v_f_phone+1; -- 失败发送数 rollback; end; -- 每一万条数据提交一次 if v_all_phone = 1000 then v_all_phone := 0; commit; end if; end loop; commit; -- 关闭文件 --utl_file.fclose(handel); --begin -- 4.更新推送信息表书券状态 --update con_ticket_sendinfo set sendflag = 1 where id = TICKETID; -- 5.更新书券主表状态 --update con_ticketinfo set status = 5 where id = TICKETID; --commit; --exception -- when others then -- rollback; --end; --dbms_output.put_line(to_char(sysdate,'yyyy-MM-dd HH24:mi:ss')); end PRE_BOOKTICKET_SEND;