在应用开发中,取序列号时除了利用数据库提供的sequence之外,还可以通过使用序列表,每取一个值,值加一.
比如:
-- Oracle语法
-- 获取序列号
drop table t_seq purge;
create table t_seq(id int);
insert into t_seq values(0);
commit;
create or replace function func_getid return int
is
v_id int;
begin
update t_seq set id = id+1 returning id into v_id;
return v_id;
dbms_output.put_line('ID = '||v_id);
end;
/
其中t_seq是序号表,函数func_getid对id加一并返回新值.
使用该函数更新业务表t_result
drop table t_result purge;
create table t_result(id int);
insert into t_result values(1);
declare
begin
for i in 1..4 loop
insert into t_result select * from t_result;
end loop;
end;
/
update t_result set id = func_getid;
在Oracle中,多个会话同时执行update语句,t_result的ID是可以保证连续的,但在PG中却会出现”跳号”
Oracle
-------------------- Session 1
SQL> update t_result set id = func_getid;
已更新 16 行。
SQL> commit;
提交完成。
SQL>
SQL> select * from t_result;
ID
----------
1
2
3
4
5
6
7
8
9
10
11
ID
----------
12
13
14
15
16
已选择 16 行。
--------------------- Session 2
SQL> update t_result set id = func_getid;
已更新 16 行。
SQL> select * from t_result;
ID
----------
17
18
19
20
21
22
23
24
25
26
27
ID
----------
28
29
30
31
32
已选择 16 行。
SQL>
PostgreSQL
创建基表
drop table if exists t_seq;
create table t_seq(id int);
insert into t_seq values(0);
CREATE OR REPLACE FUNCTION func_getid() RETURNS int
LANGUAGE plpgsql
AS
$func_getid$
DECLARE
v_id int;
BEGIN
update t_seq
set id = id + 1
returning id into v_id;
RETURN v_id;
END;
$func_getid$;
drop table t_result;
create table t_result(id int);
insert into t_result select generate_series(1,16);
更新数据
------------- Session 1
[local]:5014 pgmaster@testdb=# begin;
BEGIN
Time: 0.299 ms
[local]:5014 pgmaster@testdb=#* update t_result set id = func_getid();
UPDATE 16
Time: 1.132 ms
[local]:5014 pgmaster@testdb=#* select * from t_result;
id
----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(16 rows)
Time: 0.676 ms
[local]:5014 pgmaster@testdb=#*
[local]:5014 pgmaster@testdb=#* commit; ---- 在Session 执行update后执行
COMMIT
Time: 4.250 ms
[local]:5014 pgmaster@testdb=#
------------- Session 2
[local]:5014 pgmaster@testdb=# begin;
BEGIN
Time: 0.445 ms
[local]:5014 pgmaster@testdb=#* update t_result set id = func_getid();
UPDATE 16
Time: 2959.112 ms (00:02.959)
[local]:5014 pgmaster@testdb=#* select * from t_result;
id
----
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
(16 rows)
Time: 0.465 ms
[local]:5014 pgmaster@testdb=#*
“序号”出现了跳号的情况,原因是什么?后续有时间写个源码解读.