oracle10g根据select语句得到字段名、主键、唯一等

建立package,包含用到的自定义类型和存储过程

create or replace package pkg_getViewFieldList is
--自定义cursor,允许动态游标,否则不允许
type cur_rs_type is ref cursor;

procedure proc_ins_rs(
   sTBTableNames varchar2, --以逗号为分隔符的包含所有表名的表名

   sTBCols varchar2, --存储所有列名的表名
   sTBRs varchar2, --结果集
   sTableView varchar2 --创建的视图名
);

--存储过程
procedure proc_oraGetViewFieldList
(
  sTableView varchar2,
  sOraSelect varchar2,
  sTableNames varchar2,
  cur out cur_rs_type
) ;
end pkg_getViewFieldList;

package body中的内容,即存储过程的实现

create or replace package body pkg_getViewFieldList
as
procedure proc_oraGetViewFieldList
(
  sTableView varchar2,
  sOraSelect varchar2,
  sTableNames varchar2,
  cur out cur_rs_type
)
as
/******************************************************************************
**  Name: [sp_GetViewFieldList]
**  Desc: 查询待添加视图的字段的属性信息(类型 大小等)
**
**
**  Return Values:
**
**  Parameters:
** 临时表名
** select语句
*******************************************************************************/
sTmp varchar2(4000):='';
 begin

--分隔表名字符串,得到所有的表名,并创建表,包含所有的表名
--sTmp := 'drop table tmpTableName'||sTableView;
--execute immediate sTmp;

sTmp :='create table tmpTableName'||sTableView||'
 as SELECT REGEXP_SUBSTR ('''||sTableNames||''', ''[^,]+'', 1,rownum) tableName
