更新一个或多个列时是否可以复制表中的所有值

时间:2018-08-23 20:36:19

标签: sql oracle

我有一个包含许多列的表,我想做的是复制表中的所有行,还要将其中一列更新为新值。

例如,可以说我有下表。我想将每行的副本添加到我的表中,除了不是BASIC访问,它将具有“ ADVANCED”:

之前:

NAME, GENDER, ACCESS
----------------------
STEVE, MALE, BASIC
MOLLY, FEMALE, BASIC

之后

NAME, GENDER, ACCESS
----------------------
STEVE, MALE, BASIC
MOLLY, FEMALE, BASIC
STEVE, MALE, ADVANCED
MOLLY, FEMALE, ADVANCED

有没有一种方法可以不指定所有列?表中有60列,并且结构可以更改(这意味着可以添加,删除,重命名列等)。

在Oracle SQL中是否可以自动执行此操作?

3 个答案:

答案 0 :(得分:2)

只需使用insert . . . select

insert into t (name, gender, access)
    select name, gender, 'ADVANCED'
    from t;

您需要列出所有列。您可以通过使用查询生成列表来缩短手动过程。如果您必须执行很多操作并且始终知道自己遗漏了access并且access是最后一列,则可以使用以下视图:

create view v_t as
    select . . . -- all but access
    from t;

insert into t ( . . . )
    select v.*, 'ADVANCED'
    from v_t;

或者您可以使用动态SQL生成语句。

但是,我不推荐其中任何一个。取而代之的是,我会担心要在其中定期添加和修改表中的列的数据模型。听起来很危险。

答案 1 :(得分:1)

是否不指定所有列?在“临时”表的帮助下,方法如下:

您当前的表格:

SQL> create table test
  2    (name varchar2(10),
  3     gender varchar2(20),
  4     caccess varchar2(20));

Table created.

SQL> insert into test
  2    select 'steve', 'male', 'basic' from dual union all
  3    select 'molly', 'female', 'basic' from dual;

2 rows created.
  • 创建一个“临时”表作为“原始”表的副本
  • 您要修改的更新列
  • 将整个“临时”表复制到“原始”
  • 删除“临时”表

SQL> create table test_temp as select * From test;

Table created.

SQL> update test_temp set caccess = 'advanced';

2 rows updated.

SQL> insert into test select * From test_temp;

2 rows created.

SQL> drop table test_Temp;

Table dropped.

SQL> select * From test;

NAME       GENDER               CACCESS
---------- -------------------- --------------------
steve      male                 basic
molly      female               basic
steve      male                 advanced
molly      female               advanced

SQL>

显然可以,但是-如果原始表很大怎么办?它占用大量空间,其副本占用的空间大约是原来的两倍。你为什么要这么做?

答案 2 :(得分:0)

尝试以下使用匿名块的方法来避免在插入语句中列出列

CREATE TABLE ACCESS_CHN
(NAAME VARCHAR2(100),
GENDER VARCHAR2(20),
ACCCESS VARCHAR2(30))

INSERT into ACCESS_CHN values('STEVE','MALE','BASIC');

INSERT into ACCESS_CHN values('MOLLY','FEMALE','BASIC');

COMMIT;

DECLARE

column_list varchar2(2000):=NULL;
plsql_block VARCHAR2(1000);

BEGIN

select LISTAGG(column_name,',') within group (order by column_id)
into column_list
from user_tab_columns
where table_name='ACCESS_CHN';

plsql_block :=  'CREATE TABLE ACCESS_CHN_BKP  as select '|| column_list || ' from ACCESS_CHN';

EXECUTE IMMEDIATE plsql_block;

plsql_block := 'UPDATE ACCESS_CHN_BKP  set ACCCESS=''ADVANCED'' ';

EXECUTE IMMEDIATE plsql_block;

COMMIT;

plsql_block :=  'CREATE TABLE ACCESS_CHN_FINAL  as select * from ACCESS_CHN
union all
select * from ACCESS_CHN_BKP';

EXECUTE IMMEDIATE plsql_block;

END;

--To rerun drop tables ACCESS_CHN_BKP and ACCESS_CHN_FINAL