使用存储过程创建其信息存储在另一个表中的表

时间:2016-07-19 16:19:12

标签: sql oracle plsql

我需要编写一个存储过程来创建表,其table_name,column_name,data_type等信息存储在另一个表中,如下图所示...

table details

无需担心Primary n外键规范。 是否可以在ORACLE中执行此操作?

先谢谢。

2 个答案:

答案 0 :(得分:0)

是。在循环中构造DDL字符串并使用execute immediate执行它。

例如:

begin
    for r in (
        select 'create table ' || td.table_name || chr(10)||'( ' ||
               listagg(rpad(td.column_name,31) || td.data_type, chr(10)||', ') within group (order by id) ||
               ' )' as create_table
        from table_definitions td
        group by td.id, td.table_name
        order by td.id
    )
    loop
        dbms_output.put_line(r.create_table || ';' || chr(10));
        execute immediate r.create_table;
    end loop;
end;

演示设置:

create table table_definitions
( id integer   not null
, table_name   varchar2(30) not null
, column_name  varchar2(30) not null, data_type varchar2(30) not null
, constraint   tabdef_uk unique (table_name, column_name) );

insert all
into table_definitions values (1, 'EMP', 'EMP_ID', 'NUMBER')
into table_definitions values (1, 'EMP', 'EMP_NAME', 'VARCHAR2(30)')
into table_definitions values (1, 'EMP', 'SALARY', 'NUMBER')
into table_definitions values (1, 'EMP', 'DEPT_ID', 'NUMBER')
into table_definitions values (2, 'DEPT', 'DEPT_ID', 'NUMBER')
into table_definitions values (2, 'DEPT', 'DEPT_NAME', 'VARCHAR2(30)')
into table_definitions values (2, 'DEPT', 'LOCATION', 'VARCHAR2(30)')
select * from dual;

然而,这整个方法存在一些问题。

我必须为VARCHAR2列添加长度。如果您不希望每个数字列都使用普通NUMBER,则需要为其他人执行相同的操作。此外,没有列排序,因此可以按任何顺序生成它们。我无法看到id列的目的 - 它是{@ 1}}中唯一的还是唯一的?并且没有table_name,默认值等的规定。

如果我在系统中遇到这个问题,我会非常紧张。它的用途是什么?

答案 1 :(得分:0)

我相信会有更好的方法,但同时你可以开展以下工作:

你的proc代码应该是这样的:

select distinct id, table_name 
bulk collect into ip_id, ip_tab_name
from tab_details; 

for x in ip_id.first .. ip_id.last loop

select column_name, data_type bulk collect into v_col_name,
v_data_type from tab_Details where id= ip_id(x);

v_sql := 'create table ' || ip_tab_name(x) || ' ( col1 number) ';

execute immediate v_sql;

for i in v_col_name.first .. v_col_name.last  loop

v_sql1 := 'alter table ' || ip_tab_name(x) || ' add ' || v_col_name(i)
|| '  ' || v_data_type(i);

execute immediate v_sql1;

end loop; -- (for i loop)

v_sql2 := 'alter table ' || ip_tab_name(x) || ' drop column col1 ';

execute immediate v_sql2;

end loop;-- (for x loop)