`

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

阅读更多
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语句拿出来将参数替换成值执行了一下.又可以正常运行..

是什么原因呢?

分享到:
评论
2 楼 neitnaco 2007-11-05  
引用

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

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

本人还有一个问题:
我这个存储过程大致意思就是根据一个会计科目从本年的所有账目当中去遍历属于该会计科目的金额信息.但是现在遇到一个问题就是我会计科目有3000个.然后每次都需要去遍历固定的一个数据集合(本年所作的所有账目).大概数据再5000条左右. .也就是查询数据库3000*5000...一个存储过程执行完大概要个1分多种..现在有22个单位.也就是22*1分钟..起码也得22分钟执行存储过程..效率问题问问该怎么 解决..苦恼中...
1 楼 movingboy 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.


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

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

相关推荐

    select into和insert into select使用方法

    - **使用场景**:这段示例代码首先定义了一个名为`EmployeeSales`的新表,然后使用`INSERT INTO SELECT FROM`从多个表中选择符合条件的数据,并将其插入到`EmployeeSales`表中。 - **注意事项**: - 在实际应用中,...

    SQL SERVER:把表里的数据导出成为INSERT INTO脚本的存储过程

    根据提供的文件信息,我们可以构建一个详细的SQL Server存储过程来实现将表中的数据转换为`INSERT INTO`脚本的功能。此存储过程将适用于多种数据类型,并能够动态生成插入语句,以便用户可以方便地导出数据作为脚本...

    sap常用函数集合.rar

    11. **LOOP AT...INTO...**:用于遍历内部表,例如,`LOOP AT lt_table INTO ls_data`,每次循环将内部表的一个行复制到`ls_data`中。 12. **CALL TRANSACTION** 语句:用于调用SAP标准事务代码,如`CALL ...

    MySQL存储过程练习.pdf

    - 在实际编码时,错误处理是存储过程开发中非常重要的一个部分。需要考虑到各种边界情况,以及可能发生的异常,并进行相应的处理。 通过这些知识点,我们可以看到MySQL存储过程不仅可以用于简单的查询,还可以执行...

    存储过程-02.03.存储过程常用操作

    在SQL中,我们可以使用`CREATE PROCEDURE`语句定义一个存储过程。例如,创建一个名为`InsertEmployee`的存储过程,用于插入员工数据: ```sql CREATE PROCEDURE InsertEmployee @EmployeeID INT, @Name VARCHAR...

    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句详解(SQL数据库和Oracle数据库的区别)

    在SQL中,表复制是常见的数据操作,主要...`INSERT INTO SELECT` 是一个通用的语句,可以在多种数据库中用于将数据从一个或多个源表复制到已存在的目标表。在实际应用中,应根据具体的数据库环境和需求选择合适的语句。

    存储过程入门到精通

    INSERT INTO OrderDetails (OrderId, ItemId, Quantity) VALUES (@OrderId, (SELECT ItemId FROM Orders WHERE OrderId = @OrderId), 1); COMMIT; CATCH ROLLBACK; THROW; END; ``` **3. 安全性增强** - **...

    (实验C8 存储过程).doc

    - **执行前**:确认数据库中没有这个存储过程。 - **执行后**:验证存储过程是否成功创建,并能正确执行插入操作。 - **删除存储过程proc_insert**: - **删除语法**: ```sql DROP PROC proc_insert; ``` - ...

    T-sql教程资源下载

    - 创建一个没有输入参数的存储过程。 - 示例: `CREATE PROCEDURE p_list_students AS SELECT * FROM students` **34. 创建带输入参数的存储过程** - 创建带有输入参数的存储过程。 - 示例: `CREATE PROCEDURE p_...

    用java调用oracle存储过程总结.docx

    SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1; END TESTB; ``` **Java调用示例**: 1. **引入必要的包**同上。 2. **建立数据库连接**同上。 3. **创建CallableStatement并设置参数**: - 创建...

    java类实现导出各种数据库insert语句.pdf

    `SELECT * FROM` 是一个通用查询所有列的语句,而`INSERT INTO` 和 `VALUES` 用于构建插入数据的语句。 4. 处理结果集(ResultSet):`ResultSet` 是执行SQL查询后返回的结果对象,它包含了一组记录。`...

    DB2数据库存储过程入门

    创建一个DB2存储过程可以通过DB2开发中心进行,步骤包括: - 新建项目并连接到目标数据库。 - 右键点击选择“新建存储过程”,可以选择直接创建或使用向导辅助创建。 - 定义存储过程的基本结构,如示例所示: `...

    利用SQL语句插入批量数据.rar

    5. **使用存储过程**:对于更复杂的批量插入,可以创建一个存储过程来执行一系列的INSERT语句,这在处理大量数据或者需要事务控制时非常有用。例如,在MySQL中,你可以这样定义一个存储过程: ```sql CREATE ...

    oracle存储过程语法[参照].pdf

    在Oracle数据库管理系统中,存储过程是一种预编译的SQL和PL/SQL代码集合,用于执行特定任务。它们可以提高性能、减少网络流量,并提供封装和模块化的编程方式。以下是对"oracle存储过程语法[参照].pdf"文件中提到的...

    Procedure存储过程.docx

    `pro_select`存储过程演示了如何创建一个查询数据的存储过程。它接受一个输入参数`v_id`,并返回对应的`name`。使用`SELECT INTO`将查询结果存入变量`v_name`,然后使用`DBMS_OUTPUT.PUT_LINE`显示结果。 5. **...

    数据库技术与应用:实验五 视图_存储过程和触发器.docx

    ### 数据库技术与应用:实验五 视图、存储过程和触发器 #### 视图的定义与查询 1. **定义视图** 在本实验中,首先定义了一个名为`ViewA`的视图,该视图的目的是为了查询`UNIVERSITY`数据库中的选课记录,具体...

    sqlserver导出insert语句的存储过程

    本篇文章详细介绍了一个名为 `dataToSQLScript` 的存储过程,该过程能够帮助用户实现这一目标。 #### 存储过程 `dataToSQLScript` 此存储过程的调用方式如下: ```sql EXEC dataToSQLScript @tablename; ``` ...

Global site tag (gtag.js) - Google Analytics