日期:2014-05-17  浏览次数:20881 次

oracle存储过程中临时表的使用
我想完成一个存储过程 实现创建临时表 插入数据 查询结果(以游标返回) 删除临时表的操作 代码如下 不知道问题在哪?
貌似在用循环插入数据时就出错了,这里我是要用循环插入数据的,要通过筛选数据 不能直接

CREATE GLOBAL TEMPORARY TABLE TEMP_STUDENTINFO ON COMMIT PRESERVE ROWS as select * from table;

代码如下

create or replace procedure sys_Operation_Select
(
  V_CX out SYS_REFCURSOR
)
as
  V_SqlString varchar2(2000);
  CURSOR cur_opt IS select * from sys_Operation;
begin
  V_SqlString:='CREATE GLOBAL TEMPORARY TABLE temp_DomainOperation (
  ID VARCHAR2(36),
  OperationDomain VARCHAR2(36),
  Name varchar2(50),
  Father varchar2(36),
  URL varchar2(200),
  Target varchar2(50),
  ICON varchar2(50),
  Seq integer,
  Memo varchar(50)
  ) ON COMMIT PRESERVE ROWS';
  execute immediate V_SqlString;
   
  FOR v_opt IN cur_opt LOOP
  V_SqlString:=' insert into temp_DomainOperation values (v_opt.id,v_opt.operationdomain,v_opt.name,v_opt.father,v_opt.url,v_opt.target,v_opt.Icon,v_opt.seq,v_opt.memo)';
  DBMS_OUTPUT.PUT_LINE(V_SqlString);
  execute immediate V_SqlString;
  END LOOP;
   
  V_SqlString:=' select * from TEMP_DOMAINOPERATION';
  open V_CX for V_SqlString;
   
  V_SqlString:='drop table temp_DomainOperation';
  execute immediate V_SqlString;

end sys_Operation_Select;

------解决方案--------------------
1、oracle临时表不要这样使用,oracle临时表不同于其它数据库的临时表,如果sqlserver;oracle临时表的特点时数据临时。
2、要使用临时表,事先建立好临时表就行了,并由oracle自己去处理并发就行了,并且每个会话的数据是互不影响的。
3、在万不得已的情况下,尽量不要使用动态SQL,因为其性能比静态SQL低。
--建立临时表
CREATE GLOBAL TEMPORARY TABLE temp_DomainOperation(
 ID VARCHAR2(36),
 OperationDomain VARCHAR2(36),
Name varchar2(50),
Father varchar2(36),
URL varchar2(200),
Target varchar2(50),
ICON varchar2(50),
Seq integer,
Memo varchar(50)
) ON COMMIT PRESERVE ROWS;
--建立存储过程
CREATE OR REPLACE PROCEDURE sys_Operation_Select(V_CX OUT SYS_REFCURSOR)
AUTHID CURRENT_USER AS
V_SqlString VARCHAR2(2000);
CURSOR cur_opt IS
SELECT * FROM sys_Operation;
BEGIN

FOR v_opt IN cur_opt LOOP
V_SqlString := 'insert into temp_DomainOperation values (:id,:operationdomain,:name,:father,:url,:target,:Icon,:seq,:memo)';
DBMS_OUTPUT.PUT_LINE(V_SqlString);
EXECUTE IMMEDIATE V_SqlString
USING v_opt.id, v_opt.operationdomain, v_opt.name, v_opt.father, v_opt.url, v_opt.target, v_opt.Icon, v_opt.seq, v_opt.memo;
END LOOP;

V_SqlString := ' select * from TEMP_DOMAINOPERATION';
OPEN V_CX FOR V_SqlString;

END sys_Operation_Select;