小弟是新手,请高手帮忙,谢谢1. 请编写一个分页存储过程
2. 要求:
  2.1. 表结构:自己写一个脚本,建立一张名为SQL001的表,表中需要有字段
               id     number  主键,从序列器sql001_seq中取值,从1开始
               page   number  非空,页码
  2.2. 写一个存储过程,每执行一次向表中插入一条记录:id为直接从序列器中取,page为随机生成一个从1-20之间的数。
  2.3. 后面插入的page不会与已插入的page重复。
  2.4. 再写一个存储过程,循环往表中插入20条随机记录,即表中数据是:1-20随机排列的数据。
  2.5. 再写一个存储,参数如下:
         p_i_begin 输入,与表中page类型一样
         p_i_end 输入,与表中page类型一样
         p_o_flag 输出,VARCHAR2(2) 如果有输出结果则返回1,并在p_o_result中返回结果,如果没有结果或异常,则返回0,p_o_result返回空记录游标
         p_o_result 输出,游标类型,用于返回查询结果集
       功能:查询已插入page从小到大排列后,第p_i_begin到第p_i_end条记录。
  2.6. 3个存储过程需要放在一个包中,包名自己定义。
  2.7. 严格按照编码规范编码,代码需要有尽量多的注释。
3. 说明:
    主要考核建表语句,序列器,基本包,存储过程,随机函数等知识
4.提示:
  0-1之间随机数取法:dbms_random.value

解决方案 »

  1.   

        create or replace procedure PROC_COUNTER(COUNTER_I_DATE          IN DATE,
                                                 COUNTER_I_MONEY         IN NUMBER,
                                                 COUNTER_I_FROM_USERNAME IN VARCHAR2,
                                                 COUNTER_I_PASSWORD      IN VARCHAR2,
                                                 COUNTER_I_TO_USERNAME   IN VARCHAR2,
                                                 COUNTER_O_MESSAGE       OUT VARCHAR2) is
          c_confirm sys_refcursor;
          t_test counter%rowtype;
          n_count number := 0;
          c_date1 varchar2(32);
          c_date2 varchar2(32);
        begin
          open c_confirm for 'select * from counter where user_name = :a and user_password = :b'
            using COUNTER_I_FROM_USERNAME, COUNTER_I_PASSWORD;
          fetch c_confirm
            into t_test;
          if c_confirm%found then
            close c_confirm;
            open c_confirm for 'select * from counter where user_name = :a'
              using COUNTER_I_TO_USERNAME;
            fetch c_confirm
              into t_test;
            if c_confirm%found then
              close c_confirm;
              open c_confirm for 'select * from counter where user_name = :a and money-(:b)>=0 and money>=0'
                using COUNTER_I_FROM_USERNAME, COUNTER_I_MONEY;
              fetch c_confirm
                into t_test;
              if c_confirm%found then
                select count(*) into n_count from loging;
                c_date1 :=trim(to_char(sysdate,'dy'));
                c_date2 :=substr(to_char(sysdate,'yyyy-mm-dd'),10,1);
                if c_date2='5' or c_date1='星期五' then
                   COUNTER_O_MESSAGE := '今天不能进行划帐业务!';
                
                else 
                if n_count = 0 then
                
                  
                    update counter
                     set money = money - COUNTER_I_MONEY
                    where user_name = COUNTER_I_FROM_USERNAME;
                   
                    update counter
                     set money = money + COUNTER_I_MONEY
                   where user_name = COUNTER_I_TO_USERNAME;
                 
                  insert into loging
                  values
                    (sql001_seq.nextval,
                     COUNTER_I_FROM_USERNAME,
                     COUNTER_I_TO_USERNAME,
                     COUNTER_I_MONEY,
                     sysdate);
                    
                  COUNTER_O_MESSAGE := '划帐成功!';
                
                else
                   select count(*) into n_count from loging where 
                   to_char(trade_date,'yyyy-mm-dd') = to_char(sysdate,'yyyy-mm-dd') AND user_from_name=COUNTER_I_FROM_USERNAME;
                   if(n_count>=2) then
                    COUNTER_O_MESSAGE := '今天您已经操作两次,请明天再来!';
                   else
                       select count(*) into n_count from loging where 
                   to_char(trade_date,'yyyy-mm') = to_char(sysdate,'yyyy-mm') AND user_from_name=COUNTER_I_FROM_USERNAME;
                      if(n_count>=30) then
                       COUNTER_O_MESSAGE := '本月您已经操作三十次,请下月再来!';
                      else
                      
                     
                       update counter
                       set money = money - COUNTER_I_MONEY
                       where user_name = COUNTER_I_FROM_USERNAME;
                       
                       update counter
                       set money = money + COUNTER_I_MONEY
                       where user_name = COUNTER_I_TO_USERNAME;
                       
                       insert into loging
                       values
                       (sql001_seq.nextval,
                       COUNTER_I_FROM_USERNAME,
                       COUNTER_I_TO_USERNAME,
                       COUNTER_I_MONEY,
                       sysdate);
                     
                       COUNTER_O_MESSAGE := '划帐成功!';
                      end if;
                   end if;
                end if;
                
                end if;
              
              else
                COUNTER_O_MESSAGE := '帐户余额不足!';
                close c_confirm;
              end if;
            else
              COUNTER_O_MESSAGE := '划入帐户名字不正确!';
              close c_confirm;
            end if;
          else
            COUNTER_O_MESSAGE := '您输入的用户密码不正确!';
            close c_confirm;
          end if;
          commit;
        EXCEPTION
          WHEN OTHERS THEN
            rollback;
            COUNTER_O_MESSAGE := '不知道的错误!';
          
        end PROC_COUNTER;
      

  2.   

                          p_o_result  OUT test_cur)
        IS
          --临时变量,用于判断区间内是否有值
          num NUMBER(3);
        BEGIN
           --flag默认为无值    
          p_o_flag:=0;
           --判断区间内是否为空
               SELECT COUNT(page)
                 INTO num
                 FROM sql001
                WHERE page
              BETWEEN p_i_begin
                  AND p_i_end;
                  
              IF num>0  THEN 
              --flag为1
                  p_o_flag:=1;  
          --打开游标取值
                     OPEN p_o_result
                      FOR  
                         SELECT page
                           FROM sql001
                          WHERE page
                        BETWEEN p_i_begin
                            AND p_i_end
                       ORDER BY page ASC;
                      
                END IF;
             END proc_sel;
    END pkg_test;