0

私は本当に簡単なことをしようとしています...例を挙げましょう。いくつかの列を持つテーブルがあり、列の 1 つを「u」と呼びましょう。この列には 3 つの異なる値しかありません。0、1、および 2。次のように、u_0、u_1、および u_2 の 3 つの追加の列を作成します。

If u = 0, then u_0 = 1, u_1 = 0 and u_2 = 0
If u = 1, then u_0 = 0, u_1 = 1 and u_2 = 0
If u = 2, then u_0 = 0, u_1 = 0 and u_2 = 1

これはほんの一例です。u のようないくつかの列があり、3 つ以上の異なる値があり、そのようなすべての変数に対して同様の列の追加を行う必要があります。これを効率的に実行できるプログラムを Oracle PL/SQL で作成することは可能ですか? よろしくお願いします。

4

2 に答える 2

4

仮想列はどうですか?手動で追加する必要がありますが、値はプログラムで計算 (および更新) されます。

ALTER TABLE mytable ADD (u_0 NUMBER GENERATED ALWAYS
    AS (CASE u WHEN 0 THEN 1 ELSE 0 END) CHECK (u_0 IN (0,1)));
于 2013-01-12T08:09:25.240 に答える
1

次のストアドプロシージャは、必要なことを実行すると思います。

create or replace procedure expandcolumn 
(
  colname in varchar2  
) as 
  v_max integer;
  v_col_index integer := 0;
  v_sql_ddl varchar2(2000) := 'alter table demo add (';
  v_sql_update varchar2(2000) := 'update demo set ';
  v_sep varchar2(3) := ', ';
begin
  -- Retrieve the maximum value of the column so we know how many columns to add
  execute immediate 'select max(' || colname || ') from demo' into v_max;

  -- Starting from zero, prepare the DDL and UPDATE statements for each new column
  for v_col_index in 0..v_max loop
    if v_col_index = v_max then
      v_sep := null; -- We don't need a comma separator after the last column
    end if;

    v_sql_ddl := v_sql_ddl || colname || '_' || v_col_index || ' number(1)' || v_sep;
    v_sql_update := v_sql_update || colname || '_' || v_col_index ||
      '=decode(' || colname || ',' || v_col_index || ', 1, 0)' || v_sep;
  end loop;

  v_sql_ddl := v_sql_ddl || ')';

  execute immediate v_sql_ddl; -- Add the new columns to the demo table
  execute immediate v_sql_update; -- Set the new column values (implicit commit)
end expandcolumn;

複数列に拡張する元の列名で呼び出します。例:

create table demo (u number(1));
insert into demo values (0);
insert into demo values (2);
insert into demo values (1);
commit;
exec expandcolumn('U');
select * from demo;

         U        U_0        U_1        U_2
---------- ---------- ---------- ----------
         0          1          0          0
         2          0          0          1
         1          0          1          0

もちろん、より多くのもの(テーブル名や列幅など)をパラメーター化する必要がありますが、簡単にするためにそれらを省略しました。

于 2013-01-12T12:08:29.423 に答える