我找到了一个没有主键的旧表,为了添加一个,我必须添加一个新列并用序列值填充它。我有另一列包含创建记录的时间,所以我想将序列值插入到按时间列排序的表中。
我不知道该怎么做。我尝试使用PL \ SQL - 我为查询创建了一个游标,该查询返回带有ORDER BY的表,然后更新游标返回的每个记录,但它不起作用。
有没有一种聪明的工作方式来做到这一点?
提前致谢。
答案 0 :(得分: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);
答案 1 :(得分:0)
首先,创建新字段并允许空值。
然后,从其他表或查询更新字段。最好的方法是使用merge语句。
以下是文档中的示例:
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)
;
答案 2 :(得分: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