0

我发现一个没有主键的旧表,为了添加一个,我必须添加一个新列并用序列值填充它。我有另一列包含创建记录的时间,所以我想将序列值插入到按时间列排序的表中。

我不知道该怎么做。我尝试使用 PL\SQL - 我为查询创建了一个游标,该游标返回带有 ORDER BY 的表,然后更新游标返回的每条记录,但它不起作用。

有没有一种聪明的工作方式来做到这一点?

提前致谢。

4

3 回答 3

2

另一种选择是只使用相关子查询,使用嵌套子查询的皱纹来生成行号。设置一些示例数据:

create table t42 (datefield date);
insert into t42 (datefield) values (sysdate - 7);
insert into t42 (datefield) values (sysdate + 6);
insert into t42 (datefield) values (sysdate - 5);
insert into t42 (datefield) values (sysdate + 4);
insert into t42 (datefield) values (sysdate - 3);
insert into t42 (datefield) values (sysdate + 2);

select * from t42;

DATEFIELD
---------
12-JUL-12
25-JUL-12
14-JUL-12
23-JUL-12
16-JUL-12
21-JUL-12

然后添加并填充新列:

alter table t42 add (id number);

update t42 t1 set t1.id = (
    select rn from (
        select rowid, row_number() over (order by datefield) as rn
        from t42
    ) t2
    where t2.rowid = t1.rowid
);

select * from t42 order by id;

DATEFIELD         ID
--------- ----------
12-JUL-12          1
14-JUL-12          2
16-JUL-12          3
21-JUL-12          4
23-JUL-12          5
25-JUL-12          6

由于这是一个合成键,使其与另一列的顺序相匹配似乎有点毫无意义,但我想不会造成任何伤害。


完成任务:

alter table t42 modify id not null;

alter table t42 add constraint t42_pk primary key (id);
于 2012-07-19T22:53:36.550 回答
0
  • 首先,创建新字段并允许空值。

  • 然后,从其他表或查询中更新字段。最好的方法是使用合并语句。

这是文档中的示例:

MERGE INTO bonuses D
   USING (SELECT employee_id, salary, department_id FROM employees
   WHERE department_id = 80) S
   ON (D.employee_id = S.employee_id)
   WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
     DELETE WHERE (S.salary > 8000)
   WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
     VALUES (S.employee_id, S.salary*.01)
     WHERE (S.salary <= 8000);

这里的例句:

ALTER TABLE 
   customer 
MODIFY 
   ( 
   your_new_field varchar2(100) not null
   )
;
ALTER TABLE 
   customer 
ADD CONSTRAINT customer_pk PRIMARY KEY (your_new_field)
;
于 2012-07-19T19:36:22.500 回答
0

一种简单的方法是创建一个新表,其中包含所有其他列的新列:

create table newt (
    newtID int primary key not null,
    . . .
)

然后将所有旧数据插入其中:

insert into newt
    select row_number() over (order by <CreatedAt>), t.*
    from t

(您可以替换所有列,而不是使用“*”。按名称列是更好的做法。这更短,另外,我不知道列名。)

如果您更改表格以添加列,则该列将出现在末尾。我发现主键很尴尬。但是,如果您这样做,您可以将其更新为:

with t as (select row_number() over (order by <CreatedAt>) as seqnum, t.*
           from t
          )
update t
    set newtID = seqnum
于 2012-07-19T20:16:07.583 回答