【问题标题】:Oracle 11g: add a column to an EXISTING table with auto increment long valueOracle 11g:将一列添加到具有自动递增长值的 EXISTING 表
【发布时间】:2017-05-21 00:08:42
【问题描述】:

我有一个表格,比如 Name,(为简单起见,我简化了示例)。该表已经存在,并且有数据。现在,我需要向它添加一个 long 类型的 ID 列,并且需要使值自动递增。

对于 Oracle 12c,这很容易,始终作为身份生成

但是,我在 Oracle 11g 上工作,不支持这样的功能。所以我需要创建一个触发器,如本文所述:How to create id with AUTO_INCREMENT on Oracle?

alter table name add (id integer);

create sequence name_seq;

create or replace trigger name_bir;   
before insert on name
for each row
begin
 select name_seq.NEXTVAL
 into :new.id
 from dual;
end;

但是,该解决方案(创建序列,然后在插入/更新时触发)仅在插入新行时才有效。它不适用于表中的现有行。

如果有任何建议,我将不胜感激。基本上,我需要 existingnewly-inserted 行来为我新添加的列 ID 设置新的 ID 值。

==============================

解决方案(从答案中收集):

  1. 使用“a_horse_with_no_name”发布的“update”语句更新现有行

  2. 对于将要插入的任何新行,仍然需要上述触发器。

【问题讨论】:

  • 创建一个#table_seq 并编写一个查询,将loop#table 添加#table_seq.nexvalid
  • 你的意思是,我需要触发器(用于新插入的行)和循环(用于现有行),对吗?
  • 您不需要任何触发器。插入新行时只需使用#table_seq.nextval
  • 我对 PL/SQL 不太熟悉。可以举个语法例子吗?
  • @kzharas210:PL/SQL 中不需要慢循环来更新现有行。

标签: sql plsql oracle11g triggers


【解决方案1】:

这应该可以解决问题

BEGIN
alter table name add (id integer);
create sequence name_seq;

FOR REC IN (SELECT * FROM NAME) LOOP
UPDATE NAME SET ID = NAME_SEQ.NEXTVAL 
WHERE ROWID = REC.ROWID;
END LOOP;
END;

【讨论】:

  • 你还需要循环吗?不能用简单的更新子句来完成吗?
  • @VimalBhaskar:不需要循环,看我的回答
  • @a_horse_with_no_name 我必须检查那个兄弟。这很清楚。因此我放弃了投票:)
【解决方案2】:

创建序列后,只需更新现有行:

alter table name add (id integer);

create sequence name_seq;

update name 
  set id = name_seq.nextval;
commit;

不需要 PL/SQL 或 LOOP 中缓慢且低效的逐行处理。


不相关,但是:触发器中的赋值可以简化为:

:new.id := name_seq.NEXTVAL;

不需要select .. from dual

【讨论】:

    【解决方案3】:

    在添加 ID 列并创建 NAME_SEQ 序列后,而不是使用循环,更简单的选择是使用 Update 语句,如下所示:

    update NAME set ID= NAME_SEQ.nextval ;
    

    【讨论】:

      猜你喜欢
      • 2011-12-14
      • 1970-01-01
      • 2014-01-06
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      相关资源
      最近更新 更多