トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-177 LRU方式で追加更新その1

SQLパズル

LRUTable
PID  PName
---  -------
  1  NotePad
  2  EmEditor
  3  Oracle
  4  Java

LRU方式で管理しているLRUTableに、
データを追加更新するストアドプロシージャLRUを作成する。

exec LRU('iexplore'); を実行後
PID  PName
---  --------
  1  NotePad
  2  EmEditor
  3  Oracle
  4  Java
  5  iexplore

exec LRU('Java'); を実行後
PID  PName
---  -------
  1  NotePad
  2  EmEditor
  3  Oracle
  4  iexplore
  5  Java

exec LRU('NotePad'); を実行後
PID  PName
---  -------
  1  EmEditor
  2  Oracle
  3  iexplore
  4  Java
  5  NotePad

exec LRU('Java'); を実行後
PID  PName
---  -------
  1  EmEditor
  2  Oracle
  3  iexplore
  4  NotePad
  5  Java

こちらを参考にさせていただきました(英語)


データ作成スクリプト

create table LRUTable(
PID   number(1) primary key,
PName varchar2(8) unique);

truncate table LRUTable;
insert into LRUTable values(1,'NotePad');
insert into LRUTable values(2,'EmEditor');
insert into LRUTable values(3,'Oracle');
insert into LRUTable values(4,'Java');
commit;


SQL

create or replace procedure LRU(p_val varchar2) as
begin
    insert into LRUTable a
    select count(*)+1,p_val
      from LRUTable b
    having min(case when b.PName = p_val then 0 else 1 end) = 1;

    if SQL%RowCount = 0 then
        update LRUTable a
        set PID = (select b.NewPID
                     from (select bb.RowID as Row_ID,
                           Row_Number() over(order by decode(bb.PName,p_val,1,0),bb.PID) as NewPID
                           from LRUTable bb) b
                   where a.RowID = b.Row_ID);
     end if;
end;
/

sho err

select PID,PName from LRUTable order by PID;

exec LRU('iexplore');
select PID,PName from LRUTable order by PID;

exec LRU('Java');
select PID,PName from LRUTable order by PID;

exec LRU('NotePad');
select PID,PName from LRUTable order by PID;

exec LRU('Java');
select PID,PName from LRUTable order by PID;


解説

最初のinsert文で、
having句で全称命題(全ての要素が、PName = p_val を満たさない)
の真偽を調べてます。

10-173 全称命題と存在命題で論理積(group化版)