Как динамически создать таблицу с динамическим типом данных из процедуры PL / SQL - PullRequest
0 голосов
/ 25 марта 2010
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; 

Есть ли лучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 25 марта 2010

Если я правильно читаю, похоже, что вы хотите создать новую таблицу, содержащую один столбец для каждого почтового индекса.

Я думаю, что ответ, который вы придумали, является наилучшим из возможных способов достижения поставленных целей. Я хотел бы добавить, что вы, вероятно, захотите отсортировать курсор, используемый для цикла, который будет гарантировать, что столбцы всегда в том же порядке.

Однако ваша цель весьма подозрительна. Возможно, лучше сделать шаг назад и подумать, действительно ли создание этой таблицы является правильным решением вашей проблемы. Похоже, что это огромная де-нормализация и будет кошмаром для поддержания. Не зная, почему вы используете этот подход, я не могу предложить лучшего решения, но, тем не менее, я думаю, что, вероятно, есть одно.

0 голосов
/ 25 марта 2010

Почему бы вам не создать представление для таблицы, которая содержит только те столбцы с почтовым индексом?

create or replace view Zip_View as
select * from test1
where test1.zip is not null;

Таким образом, вам не нужно копировать данные. Или каковы ваши точные требования?

...