Oracle XML 节点 增 删 改 全解析

 

Create Or Replace Procedure p_诊疗检查部位_Edit
(
  -------------------------------------------------------
  --功能:处理诊疗检查部位信息;
  --参数:如下
  --编制:王圣峰, 2010.07.10
 
  --修改人: 王圣峰 2010.09.10
  --原因   :方法改为XML方式解析
  -----------------------------------------------------
  操作_In   In Number, --1:增加;2:修改;3:删除
  类型_In   In 诊疗检查部位.类型%Type,
  原编码_In In 诊疗检查部位.编码%Type,
  新编码_In In 诊疗检查部位.编码%Type,
  名称_In   In 诊疗检查部位.名称%Type,
  分组_In   In 诊疗检查部位.分组%Type,
  备注_In   In 诊疗检查部位.备注%Type := Null,
  方法_In   In Sys.Xmltype
) Is
  -----1.互斥,2.互斥及附加,3,附加,4.共用. 四种类型的方法传入
  v_原名称          诊疗检查部位.名称%Type := Null;
  v_名称            Varchar2(100);
  v_可选            Char(1);
  v_造影            Char(1);
  v_标准方法        Varchar2(4000);
  v_应用方法        Varchar2(4000);
  n_Compsign        Number(10); --比较方法
  n_Count           Number(10); --循环应用方法次数
  v_应用方法_子方法 Varchar2(2000);
  n_标准造影        Char(1); --造影比较1
  n_应用造影        Char(1); --造影比较2
  --第几个方法组 值
  v_分组 Varchar2(30);
  n_分组 Number(2);
  --功能:根据传入的参数判断 字符是否是数字
  Function f_Is_Number(Num_In Varchar2) Return Number Is
    v_Sign Number;
  Begin
    v_Sign := To_Number(Nvl(Num_In, 'Var'));
    Return 1;
  Exception
    When Others Then
      Return - 1;
  End f_Is_Number;
