论坛首页 入门技术论坛

一个存储过程[insert into ... select * from ...]执行报错误

浏览 4838 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-02  
sql 代码
  1. create or replace procedure GETREMAIN_JSZX1(   
  2. P_SETID IN NUMBER,                --帐套   
  3. P_YEAR IN NUMBER,                 --年度   
  4. P_MONTH IN NUMBER,                --月份   
  5. P_UNITID IN VARCHAR2,             --乡镇编号   
  6. P_EID IN Varchar2,                --单位   
  7. P_SID IN Varchar2)                --会计科目   
  8.   
  9. Is  
  10.   
  11. PA_YEAR NUMBER;   
  12.   
  13. Begin  
  14.   
  15. PA_YEAR := P_YEAR+1;   
  16.   
  17. If P_SID='1' Then  
  18.   
  19. INSERT INTO REMAIN (   
  20.   
  21. SELECT SETID,PA_YEAR AS YEAR,UNITID,   
  22. SEQ_REMAIN_ID.NEXTVAL AS ID,   
  23. SID,P_EID AS EID,'' AS BID,   
  24. '' AS IID,BAL00,0 AS ISPLAN,'' AS ENAME,'' AS BNAME,'' AS INAME   
  25. From  
  26. (   
  27. SELECT SETID,YEAR,UNITID,   
  28. PID,SID,NAME AS SNAME,DEBCRE,ISLEAF,NVL(BAL00+(DEBMONEY_TOT-CREMONEY_TOT)*DEBCRE,0) AS BAL00   
  29. FROM(   
  30. SELECT SETID,YEAR,UNITID,SID,NAME  
  31. ,(CASE WHEN DEBCRE='1' THEN 1 ELSE -1 ENDAS DEBCRE   
  32. ,ISLEAF,PID   
  33. ,NVL(COUNTLEDGER('1','2','1',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS DEBMONEY_TOT   
  34. ,NVL(COUNTLEDGER('1','2','2',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS CREMONEY_TOT   
  35. ,NVL(COUNTREMAIN(P_UNITID,P_SETID,P_YEAR,TRIM(SID),P_EID,TRIM(''),TRIM('')),0) AS BAL00   
  36. FROM  
  37. (   
  38. SELECT SETID,YEAR,UNITID,SID,NAME,DEBCRE,ISLEAF,PID   
  39. FROM ACCOUNTSECTIONS   
  40. WHERE  
  41. SID<>'0.' AND  UNITID=P_UNITID AND SETID=P_SETID AND YEAR=P_YEAR   
  42. And SID Like '1%'   
  43. AND ISLEAF=1 AND ENABLED=1   
  44. ORDER BY ID1,ID2,ID3,ID4,ID5,ID6   
  45. )   
  46. )   
  47. where BAL00<>0   
  48. );   
  49.   
  50. Elsif P_SID = '1,2' Then    
  51.   
  52. INSERT INTO REMAIN (   
  53.   
  54. SELECT SETID,PA_YEAR AS YEAR,UNITID,   
  55. SEQ_REMAIN_ID.NEXTVAL AS ID,   
  56. SID,P_EID AS EID,'' AS BID,   
  57. '' AS IID,BAL00,0 AS ISPLAN,'' AS ENAME,'' AS BNAME,'' AS INAME   
  58. From  
  59. (   
  60. SELECT SETID,YEAR,UNITID,   
  61. PID,SID,NAME AS SNAME,DEBCRE,ISLEAF,NVL(BAL00+(DEBMONEY_TOT-CREMONEY_TOT)*DEBCRE,0) AS BAL00   
  62. FROM(   
  63. SELECT SETID,YEAR,UNITID,SID,NAME  
  64. ,(CASE WHEN DEBCRE='1' THEN 1 ELSE -1 ENDAS DEBCRE   
  65. ,ISLEAF,PID   
  66. ,NVL(COUNTLEDGER('1','2','1',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS DEBMONEY_TOT   
  67. ,NVL(COUNTLEDGER('1','2','2',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS CREMONEY_TOT   
  68. ,NVL(COUNTREMAIN(P_UNITID,P_SETID,P_YEAR,TRIM(SID),P_EID,TRIM(''),TRIM('')),0) AS BAL00   
  69. FROM  
  70. (   
  71. SELECT SETID,YEAR,UNITID,SID,NAME,DEBCRE,ISLEAF,PID   
  72. FROM ACCOUNTSECTIONS   
  73. WHERE  
  74. SID<>'0.' AND  UNITID=P_UNITID AND SETID=P_SETID AND YEAR=P_YEAR   
  75. And (SID Like '1%' OR SID LIKE '2%')   
  76. AND ISLEAF=1 AND ENABLED=1   
  77. ORDER BY ID1,ID2,ID3,ID4,ID5,ID6   
  78. )   
  79. )   
  80. where BAL00<>0   
  81. );   
  82.   
  83. Elsif P_SID = '1,2,3' Then  
  84.   
  85. INSERT INTO REMAIN   
  86.   
  87. (SETID,Year,UNITID,ID,SID,EID,BID,IID,BAL00,ISPLAN,ENAME,BNAME,INAME)   
  88.     
  89.  (   
  90.   
  91. SELECT SETID,PA_YEAR AS YEAR,UNITID,   
  92. SEQ_REMAIN_ID.NEXTVAL AS ID,   
  93. SID,P_EID AS EID,'' AS BID,   
  94. '' AS IID,BAL00,0 AS ISPLAN,'' AS ENAME,'' AS BNAME,'' AS INAME   
  95. From  
  96. (   
  97. SELECT SETID,YEAR,UNITID,   
  98. PID,SID,NAME AS SNAME,DEBCRE,ISLEAF,NVL(BAL00+(DEBMONEY_TOT-CREMONEY_TOT)*DEBCRE,0) AS BAL00   
  99. FROM(   
  100. SELECT SETID,YEAR,UNITID,SID,NAME  
  101. ,(CASE WHEN DEBCRE='1' THEN 1 ELSE -1 ENDAS DEBCRE   
  102. ,ISLEAF,PID   
  103. ,NVL(COUNTLEDGER('1','2','1',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS DEBMONEY_TOT   
  104. ,NVL(COUNTLEDGER('1','2','2',P_UNITID,P_SETID,P_YEAR,P_MONTH,TRIM(SID),TRIM(P_EID),TRIM(''),TRIM('')),0) AS CREMONEY_TOT   
  105. ,NVL(COUNTREMAIN(P_UNITID,P_SETID,P_YEAR,TRIM(SID),P_EID,TRIM(''),TRIM('')),0) AS BAL00   
  106. FROM  
  107. (   
  108. SELECT SETID,YEAR,UNITID,SID,NAME,DEBCRE,ISLEAF,PID   
  109. FROM ACCOUNTSECTIONS   
  110. WHERE  
  111. SID<>'0.' AND  UNITID=P_UNITID AND SETID=P_SETID AND YEAR=P_YEAR   
  112. And (SID Like '1%' OR SID LIKE '2%' OR SID LIKE '3%')   
  113. AND ISLEAF=1 AND ENABLED=1   
  114. ORDER BY ID1,ID2,ID3,ID4,ID5,ID6   
  115. )   
  116. )   
  117. where BAL00<>0   
  118. );   
  119. commit;   
  120.   
  121. End If;   
  122.   
  123. end GETREMAIN_JSZX1;   

 

我在

exec Getremain_Jszx1(2,2007,12,'1004','100.','1,2,3');

报错误..

错误信息为:

sql 代码
  1. ORA-04091: 表 XZKJ.REMAIN 发生了变化,触发器/函数不能读   
  2. ORA-06512: 在"XZKJ.COUNTREMAIN", line 37   
  3. ORA-06512: 在"XZKJ.GETREMAIN_JSZX1", line 85   
  4. ORA-06512: 在line 1  

但是我把存储过程里面的sql语句拿出来将参数替换成值执行了一下.又可以正常运行..

是什么原因呢?

   发表时间:2007-11-02  
下面是Oracle联机帮助中关于ORA-04091错误的说明和建议:
引用
ORA-04091 table string.string is mutating, trigger/function may not see it

Cause: A trigger (or a user defined PL/SQL function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.

Action: Rewrite the trigger (or function) so it does not read that table.


也可以采用另一种办法:重写你的存储过程,在调用出错的函数之前不要改动/锁定该函数要访问的表的数据

另外看你的代码好辛苦~~~
0 请登录后投票
   发表时间:2007-11-05  
引用

另外看你的代码好辛苦~~~

唉.本来就是循环遍历的一个过程.我上面的错误原因找到了.是由于我下面用到的函数跟上面要插入的表是同一个表.
谢谢楼上的兄弟哈.

本人还有一个问题:
我这个存储过程大致意思就是根据一个会计科目从本年的所有账目当中去遍历属于该会计科目的金额信息.但是现在遇到一个问题就是我会计科目有3000个.然后每次都需要去遍历固定的一个数据集合(本年所作的所有账目).大概数据再5000条左右. .也就是查询数据库3000*5000...一个存储过程执行完大概要个1分多种..现在有22个单位.也就是22*1分钟..起码也得22分钟执行存储过程..效率问题问问该怎么 解决..苦恼中...
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics