创建生成级联上级字符的函数
admin
2023-05-09 00:20:53
0


需求:现有表dw,里面字段bm(编码),sj(上级编码),

      新增字段px,要求在新字段中添加字符串,字符串为单位的级联上级及自身,

并从顶向下,从左到右排序,中间以“|”分割。

     如:单位代码为005,上级单位代码为004,

         单位004的上级单位单面是003,单位003的上级代码是002,

         单位002的上级是最上级单位001。

         则取出数据应为:"001|002|003|004|005"



实现:


1  首先取得某一单位的级联上级的数据 

   可以通过sql:

select sj  

  from dw T  

  START WITH T.bm=:BM  

  CONNECT BY PRIOR T.sjbm=T.bm ;


取出该单位的所有级联上级的单位编码


2  通过管道函数能列出某个单位的级联单位代码及自身单位代码并返回结果集 



create or replace FUNCTION                                                   upbm

(

  bm_IN IN VARCHAR2 

  

)  RETURN bm_DATA pipelined   

-----通过单位编码和单位分类取得上级单位编码(包括自己)数据集 

  AS 

  bm_ROW yly_row_type;

  bm_TAB bm_DATA;

  BEGIN 

  FOR MYROW IN (

  select sjbm  

  from dw T  

  START WITH T.bm=bm_IN   

  CONNECT BY PRIOR T.sj=T.bm 

  UNION ALL 

  SELECT bm 

  FROM dw 

  WHERE bm=bm_IN 

  ORDER BY 1

  ) LOOP 

  bm_ROW := YLY_ROW_TYPE(MYROW.sj);

  PIPE ROW (bm_ROW);

  END LOOP; 

  RETURN;

  END upbm; 


 这时通过select * from table(getupperdeptwitchself(:bm)),取得数据集。


001

002

003

004

005


3  通过函数把取得的数据集转换为一行 

   可以通过wm_concat函数,该函数把输入的结果集转换为1行并以","分割,需要转换为"|"


create or replace FUNCTION                                    upbm_px

(

  bm_IN IN VARCHAR2 

   

) RETURN VARCHAR2 AS 

 px VARCHAR2(400);

BEGIN 

  SELECT replace(wm_concat(bm),',','|') INTO px from table(upbm(bm_IN)); 

  RETURN px;

END upbm_px;



这时通过函数即可得到一行数据:

    select GET_UPPERDEPT_PX(bm) from dual;


得到数据: "001|002|003|004|005"



这时已基本完成需求。

接下来制作触发器,使表在插入时自动生成sjbm_xp数据。


4 创建触发器


create or replace TRIGGER "dw_SJ_TRG" 

  before insert on dw 

  for each row  

declare

begin  

--插入数据时生成px字段

  :NEW.px :=upbm_px(:NEW.bm); 

end;



但是在插入时报错:ORA-04091:表dw发生了变化 触发器/函数不能读表 


问题原因:oracle执行DML语句时需要显示进行提交操作。当我们进行插入时会触发触发器

         执行对触发器作用表和扩展表,但这时触发器和插入表在同一事物中,插入语句

没有提交时无法对触发器表进行额外操作。 


解决方法:

        把触发器改为显示提交


create or replace TRIGGER "dw_SJ_TRG" 

  before insert on dw 

  for each row  

declare

pragma autonomous_transaction;

 

begin  

--插入数据时生成px字段

  :NEW.px :=GET_UPPERDEPT_PX(:NEW.bm); 

  commit;

end;



5  全表更新


  把表dw的所有行的px字段补全 


UPDATE dw SET px=GET_UPPERDEPT_PX(bm);


这时报错:ORA-04091:表dw发生了变化 触发器/函数不能读表

错误原因与刚刚类似:

要更新的表是dw,取得结果集的函数upbm依靠dw进行循环计算,

    而更新之后循环的来源已经产生变化,ORACLE不允许这样,可能会产生无限循环。


解决办法: 创建新表数据dw_BAK与dw表一致,把upbm函数中的

  来源表从dw改为dw_BAK.


        执行语句 UPDATE dw SET px=GET_UPPERDEPT_PX(bm);

提交后把函数upbm的来源改回dw.


相关内容

热门资讯

以军士兵集体丢掉武器抗命,大喊... 据凤凰卫视报道,以色列国防军一军事基地7月30日发生士兵抗命事件,约120名士兵抗议指挥官做法,将武...
蒋成华任商务部副部长 国务院任免国家工作人员。任命蒋成华为商务部副部长。免去蒋成华的商务部国际贸易谈判副代表职务。
伊朗驻华大使:在军事威胁下,不... 新华社北京7月31日电(记者刁慧琳) 伊朗驻华大使法兹里7月28日表示,伊美回到谈判桌的前提是美国必...
伊朗革命卫队在霍尔木兹海峡击中... 当地时间31日,伊朗伊斯兰革命卫队发布声明称,革命卫队海军当天在霍尔木兹海峡击中并扣留了两艘违反禁令...
美媒:特朗普,遇到了一个更强硬... 据《纽约时报》7月29日报道,就在特朗普总统看似放弃战事升级计划几天后,美国再次与伊朗交火。上周末,...
女子做气管镜时不幸身亡,丈夫称... 7月29日,西安刘先生反映妻子在当地医院做支气管镜检查时死亡,看监控时发现医生疑有违规操作。刘先生表...
全网“帮卖西瓜”,然后呢? 近日,河南部分地区西瓜滞销的消息在网上热度很高。很多地方也伸出援手:有景区收购千斤西瓜、免费赠予游客...
美媒:乌克兰袭击伊朗船只,险引... 据《纽约时报》7月28日报道,据伊朗和西方官员称,伊朗曾考虑攻击乌克兰的一个港口,以报复乌克兰对一艘...
20年里,他只画美女,用东方风... 迈进KIM在上海的工作室,迎面是一整墙的美女们。她们像是刚从一场时髦的沙龙里退场,或倚或立,眉宇间是...
Google在港推出AI代理G... 观点网讯:7月29日,Google在香港推出AI代理Gemini Spark,该代理可全天候在后台运...