Begin

  If 操作_In = 1 Then
    --分组前两位是否数字,第三是否 为  '-'
    Select Count(Distinct 分组) + 1 Into n_分组 From 诊疗检查部位 Where 类型 = 类型_In;
    If f_Is_Number(Substr(分组_In, 1, 2)) = 1 And Substr(分组_In, 3, 1) = '-' Then
      v_分组 := 分组_In;
    Else
      v_分组 := Lpad(n_分组, 2, '0') || '-' || 分组_In;
    End If;
    --检查方法 造影 上级 状态 序号
    Insert Into 诊疗检查部位 (类型, 编码, 名称, 分组, 备注, 方法) Values (类型_In, 新编码_In, 名称_In, v_分组, 备注_In, Null);
    Update 诊疗检查部位 Set 方法 = Xmltype('<methodset></methodset>') Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
    For r_Xmltab In (Select Extractvalue(Column_Value, '/ROW/检查方法') As 检查方法, Extractvalue(Column_Value, '/ROW/造影') As 造影,
                            Extractvalue(Column_Value, '/ROW/上级') As 上级, Extractvalue(Column_Value, '/ROW/状态') As 状态
                     From Table(Xmlsequence(Extract(方法_In, '/ROWSET/ROW')))) Loop
      ---查询出 名称可选 造影
      v_名称 := Replace(Replace(Trim(r_Xmltab.检查方法), '○', ''), '□', '');
      Select Decode(r_Xmltab.状态, '3', '1', '4', '1', '0') Into v_可选 From Dual;
      Select Decode(r_Xmltab.造影, '√', '1', '0') Into v_造影 From Dual;
      ---查询出 名称可选 造影
      If Nvl(r_Xmltab.上级, '0000') = '0000' Then
        Update 诊疗检查部位 a
        Set a.方法 = Insertchildxml(a.方法, '/methodset', 'method',
                                   Xmltype('<method><name>' || v_名称 || '</name><choice>' || v_可选 || '</choice><shadow>' || v_造影 || '</shadow></method>'))
        Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
      Else
        Update 诊疗检查部位 a
        Set a.方法 = Insertchildxml(a.方法, '/methodset//method[name="' || r_Xmltab.上级 || '"]', 'method',
                                   Xmltype('<method><name>' || v_名称 || '</name><choice>' || v_可选 || '</choice><shadow>' || v_造影 || '</shadow></method>'))
        Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
      End If;
    End Loop;
 
  Elsif 操作_In = 2 Then
    --分组前两位是否数字,第三是否 为  '-'
    Select Count(Distinct 分组) + 1 Into n_分组 From 诊疗检查部位 Where 类型 = 类型_In;
    If f_Is_Number(Substr(分组_In, 1, 2)) = 1 And Substr(分组_In, 3, 1) = '-' Then
      v_分组 := 分组_In;
    Else
      v_分组 := Lpad(n_分组, 2, '0') || '-' || 分组_In;
    End If;
    Begin
      Select 名称 Into v_原名称 From 诊疗检查部位 Where 编码 = 原编码_In And 类型 = 类型_In;
    Exception
      When Others Then
        Null;
    End;
    If v_原名称 Is Null Then
      Raise_Application_Error(-20102, '此检查部位方法已经删除[ZLSOFT]');
    End If;
    Update 诊疗检查部位 Set 编码 = 新编码_In, 名称 = 名称_In, 分组 = v_分组, 备注 = 备注_In Where 编码 = 原编码_In And 类型 = 类型_In;
    Update 诊疗检查部位 Set 方法 = Xmltype('<methodset></methodset>') Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
    --  commit;
    For r_Xmltab In (Select Extractvalue(Column_Value, '/ROW/检查方法') As 检查方法, Extractvalue(Column_Value, '/ROW/造影') As 造影,
                            Extractvalue(Column_Value, '/ROW/上级') As 上级, Extractvalue(Column_Value, '/ROW/状态') As 状态
                     From Table(Xmlsequence(Extract(方法_In, '/ROWSET/ROW')))) Loop
      ---查询出 名称可选 造影
      v_名称 := Replace(Replace(Trim(r_Xmltab.检查方法), '○', ''), '□', '');
      Select Decode(r_Xmltab.状态, '3', '1', '4', '1', '0') Into v_可选 From Dual;
      Select Decode(r_Xmltab.造影, '√', '1', '0') Into v_造影 From Dual;
      ---查询出 名称可选 造影
      If Nvl(r_Xmltab.上级, '0000') = '0000' Then
        Update 诊疗检查部位 a
        Set a.方法 = Insertchildxml(a.方法, '/methodset', 'method',
                                   Xmltype('<method><name>' || v_名称 || '</name><choice>' || v_可选 || '</choice><shadow>' || v_造影 || '</shadow></method>'))
        Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
      Else
        Update 诊疗检查部位 a
        Set a.方法 = Insertchildxml(a.方法, '/methodset//method[name="' || r_Xmltab.上级 || '"]', 'method',
                                   Xmltype('<method><name>' || v_名称 || '</name><choice>' || v_可选 || '</choice><shadow>' || v_造影 || '</shadow></method>'))
        Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
      End If;
    End Loop;
    --级联修改 [诊疗项目部位]
    For r_Used In (Select t.项目id, t.部位 From 诊疗项目部位 t Where t.部位 = v_原名称 And t.类型 = 类型_In) Loop
      --取出标准方法
      Select Substr(m.方法, 1, Length(m.方法) - 1)
      Into v_标准方法
      From (Select Replace(Replace(Xmlquery('for $i in /methodset/method return $i/name' Passing 方法 Returning Content).Getstringval(), '<name>', ''),
                             '</name>', ',') || Replace(Replace(Xmlquery('for $i in /methodset/method/method return $i/name' Passing 方法 Returning Content)
                                                                .Getstringval(), '<name>', ''), '</name>', ',') As 方法
             From 诊疗检查部位
             Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组) m;
      --取出标准方法
      --取出应用方法
      Select Substr(m.方法, 1, Length(m.方法) - 1)
      Into v_应用方法
      From (Select Replace(Replace(Xmlquery('for $i in /methodset/method return $i/name' Passing 方法 Returning Content).Getstringval(), '<name>', ''),
                             '</name>', ',') || Replace(Replace(Xmlquery('for $i in /methodset/method/method return $i/name' Passing 方法 Returning Content)
                                                                .Getstringval(), '<name>', ''), '</name>', ',') As 方法
             From 诊疗项目部位
             Where 部位 = v_原名称 And 类型 = 类型_In And 项目id = r_Used.项目id) m;
      --取出应用方法
      --循环比较 n_compSign
      Select Count(Column_Value) Into n_Count From Table(f_Split_String(v_应用方法, ','));
      For n_Index In 1 .. n_Count Loop
        Select a.Column_Value
        Into v_应用方法_子方法
        From (Select Rownum No, Column_Value From Table(f_Split_String(v_应用方法, ','))) a
        Where a.No = n_Index;
        n_Compsign := Instr(v_标准方法, v_应用方法_子方法);
        If n_Compsign = 0 Then
          Update 诊疗项目部位 t
          Set t.方法 = Deletexml(方法, '/methodset//method[name/text()="' || v_应用方法_子方法 || '"]')
          Where t.项目id = r_Used.项目id And t.部位 = r_Used.部位 And t.类型 = 类型_In;
        Else
          --是否造影的修正
          Select Extractvalue(方法, '/methodset//method[name/text()="' || v_应用方法_子方法 || '"]/shadow')
          Into n_应用造影
          From 诊疗项目部位 t
          Where t.项目id = r_Used.项目id And t.部位 = r_Used.部位 And t.类型 = 类型_In;
          Select Extractvalue(方法, '/methodset//method[name/text()="' || v_应用方法_子方法 || '"]/shadow')
          Into n_标准造影
          From 诊疗检查部位
          Where 编码 = 新编码_In And 类型 = 类型_In And 分组 = v_分组;
       
          If n_标准造影 <> n_应用造影 Then
            Update 诊疗项目部位 t
            Set t.方法 = Updatexml(t.方法, '/methodset//method[name="' || v_应用方法_子方法 || '"]/shadow/text()', n_标准造影)
            Where Existsnode(t.方法, '/methodset//method[name/text()="' || v_应用方法_子方法 || '"]') = 1 And t.项目id = r_Used.项目id And t.部位 = r_Used.部位 And
                  t.类型 = 类型_In;
          End If;
        End If;
      End Loop;
    End Loop;
  Elsif 操作_In = 3 Then
    --同步删除 诊疗项目部位方法
    Delete 诊疗项目部位 Where 类型 = 类型_In And 部位 = 名称_In;
    Delete 诊疗检查部位 Where 编码 = 原编码_In And 类型 = 类型_In;
  End If;
Exception
  When Others Then
    zl_ErrorCenter(SQLCODE, SQLERRM);
End p_诊疗检查部位_Edit;

-------删除带有某个节点信息的数据       --删除节点   
    Update 服务活动记录 a
    Set a.附加信息 = deleteXML(a.附加信息, '/ROWSET/ROW[病况变更时间/text()="' || to_char(d_变动时间, 'YYYY-MM-DD HH24:MI:SS') || '"]')
    Where a.个人id = 个人id_in And a.id = v_服务ID;

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

長安只在旧夢中

知识的大门打开后,才有真正机会

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值