我需要编写一个存储过程来创建表,其table_name,column_name,data_type等信息存储在另一个表中,如下图所示...
无需担心Primary n外键规范。 是否可以在ORACLE中执行此操作?
先谢谢。
答案 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)