传递数组的存储过程实例

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;


你可能感兴趣的:(sql,SQL Server,F#)