FROM DUAL
CONNECT BY ROWNUM <=
LENGTH ('''||sTableNames||''') - LENGTH (REPLACE ('''||sTableNames||''', '','', ''''))+1';

dbms_output.put_line('split by , ');
--执行
execute immediate sTmp;

--创建一个结果集,包括列名、类型、主键、唯一等
--sTmp := 'drop table rsTable'||sTableView;
--execute immediate sTmp;

sTmp :='create table rsTable'||sTableView||'
      (FieldName varchar2(100),FieldIsIdentity varchar2(10),
      FieldIsPrimary varchar2(10), FieldType varchar2(100),
      FieldLength varchar2(100), FieldPrecision varchar2(100),
      FieldScale varchar2(100)) ';
dbms_output.put_line('exec rsTable');
--执行创建结果集
execute immediate sTmp;

--创建一个视图,为后面的获取sSQLSelect中的列作准备
--sTmp  :=  'drop view tmpView'||sTableView;
--execute immediate sTmp;

sTmp :='create view ' || sTableView || ' as ' || sOraSelect;
dbms_output.put_line('exec tmpView');
--执行创建视图
execute immediate sTmp;

--获取sSQLSelect中包含的所有列表,创建临时表
--sTmp := 'drop table tmpCols'||sTableView;
--execute immediate sTmp;

sTmp :='create table tmpCols'||sTableView||' as
     select a.column_name from user_tab_cols a, user_objects b
      where a.table_name=b.object_name and b.object_type = ''VIEW''
      and b.object_name=upper('''||sTableView||''')';
dbms_output.put_line('exec tmpCols');
execute immediate sTmp;
--执行函数,获得结果集
--遍历列,判断每一列是否在各个表中
--如果存在,进行下一次循环,否则逐个判断每一个表

proc_ins_rs('tmpTableName'||sTableView,
                           'tmpCols'||sTableView,
                           'rsTable'||sTableView,
                           sTableView);
                          
 open cur for 'select * from rsTable'||sTableView;
                          
--dbms_output.put_line('cur rows = '||cur%rowcount);

--删除所有临时表
dbms_output.put_line('drop tables');
sTmp := 'drop view '||  sTableView;
--execute immediate sTmp;
sTmp := 'drop table tmpTableName'||  sTableView;
--execute immediate sTmp;
sTmp := 'drop table tmpCols'||  sTableView;
--execute immediate sTmp;
sTmp := 'drop table rsTable'||  sTableView;
--execute immediate sTmp;

end proc_oragetviewfieldlist;


procedure proc_ins_rs
(
   sTBTableNames varchar2,
   sTBCols varchar2,
   sTBRs varchar2,
   sTableView varchar2 --创建的视图名
)

is
   tmpColsCur cur_rs_type;
   tmpTableCur cur_rs_type;
   tmpCol varchar2(100):='';
   tmpTable varchar2(100):='';
   tbCount int := ''; --表名数
   sTmp varchar2(4000):='';
   sTmpCol varchar2(100):='';
   sTmpTable varchar2(100):='';
   colExist int :=0; --列是否存在的标示,0不存在,1存在
   nCol int :=0;
   nTable int :=0;
   rsColExist int :=0; --结果集中是否有此字段的信息,0不存在,1存在
begin
--声明包含所有列和所有表的游标
--sTmpCol := ||'';
dbms_output.put_line('stbCols = '||sTBCols);
dbms_output.put_line('sTBTableNames = '||sTBTableNames);

open tmpColsCur for 'select * from '||sTBCols;
sTmpTable := 'select * from '||sTBTableNames||'';
--open tmpTableCur for 'select * from '||sTBTableNames;

--打开游标
--open tmpColsCur;
dbms_output.put_line('tmpColsCur open ');

--开始循环
loop
  <<nextCol>>
  --从游标中取记录,放入临时列中
  fetch tmpColsCur into tmpCol;
  --针对每一列,遍历所有表,判断是否在表中
  exit when tmpColsCur%notfound;
 
  dbms_output.put_line('tmpCol = '||tmpCol);
  --打开表游标
   open tmpTableCur for sTmpTable;
  loop
    --从table游标中取记录
     <<nextTable>>
      fetch tmpTableCur into tmpTable;
      exit when tmpTableCur%notfound;
     
       select count(column_name) into colExist from user_tab_cols
           where table_name=upper(''||tmpTable||'')
           and column_name=upper(''||tmpCol||'');
          
           dbms_output.put_line('colExist = '||colExist);
           --如果列存在本表中,则colExist为1,将列的信息插入到结果集中
        if colExist > 0
          then
           -- colExist := 1;
            --检查rs结果集中是否有该字段的信息,若有,则rsColExist=1
           -- select count(FieldName) into rsColExist
           --  from '||sTBRs||'
           --  where FieldName = upper(''||tmpCol||'');
            -- execute immediate sTmp;
            
             --if rsColExist = 0
            --   then
            sTmp := 'insert into '||sTBRs||'
 select distinct a.COLUMN_NAME FieldName,
case when
  exists(select h.COLUMN_NAME from all_indexes g
  inner join all_ind_columns h on g.INDEX_NAME = h.INDEX_NAME
  where a.COLUMN_NAME = h.COLUMN_NAME and g.UNIQUENESS = ''UNIQUE''
   and h.column_name = upper('''||tmpCol||''')
    and h.TABLE_NAME = a.TABLE_NAME )
  then ''1''
    else ''0''
     end FieldIsIdentity,
case when
  exists(select e.COLUMN_NAME from user_cons_columns e
  inner join user_constraints f on e.TABLE_NAME = f.TABLE_NAME
  where e.TABLE_NAME=a.TABLE_NAME 
   and f.CONSTRAINT_TYPE = ''P''
    and e.COLUMN_NAME = upper('''||tmpCol||'''))
  then ''1''
    else ''0''
     end FieldIsPrimary,
a.DATA_TYPE FieldType,
a.DATA_LENGTH FieldLength,
  a.DATA_PRECISION FieldPrecision,
  a.DATA_SCALE FieldScale
 from user_tab_columns a, user_constraints b, user_cons_columns c,user_tab_comments d
 where b.CONSTRAINT_NAME = c.CONSTRAINT_NAME
 and d.TABLE_NAME = a.TABLE_NAME
 and a.column_name = upper('''||tmpCol||''')
 and a.table_name = upper('''||sTableView||''')' ;
 
                  execute immediate sTmp;
                  close tmpTableCur;     
            goto nextCol;
          --  end if;
            else --当前列不在当前表中,查看下一张表
              colExist := 0;
              goto nexttable;
          end if;
      end loop;
     
end loop;

--关闭游标
if tmpColsCur%isOpen
  then
    close tmpColsCur;
    end if;

if tmpTableCur%isOpen
  then
    close tmpTableCur;
    end if;  
   
--sTmp :='select * from '||sTBRs||'';
--open rsCur for sTmp;
--dbms_output.put_line('rsCur rows = '||rsCur%rowcount);
--return rsCur;
end proc_ins_rs;
end pkg_getViewFieldList;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值