`

存储过程(数组参数、for循环、拼接的动态sql游标、merge into)

 
阅读更多
create or replace procedure SFGL_XF_ONE_ADD(p_njdm   in varchar2,
                                        p_yxdm   in varchar2,
                                         p_zydm   in varchar2,
                                         p_fy     in varchar2,
                                         p_czr    in varchar2,
                                         o_errMsg out varchar2) is
  /**
  *  生成单个年级专业学费
  *  功能:遍历当前年级的学院专业的学生把每个学生需要缴纳的学费保存到应缴费用表,
           如果该学生的学费已经存在于应缴费用表中则更新,否则插入,同时更新当前学生的学费         

  *  2015年11月1日
  *   p_njdm 年级代码
  *   p_yxdm 院系代码
  *   p_zydm 专业代码
  *   p_fy 住宿费用
  *   p_czr 当前操作人
  *   o_errMsg 返回出错信息
  */

begin
  for xsxx_rec in (SELECT * FROM SFGL_XSXX WHERE nj = p_njdm and yxdm = p_yxdm and zydm = p_zydm) loop
  
      merge into SFGL_YJFY a
        using (SELECT xsxx_rec.xsid xsid, p_njdm ||p_yxdm||p_zydm||'xf' scm, '1' lx FROM dual) b
        on (a.YJYH = b.xsid and a.SCM = b.scm and a.FYLX = b.lx)
        when matched then
          update set a.FY = p_fy,a.modified_time = sysdate,a.modified_by = p_czr  --更新费用,修改时间,修改人
        
        when not matched then
          insert
            (a.YJFYID,a.FYMC,a.FY,a.FYLX,a.YJYH,a.SCM,
            a.modified_Time,a.modified_By,a.create_Time,a.create_By,a.bz)
          values
            (XL_SFGL_YJFY.NEXTVAL,p_njdm ||'年'||xsxx_rec.yxmc||xsxx_rec.zymc||'学费',p_fy,'1',xsxx_rec.xsid,p_njdm ||p_yxdm||p_zydm||'xf',
            sysdate,p_czr,sysdate,p_czr,null); --插入应缴费用表
      
        update SFGL_XSXX set xf = p_fy WHERE XSID = xsxx_rec.xsid; --更新学生信息表'学费'字段
  
  end loop;
exception
  when others then
    o_errMsg := '程序运行出现内部错误,请联系管理员。';
    raise;
end SFGL_XF_ONE_ADD;

 

create or replace procedure SFGL_XF_All_ADD(p_njdmAttr   in type_varchar,
                                         p_czr    in varchar2,
                                         o_errMsg out varchar2) is
  /**
  *  生成全部学费
  *  功能:根据选择的年级生成全部的学费,遍历当前年级的学院专业的学生把每个学生需要缴纳的学费保存到应缴费用表,
           如果该学生的学费已经存在于应缴费用表中则更新,否则插入,同时更新当前学生的学费         

  *  2015年11月1日
  *   p_njdmAttr 年级代码数组
  *   p_czr 当前操作人
  *   o_errMsg 返回出错信息
  */

begin
--循环需要生成的年级
  for i in 1..p_njdmAttr.Count loop 
  --根据年级查找学费表
    for xf_rec in (SELECT * FROM SFGL_XF WHERE nj = p_njdmAttr(i)) loop 
    --根据年级、院系、专业查找学生信息,然后遍历这些学生查看在应缴费用表中是否已经存在,存在则更新,不存在插入;
    --最后更新这个学生的学费字段
      for xsxx_rec in (SELECT * FROM SFGL_XSXX WHERE nj = xf_rec.nj and yxdm = xf_rec.yxdm and zydm = xf_rec.zydm) loop
      
          merge into SFGL_YJFY a
            using (SELECT xsxx_rec.xsid xsid, xsxx_rec.nj ||xsxx_rec.yxdm||xsxx_rec.zydm|| 'xf' scm, '1' lx FROM dual) b
            on (a.YJYH = b.xsid and a.SCM = b.scm and a.FYLX = b.lx)
            when matched then
              update set a.FY = xf_rec.fy,a.modified_time = sysdate,a.modified_by = p_czr --学生信息已经存在,更新应缴费用表中的费用,修改时间,修改人
            
            when not matched then
              insert
                (a.YJFYID,a.FYMC,a.FY,a.FYLX,a.YJYH,a.SCM,
                a.modified_Time,a.modified_By,a.create_Time,a.create_By,a.bz)
              values
                (XL_SFGL_YJFY.NEXTVAL,xsxx_rec.nj ||'年'||xsxx_rec.yxmc||xsxx_rec.zymc||'学费',xf_rec.fy,'1',xsxx_rec.xsid,xsxx_rec.nj ||xsxx_rec.yxdm||xsxx_rec.zydm|| 'xf',
                sysdate,p_czr,sysdate,p_czr,null); --学生信息不已经存在应缴费用表中,插入
          
            update SFGL_XSXX set xf = xf_rec.fy WHERE XSID = xsxx_rec.xsid; --更新学生信息表'学费'字段
      
      end loop;
     end loop;
  end loop;
exception
  when others then
    o_errMsg := '程序运行出现内部错误,请联系管理员。';
    raise;
end SFGL_XF_All_ADD;

 

create or replace procedure SFGL_QTFY_XS(p_njdm   in varchar2,
                                         p_xqdm   in varchar2,
                                         p_dwh    in varchar2,
                                         p_zydm   in varchar2,
                                         p_bjdm   in varchar2,
                                         p_xh     in varchar2,
                                         p_qtfyid     in varchar2,
                                         p_fymc   in varchar2,
                                         p_fy     in varchar2,
                                         p_czr    in varchar2,
                                         o_errMsg out varchar2) is
  /**
  *  生成其他费用(学生类型)
  *  功能:根据查询条件遍历学生把每个学生需要缴纳的其他费用保存到应缴费用表,
           如果该学生的其他费用已经存在于应缴费用表中则更新,否则插入,同时更新当前学生的其他费用
  

  *  2015年11月6日
  *   p_njdm 年级代码
  *   p_xqdm 校区代码
  *   p_dwh 院系代码
  *   p_zydm 专业代码
  *   p_bjdm 班级代码
  *   p_xh 教务学号
  *   p_qtfyid 其他费用主键
  *   p_fymc 费用名称
  *   p_fy 费用
  *   p_czr 当前操作人
  *   o_errMsg 返回出错信息
  */

  v_sql STRING(3000);  --存放查询语句

  TYPE cur_type IS REF CURSOR; --创建学生信息的动态游标,根据查询条件生成相应的游标
  xsxx_cur cur_type;
  xsxx_rec SFGL_XSXX%rowtype; --创建与SFGL_XSXX相同类型的临时集合

begin
  --根据查询条件初始化的游标语句
  v_sql := 'select * FROM SFGL_XSXX where 1=1 and nj = ''' || p_njdm || '''';
  if p_xqdm is not null then
    v_sql := v_sql || ' and xqdm = ''' || p_xqdm || '''';
  end if;
  if p_dwh is not null then
    v_sql := v_sql || ' and yxdm = ''' || p_dwh || '''';
  end if;
  if p_zydm is not null then
    v_sql := v_sql || ' and zydm = ''' || p_zydm || '''';
  end if;
  if p_bjdm is not null then
    v_sql := v_sql || ' and bjdm = ''' || p_bjdm || '''';
  end if;
  if p_xh is not null then
    v_sql := v_sql || ' and xh = ''' || p_xh || '''';
  end if;
  /*dbms_output.put_line('查询语句:'||v_sql);*/

  --打开学生信息游标
  open xsxx_cur for v_sql;
  loop
    fetch xsxx_cur into xsxx_rec; --把游标的值放到xsxx_rec临时集合
    exit when xsxx_cur%notfound;
  
    merge into SFGL_YJFY a
    using (SELECT xsxx_rec.xsid xsid, p_njdm ||p_qtfyid|| 'xsqtfy' scm, '4' lx FROM dual) b
    on (a.YJYH = b.xsid and a.SCM = b.scm and a.FYLX = b.lx)
    when matched then
      update set a.FY = p_fy, a.modified_time = sysdate, a.modified_by = p_czr --更新费用,修改时间,修改人
      
    when not matched then
      insert(a.YJFYID,a.FYMC,a.FY,a.FYLX,a.YJYH,a.SCM,a.modified_Time,a.modified_By,a.create_Time,a.create_By,a.bz)
      values
        (XL_SFGL_YJFY.NEXTVAL,p_fymc || '学生其他费用',p_fy,'4',xsxx_rec.xsid,p_njdm ||p_qtfyid|| 'xsqtfy',sysdate,p_czr,
         sysdate,p_czr,null); --插入应缴费用表
  
    update SFGL_XSXX set qtfy = p_fy WHERE XSID = xsxx_rec.xsid; --更新学生信息表'其他费用'字段
  
  end loop;
  close xsxx_cur;
exception
  when others then
    o_errMsg := '程序运行出现内部错误,请联系管理员。';
    raise;
end SFGL_QTFY_XS;

 

p_njdmAttr   in type_varchar 这是定义的数组类型

 

CREATE OR REPLACE TYPE "TYPE_VARCHAR" AS TABLE OF VARCHAR2(200)



 
--创建一个collection类型,用于格式化输出,主要应用于存储过程传入数组类型参数。

分享到:
评论

相关推荐

    整理:oracle pl/sql 入门+ 数组使用+游标+动态SQL

    在这个“整理:Oracle PL/SQL 入门+数组使用+游标+动态SQL”文档中,我们将深入探讨这四个关键概念。 1. Oracle PL/SQL入门: - PL/SQL的基本结构:PL/SQL由声明部分、执行部分和异常处理部分组成,用于定义变量、...

    静态、动态sql及各种游标

    静态、动态SQL及各种游标 静态SQL和动态SQL是两种不同的SQL语句执行方式,分别应用于不同的场景中。静态SQL是指在PL/SQL中直接运行的SQL语句,没有什么特别之处。动态SQL则是指利用EXECUTE IMMEDIATE语句执行的SQL...

    sql语句拼接+游标技术

    sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术sql语句拼接+游标技术

    DB2游标及动态SQL

    ### DB2游标及动态SQL详解 #### 一、DB2游标概念与使用 **1.1 游标简介** 在DB2中,游标是一种用于遍历查询结果集的强大工具。它允许用户一行一行地处理数据,这对于需要逐行处理数据的应用场景非常有用。游标通常...

    SQL游标使用例子--有注释

    ### SQL游标使用详解 #### 一、引言 在SQL编程中,游标是一种用于处理查询结果集的工具,可以实现对数据行的逐行访问。本文将通过一个具体的示例来详细介绍如何使用SQL游标,并解释其背后的原理与应用场景。 ####...

    SQL游标原理和使用方法.doc

    `Transact-SQL`游标主要用于服务器上,通过从客户端发送给服务器的`Transact-SQL`语句或者是在存储过程、触发器中的`Transact-SQL`进行管理。这类游标不支持提取数据块或多行数据。 ##### 3.2 API服务器游标 API...

    Sqlserver游标拼接

    Sqlserver游标拼接学习,简单的游标学习,直接exec执行查看结果

    利用SQL游标存储过程分页方案

    利用SQL游标存储过程分页方案,以前用过,应该还行

    SQL游标小计

    SQL游标小计

    SqlServer存储过程游标

    ### SqlServer 存储过程与游标应用实例详解 #### 一、存储过程概述 在SQL Server中,存储过程是一种预编译的SQL语句集合,它可以被当作一个单独的对象来调用。存储过程可以提高应用程序性能,简化复杂的业务逻辑,...

    SQL语句\sql 游标总结

    游标提供了一种从表中检索数据并进行操作的灵活手段,主要用在服务器上,处理由客户端发送给服务器端的 SQL 语句,或是批处理、存储过程、触发器中的数据处理请求。 1. 游标的概念 游标的优点在于它可以定位到结果...

    Mysql游标(循环操作)

    ### MySQL游标(循环操作) #### 一、游标简介 在MySQL中,游标是一种数据库对象,主要用于处理存储过程中的结果集。游标允许我们逐行地读取查询结果,这对于需要对每一行数据执行特定操作的情况非常有用。通过...

    sql 存储过程常用函数及游标用法

    本文将深入探讨SQL存储过程中的常用函数、游标用法以及日期函数。 一、字符函数 字符函数主要用于对字符串进行各种操作。例如: 1. `LEN(str)`:返回字符串`str`的长度。 2. `SUBSTRING(str, start, length)`:从...

    SQL经典游标使用方法

    例如,可以使用存储过程、递归查询或者窗口函数来替代游标。 综上所述,理解并熟练掌握SQL游标是提升数据库操作能力的重要步骤。通过游标,我们可以实现更加灵活和精细的数据处理,但也需要注意在性能和灵活性之间...

    SQL游标实例

    SQL游标是数据库管理系统中一个重要的概念,它允许程序员或数据库管理员逐行处理查询结果集,而不仅仅是一次性处理整个结果集。在处理大量数据或需要按特定顺序执行操作时,游标显得尤为有用。本篇文章将深入探讨SQL...

    SQL游标原理和使用方法

    SQL游标是数据库管理系统中一个重要的概念,它允许程序员按需逐行处理查询结果,而不仅仅是一次性获取所有数据。在数据库编程中,特别是在处理大量数据或进行复杂事务时,游标显得尤为有用。本文将详细讲解SQL游标的...

    sql 游标详解

    - 注意:游标中不能使用`COMPUTE`、`COMPUTE BY`、`FOR BROWSE`、`INTO`等语句。 - **`READONLY`**:禁止通过游标更新数据。 - **`UPDATE [OF column_name[, n]]`**:指定游标中可以被更新的列。 #### 四、扩展的...

    sqlserver游标存储过程的使用

    本篇文章将深入探讨SQL Server中游标的使用,以及如何在存储过程中集成游标。 首先,我们需要了解游标的几个基本概念: 1. 游标的类型:包括静态、动态、键集和只进。静态游标在打开时加载所有数据,数据更改不会...

    sql存储过程和游标的运用

    SQL存储过程和游标的运用 SQL存储过程和游标是SQL语言中两个非常重要的概念,它们可以帮助开发者更好地管理和处理数据。在本节中,我们将详细介绍存储过程和游标的基本概念和应用。 什么是存储过程 存储过程是一...

Global site tag (gtag.js) - Google Analytics