任何查看當前表值的解決方案都不適用於包含多個用戶和多個會話以及並行事務的「真實」環境。
我認爲你需要分離出兩個要求:
- 不得不基於序列的時候被創建
- 不得不在一年內記錄排序報告的能力上記錄的能力。
首先是使用序列因爲這些正是爲此設計和處理併發(多用戶,多筆交易,...)來處理。
第二個是報告要求,根據性能要求有多個選項。
首先創建一個序列:
create sequence seq_analysis_id start with 1 increment by 1 nocache nocycle;
不是讓我們創建一個基表和觸發器來處理自動遞增:
create table analysis_data (
analysis_id integer not null,
analysis_date date not null
);
alter table analysis_data add constraint pk_analysis_data primary key (analysis_id);
create or replace trigger trg_analysis_data
before insert on analysis_data
for each row
begin
:new.analysis_id := seq_analysis_id.nextval();
end trg_analysis_data;
/
insert into analysis_data (analysis_date) values (to_date('2015-12-28', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-29', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-30', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-31', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-01', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-02', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-03', 'YYYY-MM-DD'));
commit;
select * from analysis_data;
ANALYSIS_ID ANALYSIS_DATE
1 28/12/2015
2 29/12/2015
3 30/12/2015
4 31/12/2015
5 01/01/2016
6 02/01/2016
7 03/01/2016
好 - 讓所有工作正常,但沒有按給你所要求的:)
這是第二部分 - 報告要求:
第一個選項是剛拿到號碼,你需要動態:
select
analysis_id,
analysis_date,
extract(year from analysis_date) analysis_year,
row_number()
over (partition by trunc(analysis_date, 'YYYY')
order by analysis_date, analysis_id) analysis_number
from
analysis_data;
使用解析函數(row_number
在這種情況下)是處理這種事情的好方法。
ANALYSIS_ID ANALYSIS_DATE ANALYSIS_YEAR ANALYSIS_NUMBER
1 28/12/2015 2015 1
2 29/12/2015 2015 2
3 30/12/2015 2015 3
4 31/12/2015 2015 4
5 01/01/2016 2016 1
6 02/01/2016 2016 2
7 03/01/2016 2016 3
我已在row_number
函數中訂購analysis_date, analysis_id
。這可能不是必需的,但如果您必須處理analysis_date
的更新(在這種情況下,序列不再適用於年內訂購),則可能需要此選項。
您可以通過在視圖中包裝它使本作的報告有點更直截了當:
create or replace view analysis_data_v as
select
analysis_id,
analysis_date,
extract(year from analysis_date) analysis_year,
row_number()
over (partition by trunc(analysis_date, 'YYYY')
order by analysis_date, analysis_id) analysis_number
from
analysis_data;
這可能是你所需要的,但如果你有大量的數據集,那麼你可能需要預先計算其中一些價值。您有11g中的虛擬列,但這些不適用於分析功能。在這裏,我的選擇是使用物化視圖 - 很多方法來處理物化視圖刷新,最簡單的是:
create materialized view analysis_data_mv
build immediate
refresh complete on demand
as
select
analysis_id,
analysis_date,
analysis_year,
analysis_number
from
analysis_data_v;
select * from analysis_data_mv order by analysis_year, analysis_number;
ANALYSIS_ID ANALYSIS_DATE ANALYSIS_YEAR ANALYSIS_NUMBER
1 28/12/2015 2015 1
2 29/12/2015 2015 2
3 30/12/2015 2015 3
4 31/12/2015 2015 4
5 01/01/2016 2016 1
6 02/01/2016 2016 2
7 03/01/2016 2016 3
在這種情況下,物化視圖就可以手動刷新:
exec dbms_mview.refresh('analysis_data_mv');
希望這可以幫助。
是否要更新以列值插入的表中的同一行1 – XING
否該列不會更新 – SantyEssac