2013-01-12 88 views
0

我正在嘗試做一些非常簡單的事情......讓我舉一個例子。 假設我有一個有多列的表格,讓我們調用其中一列「u」。這個列只有3個不同的值, 0,1和2。 我想創建附加的三列U_0,U_1和U_2如下:以編程方式將列添加到Oracle表中

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這樣的列,有三個以上不同的值,我需要爲所有這些變量做相似的列添加。 是否可以在Oracle PL/SQL中編寫一個程序,它可以有效地執行此操作? 感謝和問候, Dibyendu

+0

我不認爲有一個簡單的方法來做到這一點,並有充分的理由。 Oracle具有「立即執行」語句,但不允許DDL。 DDL需要隱式提交。爲什麼不寫一個sqlplus腳本呢? – OldProgrammer

+1

@LeorA - 立即執行確實可以與DDL一起工作。例如,'begin execute immediate'create table test1(a number)';結束;'。 Dibyendu - 這些色譜柱需要更換多久?你只需要創建一次列? U_0,U_1和U_2中的值是否需要與U的更改保持一致? –

+0

讓我們假設這些值永遠不會改變......我只需要創建一次額外的列。祝好,Dibyendu –

回答

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))); 
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 

當然,你可能會需要更多的參數化的東西(如表名和列寬),但我已經離開了那些爲了簡單起見。

相關問題