您的位置:首页 > 数据库 > Oracle

Oracle关于创建存储过程权限问题以及带参数的游标的范例

2016-03-31 10:51 731 查看
由于公司的项目需要,创建了一个关于对表的字段动态增加的存储过程,用到了游标,带参数的游标,解决存储过程执行权限问题: AUTHID CURRENT_USER,看下面的代码:

create or replace procedure YS_CWYS_YSFZPZ(DIRCODE varchar2) AUTHID CURRENT_USER  as
/*********************************
名称:YS_CWYS_YSFZPZ
功能描述:修改财务预算配置表
参数:财务预算分类的CODE

修订记录:
版本号   编辑时间  编辑人  修改描述
1.0.0    2016-3-28  XXX  1.创建此存储过程

存储过程执行权限问题: AUTHID CURRENT_USER

入参出参描述:
DIRCODE 财务预算分类的编码
**********************************/
v_tablename varchar2(30);--表名
v_tableselect_sql varchar(200);--查询表名的SQL
v_table_bakname  varchar2(40); --备份表的表名
v_tablebak_sql varchar(200);--对表进行备份数据的SQL
v_droptable_sql varchar(200); --删除表的sql

v_column varchar(20); --字段别名
v_column_sql varchar(200);--拼装SQL
v_column_name  varchar(200);--中间变量
v_createtable_sql varchar(1000);--创建新表的SQL
v_inserttable_sql varchar(1000);--插入数据的SQL
v_createtablebak_sql varchar(1000);--创建备份表的SQL
v_droptablebak_sql varchar(200);--删除备份表
i  number;
v_cloumncount_sql  varchar(200);--统计字段总数SQL
v_cloumn_count number;--统计字段总数
v_alerttable_sql varchar(200); -- 设置主键
begin
v_column_sql:='';
v_cloumn_count:=0;
--通过CODE查询表名
v_tableselect_sql:= 'SELECT TABLENAME FROM ys_financialbudgetdir WHERE DIRCODE = '|| DIRCODE;
execute immediate v_tableselect_sql into v_tablename;
v_tablename:=UPPER(v_tablename);
v_table_bakname:= v_tablename ||'BAK';
v_tablebak_sql:=' INSERT INTO ' || v_table_bakname || ' SELECT * FROM ' ||v_tablename;
--执行备份
execute immediate v_tablebak_sql;

v_droptable_sql:='DROP TABLE '|| v_tablename;
--删除原有的表
execute immediate v_droptable_sql;

v_createtable_sql:= 'CREATE TABLE '|| v_tablename || '(ID   NUMBER(8) NOT NULL, TYPE  CHAR(2),';
v_createtablebak_sql:= 'CREATE TABLE '|| v_table_bakname || '(ID   NUMBER(8) NOT NULL, TYPE  CHAR(2),';

--定义配置表游标
DECLARE CURSOR cwpz_Cusor(C_DIRCODE VARCHAR2) IS SELECT CLOUMN FROM YS_FINANCIALCONFIG  WHERE  ISLEAF='1' and dircode = C_DIRCODE  ;

--开始使用游标取数据
BEGIN
OPEN cwpz_Cusor(DIRCODE);
LOOP
FETCH cwpz_Cusor INTO v_column;
--游标取不到数据则退出
EXIT WHEN cwpz_Cusor%NOTFOUND;
v_column_sql:= v_column_sql || v_column || ' VARCHAR2(200),';
END LOOP;
CLOSE cwpz_Cusor;
END;
v_createtable_sql:= v_createtable_sql || v_column_sql
|| ' orgid  NUMBER(8),year VARCHAR2(4),bscs  NUMBER(8), bsqj VARCHAR2(100),dirid  NUMBER(8), parentid NUMBER(8) )';

v_createtablebak_sql:= v_createtablebak_sql || v_column_sql
|| ' orgid  NUMBER(8),year VARCHAR2(4),bscs  NUMBER(8), bsqj VARCHAR2(100),dirid  NUMBER(8), parentid NUMBER(8) )';
--创建表
execute immediate v_createtable_sql;
--指定主键
v_alerttable_sql:= 'ALTER TABLE '||v_tablename||' ADD CONSTRAINT '||' PK_'||v_tablename ||' primary key (ID)';
execute immediate v_alerttable_sql;

--清空
v_column_sql:='';
--统计总数
v_cloumncount_sql:='SELECT count(column_name) count_num  FROM user_tab_columns  WHERE table_name ='''|| v_table_bakname||'''';
execute immediate v_cloumncount_sql into v_cloumn_count;

v_inserttable_sql:= 'INSERT INTO ' || v_tablename || ' (';
i:=0;
--定义备份表游标
DECLARE CURSOR cwys_Cusor(C_TABLENAME VARCHAR2) IS SELECT column_name FROM user_tab_columns  WHERE table_name = C_TABLENAME ;

--开始使用游标取数据
BEGIN
OPEN cwys_Cusor(v_table_bakname);
LOOP
i:=i+1;
FETCH cwys_Cusor INTO v_column_name;
--游标取不到数据则退出
EXIT WHEN cwys_Cusor%NOTFOUND;
if i=v_cloumn_count  then
v_column_sql:= v_column_sql|| v_column_name;
else
v_column_sql:= v_column_sql|| v_column_name || ',';
end if;
END LOOP;
CLOSE cwys_Cusor;
END;
v_inserttable_sql:= v_inserttable_sql || v_column_sql|| ') SELECT '||v_column_sql|| ' FROM '|| v_table_bakname;

dbms_output.put_line(v_inserttable_sql);
execute immediate v_inserttable_sql;

--删除备份表
v_droptablebak_sql:= 'DROP TABLE ' ||v_table_bakname;
execute immediate v_droptablebak_sql;

--创建备份表
execute immediate v_createtablebak_sql;

EXCEPTION
WHEN OTHERS THEN
--strErr := substr(sqlerrm,1,100);
ROLLBACK;
END YS_CWYS_YSFZPZ;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: