如何在oracle中使用存储过程创建表,如果存在就先删除

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在oracle中使用存储过程创建表,如果存在就先删除相关的知识,希望对你有一定的参考价值。

这个是我写的:创建存储过程
create or replace procedure createTable
(tname varchar2,createSql varchar2,dropSql varchar2)
is
vcount number(9);
begin
SELECT COUNT(*) INTO vcount FROM tabs WHERE table_name=tname;
if vcount>0 then
execute immediate dropSql;
else
execute immediate createSql;
end if;
end;
调用存储过程
declare
createSql varchar2(100):='create table java7
(
a number(8) primary key,b varchar2(20)
)';
dropSql varchar2(100):='DROP TABLE java7';
begin
createTable('JAVA7',createSql,dropSql);
end;

创建没有问题,但是在调用的是出现错误,没有权限,请教高人指点

如果是没有权限的话,照这下面做就OK了:
grant sysdba, dba, create session, create any table , create any view , create any index , create any procedure ,
   alter any table , alter any procedure , drop any table , drop any view , drop any index , drop any procedure ,
   select any table , insert any table , update any table , delete any table
   to test_data(数据库用户名);
首先我觉得你的逻辑有问题,既然数据库里面存在了表你就删除,但是你却把创建表的执行代码写在了else 条件里面;那意思如果数据库存在了你要创建的这张表,你的逻辑只是把它删除,但是却没有创建。
下面是我整理的代码你看看:

create or replace procedure createtable(
tname varchar2
)
is
v_createsql varchar2(400);
v_dropsql varchar2(100);
v_count number(9);
begin

v_createsql:='create table '||tname||'(
a number(8) primary key,
b varchar2(20))';
v_dropsql:='drop table '||tname||' cascade constraints';
select count(*) into v_count from user_tables where table_name=upper('java7');
if v_count>0 then
execute immediate v_dropsql;
commit;
end if;

execute immediate v_createsql;
commit;
end;

begin
createtable('java7');
end;

-- select * from java7
参考技术A 没有权限?具体点 或者贴图!
不过应该是没有create table和drop table的权限吧,你试试赋下给此用户看看追问

没有啊 dba的权限呢

参考技术B 存储过程里面有些关键字是不让出现的 比如create 你自己看下资料

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。

每次编译的时候在insert语句出都会出现找不到表的数据,如果用EXCUSE IMMEDIATE来插入能编译过去,但是执行的时候会出错,提示“列在此处不允许”。有高人给我的例子吗。

不知道楼主的需求如何
一般没必要创建临时表,处理数据后又它drop。
存储过程中要用到的表应该会经常用到。就让它存在吧,用完用 truncate table 清理数据就可以了。
空表不会占很多资源。 我们就是这样做的。追问

如果不删除表的话多用户操作会不会出现问题。我这样做也就是防止这一点。

追答

多用户操作确实会出问题。
可以在临时表里面加一个批次标志字段,每次运行存储过程插入数据时加上批次标志,处理后将此批次的数据删除就可以,不用truncate table,这样就不会影响到其它会话调用存储过程。

参考技术A Oracle 的临时表的 处理机制, 和 SQL Server 的不一样。

假如你的临时表的结构不是每次执行都发生变化的话
那么就是事先 通过 CREATE GLOBAL TEMPORARY TABLE 语句,把临时表建立好。
存储过程里面,就根据需要, 执行 INSERT / SELECT 之类的操作就可以了。
至于什么事情清理临时表的数据,就取决于你的临时表是 基于会话的临时表 还是 基于事务的临时表 了。

假如你的临时表的结构是每次执行都有可能发生变化的,没办法,必须动态创建的话......
这个我暂时还没学到那么透彻。

参考资料:http://hi.baidu.com/wangzhiqing999/blog/item/b390c139012393e03c6d9756.html

参考技术B create procduce test
is
isql varchar2(200);
dptable varchar2(100):='drop table test';
begin
isql:='create global temporary table test (sid int,sname varchar2(20)) on commit delete rows';
execute immediate isql; --创建临时表
insert into test values (1,'abc');
execute immediate dptable; ---删除临时表
end;

-------------------
对于oracle 临时表在存储过程中调用,我是觉得这视乎没什么意义,oracle 提供在数据库里预定义临时表,只有在调用的时候才会在临时表空间里分配空间,也就是说你可以提前在数据库里创建临时表,然后再到存储过程里直接调用临时表就行了
参考技术C 我现在和你遇到一模一样的问题,应该是你动态拼sql的时候出的问题,类似下面 sqls:='INSERT INTO temp_sc_gds_product_spec
(ID, CREATE_TIME,
SPEC_ID,
SPEC_VALUE_ID,
GOODS_ID,
PRODUCT_ID
)
VALUES
(UUID(), sysdate, ' || '''' || specId ||'''' ||','|| '''' || strIndexSubstr ||'''' ||','|| '''' || goodsId || '''' || ',' ||'''' || productId || '''' || ')';
参考技术D 见图,直接不能回复

以上是关于如何在oracle中使用存储过程创建表,如果存在就先删除的主要内容,如果未能解决你的问题,请参考以下文章

在oracle中创建带参存储过程,传进去的参数可以为空么?在存储过程中要如何判断传进来的值是不是为空。

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。

oracle 的存储过程中 动态的创建一张表 然后插入一个变量到这个表中,表能动态的创建但是变量不能插入进去

oracle存储过程中临时表的使用,该怎么处理

oracle存储过程中临时表的使用,该怎么处理

Oracle存储过程的语法分析