我想做一些非常简单的事情......让我举一个例子。 假设我有一个包含多个列的表,让我们调用其中一列“u”。此列只有3个不同的值即。 0,1和2。 我想创建三个额外的列u_0,u_1和u_2,如下所示:
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 :(得分: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 :(得分: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
当然,您可能需要对更多内容进行参数化(例如表名和列宽),但为了简单起见,我将其遗漏了。