Sql 在更新一个或多个列时,是否可以复制表中的所有值
我有一个包含许多列的表,我想做的是复制表中的所有行,同时将其中一列更新为新值 例如,假设我有下表。我想向我的表中添加每一行的副本,除了基本访问之外,它将具有“高级”: 之前:Sql 在更新一个或多个列时,是否可以复制表中的所有值,sql,oracle,Sql,Oracle,我有一个包含许多列的表,我想做的是复制表中的所有行,同时将其中一列更新为新值 例如,假设我有下表。我想向我的表中添加每一行的副本,除了基本访问之外,它将具有“高级”: 之前: NAME, GENDER, ACCESS ---------------------- STEVE, MALE, BASIC MOLLY, FEMALE, BASIC 之后 NAME, GENDER, ACCESS ---------------------- STEVE, MALE, BASIC MOLLY, FEMA
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中是否可以自动执行此操作?只需使用
插入。选择
:
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生成语句
但是,我不推荐任何一种。相反,我关心的是一个数据模型,您可以在其中定期添加和修改表中的列。听起来很危险。只要使用
插入。选择
:
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生成语句
但是,我不推荐任何一种。相反,我关心的是一个数据模型,您可以在其中定期添加和修改表中的列。听起来很危险。不指定所有列?在“临时”表格的帮助下,以下是如何: 您当前的表格:
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
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.
- 创建一个“临时”表作为“原始”表的副本
- 更新要修改的列
- 将整个“临时”表复制到“原始”表
- 删除“临时”表
显然,这是可行的,但是——如果原来的桌子很大呢?它占用了大量的空间,而且它的副本占用了大约两倍的空间。无论如何,为什么要这样做?尝试下面的匿名块方法,以避免在insert语句中列出列
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
请使用匿名块尝试下面的方法,以避免在insert语句中列出列
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
不要混淆Oracle SQL和PL/SQL;PL/SQL完全是另一回事,与您的问题无关。我会在这方面编辑你的帖子。好吧,假设你今天做“这个”。(“这意味着在更改访问权限时复制现有行。)明天,您将向表中添加1000行。如果您无意识地再次应用该过程,那么您将得到重复的旧行,其中
ACCESS='ADVANCED'
。这就是你想要的吗?您确定您考虑过多次这样做的未来副作用吗?不要将Oracle SQL与PL/SQL混淆;PL/SQL完全是另一回事,与您的问题无关。我会在这方面编辑你的帖子。好吧,假设你今天做“这个”。(“这意味着在更改访问权限时复制现有行。)明天,您将向表中添加1000行。如果您无意识地再次应用该过程,那么您将得到重复的旧行,其中ACCESS='ADVANCED'
。这就是你想要的吗?你确定你考虑过多次这样做的未来副作用吗?如前所述,我想在不指定所有列的情况下执行此操作,因为该表有近60列。如前所述,我想在不指定所有列的情况下执行此操作,因为该表有近60列。是,我曾想过这样做,但正如你所说,似乎有很多额外的数据写入到数据库中。我真的希望Oracle有类似于google SQL支持的SELECT*REPLACE的东西。听起来好像不是。我查看了你发布的链接;是的,看起来是个不错的选择。不过,据我所知,Oracle没有。是的,我曾考虑过这样做,但正如你所说,似乎有很多额外的数据写入到数据库中。我真的希望Oracle有类似于google SQL支持的SELECT*REPLACE的东西。听起来好像不是。我查看了你发布的链接;是的,看起来是个不错的选择。不过,据我所知,甲骨文没有。