CREATE OR REPLACE PROCEDURE p_create_dynamic_table IS
v_qry_str VARCHAR2 (100);
v_data_type VARCHAR2 (30);
BEGIN
SELECT data_type || '(' || data_length || ')'
INTO v_data_type
FROM all_tab_columns
WHERE table_name = 'TEST1' AND column_name = 'ZIP';
FOR sql_stmt IN (SELECT * FROM test1 WHERE zip IS NOT NULL)
LOOP
IF v_qry_str IS NOT NULL THEN
v_qry_str := v_qry_str || ',' || 'zip_' || sql_stmt.zip || ' ' ||v_data_type;
ELSE
v_qry_str := 'zip_' || sql_stmt.zip || ' ' || v_data_type;
END IF;
END LOOP;
IF v_qry_str IS NOT NULL THEN
v_qry_str := 'create table test2 ( ' || v_qry_str || ' )';
END IF;
EXECUTE IMMEDIATE v_qry_str;
COMMIT;
END p_create_dynamic_table;
有没有更好的方法呢?
答案 0 :(得分:1)
如果我正确阅读,您似乎想要为每个邮政编码创建一个包含一列的新表。
我认为您提出的答案是实现既定目标的最佳方式。我想补充一点,你可能想要对用于循环的游标进行排序,这将确保列总是以相同的顺序。
但是,你的目标非常可疑。退一步考虑创建此表是否真的是解决问题的正确方法可能会更好。这似乎是一次大规模的非正常化,并将成为维持的噩梦。不知道为什么你采用这种方法我不能提供更好的解决方案,但是,尽管如此,我认为可能还有一个。
答案 1 :(得分:0)
为什么不在表上创建一个视图,该视图仅包含带有zip的那些列?
create or replace view Zip_View as
select * from test1
where test1.zip is not null;
这样您就不需要复制数据了。或者您的具体要求是什么?