, , . , , , - ( /), - .
API (xapis). , , Table API (tapis), pl/sql. Xapis (ins/upd/del) , , , " ". . Ask Tom Xapi.
- xapi, , . ( ) pl/sql, :
create table enrollment
(
id number,
username varchar2(50),
course varchar2(50),
status varchar2(50),
created_date date default sysdate not null
);
create index enrollment_idx
on enrollment(username, course)
logging
noparallel;
create or replace package enroll_pkg as
err_already_enrolled constant number := -20101;
err_already_enrolled_msg constant varchar2(50) := 'User is already enrolled';
err_lock_request constant number := -20102;
err_lock_request_msg constant varchar2(50) := 'Unable to obtain lock';
enroll_lock_id constant number := 42;
function is_enrolled(i_username varchar2, i_course varchar2) return number;
procedure enroll_user(i_username varchar2, i_course varchar2);
end;
/
create or replace package body enroll_pkg as
-- returns 1=true, 0=false
function is_enrolled(i_username varchar2, i_course varchar2) return number is
l_cnt number := 0;
begin
-- run test if user is enrolled in this course
select decode(count(1),0,0,1)
into l_cnt
from enrollment
where username=i_username
and course=i_course
and status = 'ENROLLED';
-- testing locks here
--dbms_lock.sleep(5);
return l_cnt;
end;
procedure enroll_user(i_username varchar2, i_course varchar2)
is
l_lock_result number;
l_username enrollment.username%type;
l_course enrollment.course%type;
begin
-- try to get lock (serialize access)
l_lock_result := dbms_lock.request(enroll_lock_id, dbms_lock.x_mode, 10, true);
if (l_lock_result <> 0) then
raise_application_error(err_lock_request,err_lock_request_msg || ' (' || l_lock_result || ')');
end if;
-- simple business rule: uppercase names & course
l_username := upper(trim(i_username));
l_course := upper(trim(i_course));
if (is_enrolled(l_username, l_course) > 0) then
raise_application_error(err_already_enrolled,err_already_enrolled_msg);
end if;
-- do other business logic checks, update other tables, logging, etc...
-- add enrollment
insert into enrollment(id,username,course,status) values
(enroll_seq.nextval,l_username,l_course,'ENROLLED');
commit;
-- release lock
l_lock_result := dbms_lock.release(enroll_lock_id);
end;
end;
/
, :
exec enroll_pkg.enroll_user('Joe Smith','Biology');
, , , // xapi . , , .