如何为 PL SQL 中的现有 table 创建唯一 ID?

How to create a unique id for an existing table in PL SQL?

情况是,当我将文件导入数据库时​​,我通常做的第一件事就是为每条记录分配一个唯一的 ID。

我通常在TSQL

下面做
ALTER TABLE MyTable
    ADD ID INT IDENTITY(1,1)

我想知道PL中是否有类似的东西SQL?

我的所有搜索结果都经过多个步骤返回。

然后我想知道 PL SQL 程序员在导入文件后通常对 ID 记录做什么。他们这样做吗? 我标识这些记录的主要目的是在manipulation/copying.

之后进行追溯

同样,我知道那里有解决方案,我进一步的问题是 PL SQL 程序员是否真的这样做了,或者还有其他选择使得这一步在 PL SQL 中不是必需的?

好的,因为您使用的是 Oracle 11g,所以那里没有 identity 列 - 返回到 多个步骤 。这是一个例子:

我正在创建一个 table 来模拟您的 imported table:

SQL> create table tab_import as
  2    select ename, job, sal
  3    from emp
  4    where deptno = 10;

Table created.

添加 ID 列:

SQL> alter table tab_import add id number;

Table altered.

创建将用于填充 ID 列的序列:

SQL> create sequence seq_imp;

Sequence created.

更新当前行:

SQL> update tab_import set
  2    id = seq_imp.nextval;

3 rows updated.

创建一个触发器来处理未来的插入(如果有的话):

SQL> create or replace trigger trg_bi_imp
  2    before insert on tab_import
  3    for each row
  4  begin
  5    :new.id := seq_imp.nextval;
  6  end;
  7  /

Trigger created.

查看当前 table 中的内容:

SQL> select * from tab_import;

ENAME      JOB              SAL         ID
---------- --------- ---------- ----------
CLARK      MANAGER         2450          1
KING       PRESIDENT       5000          2
MILLER     CLERK           1300          3

让我们导入更多行:

SQL> insert into tab_import (ename, job, sal)
  2    select ename, job, sal
  3    from emp
  4    where deptno = 20;

3 rows created.

触发器已静默填充 ID 列:

SQL> select * From tab_import;

ENAME      JOB              SAL         ID
---------- --------- ---------- ----------
CLARK      MANAGER         2450          1
KING       PRESIDENT       5000          2
MILLER     CLERK           1300          3
SMITH      CLERK            800          4
JONES      MANAGER         2975          5
FORD       ANALYST         3000          6

6 rows selected.

SQL>

很快:您需要

  • 更改 table 并添加 ID 列
  • 创建序列
  • 创建触发器

结束。

@Littlefoot 给出的答案也是我的建议 - 但我仍然认为我可以提及以下变体,它仅在您不打算稍后向 table 添加更多行时才有效。

ALTER TABLE MyTable add id number(38,0); 
update MyTable set id = rownum;
commit;  

我的测试:

SQL> create table tst as select * from all_tables; 

Table created.

SQL> alter table tst add id number(38,0);  

Table altered.

SQL> update tst set id = rownum; 

3815 rows updated.

SQL> alter table tst add constraint tstPk primary key (id); 

Table altered.
SQL> 
SQL> select id from tst where id < 15; 

    ID
----------
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11

    ID
----------
    12
    13
    14

14 rows selected.

但正如最初提到的那样,- 这只会修复更新时您拥有的行的编号 - 您以后不会为新行获取新的 ID 值 - 如果您需要,请继续顺序解。

您可以使用一条语句将 id 列添加到 table(Oracle 11g,请参阅 dbfiddle):

alter table test_
add id raw( 16 ) default sys_guid() ;

示例:

-- create a table without an id column
create table test_ ( str )
as
select dbms_random.string( 'x', 16 )
from dual
connect by level <= 10 ;

select * from test_ ;

STR
ULWL9EXFG6CIO72Z
QOM0W1R9IJ2ZD3DW
YQWAP4HZNQ57C2UH
EETF2AXD4ZKNIBBF
W9SECJYDER793MQW

alter table test_
add id raw( 16 ) default sys_guid() ;

select * from test_ ;

STR                     ID
ULWL9EXFG6CIO72Z    0x782C6EBCAE2D7B9FE050A00A02005D65
QOM0W1R9IJ2ZD3DW    0x782C6EBCAE2E7B9FE050A00A02005D65
YQWAP4HZNQ57C2UH    0x782C6EBCAE2F7B9FE050A00A02005D65
EETF2AXD4ZKNIBBF    0x782C6EBCAE307B9FE050A00A02005D65
W9SECJYDER793MQW    0x782C6EBCAE317B9FE050A00A02005D65

测试

-- Are the id values unique and not null? Yes. 
alter table test_ 
add constraint pkey_test_ primary key ( id ) ;

-- When we insert more rows, will the id be generated? Yes.
begin 
  for i in 1 .. 100
  loop
    insert into test_ (str) values ( 'str' || to_char( i ) ) ;
  end loop ;
end ;
/

select * from test_ order by id desc ;
-- last 10 rows of the result
STR ID
str100  0x782C806E16A5E998E050A00A02005D81
str99   0x782C806E16A4E998E050A00A02005D81
str98   0x782C806E16A3E998E050A00A02005D81
str97   0x782C806E16A2E998E050A00A02005D81
str96   0x782C806E16A1E998E050A00A02005D81
str95   0x782C806E16A0E998E050A00A02005D81
str94   0x782C806E169FE998E050A00A02005D81
str93   0x782C806E169EE998E050A00A02005D81
str92   0x782C806E169DE998E050A00A02005D81
str91   0x782C806E169CE998E050A00A02005D81

关于您的其他问题:

{1} 然后我想知道 PL SQL 程序员在导入文件后通常对 ID 记录做什么。他们这样做吗?我标识这些记录的主要目的是在manipulation/copying.

之后进行追溯

-> 众所周知,id的作用是:标识一行。我们不 "do anything to IDs"。因此,您对 ID 的使用似乎是合法的。

{2} 同样,我知道那里有解决方案,我进一步的问题是 PL SQL 程序员是否真的这样做了,或者还有其他选择使得这一步在 PL [=34= 中不是必需的]?

-> 不太确定你在这里问什么。虽然有一个 ROWID() 伪列(参见 documentation),但我们不应该使用它来标识行。

"You should not use ROWID as the primary key of a table. If you delete and reinsert a row with the Import and Export utilities, for example, then its rowid may change. If you delete a row, then Oracle may reassign its rowid to a new row inserted later."