مفهوم جداول موقت در APEX
در این مقاله به یکی از بخشهای جالب و نهچندان واضح در برنامههای Oracle APEX یعنی جداول موقت پرداخته میشود. در ادامه، خود جداول، نحوه کار با آنها و موارد استفاده آنها بررسی خواهد شد.
استفاده از جداول موقت برای توسعهدهندگان Oracle موضوع جدیدی نیست. این جدولها معمولاً برای نگهداری دادهها در طول یک session یا یک تراکنش خاص استفاده میشوند. اما Oracle برای توسعهدهندگان APEX نیز راهکاری اختصاصی در نظر گرفته که کار با دادههای موقتی را بسیار سادهتر کرده است.
هدف اصلی استفاده از جداول موقت در APEX ذخیره دادهها تا زمانیست که session کاربر فعال باشد؛ این قابلیت برای جلوگیری از از بین رفتن دادهها در زمان بارگذاری مجدد صفحه یا در سناریوهایی مانند سبد خرید بسیار کاربردیست.
دو جدول موقت عمومی که در APEX وجود دارد:
- APEX_COLLECTIONS
- APEX_APPLICATION_TEMP_FILES
نکته قابل توجه این است که این جدولها در واقع به صورت فیزیکی «موقت» نیستند، بلکه Viewهایی هستند که فیلتر آنها بر اساس SESSION_ID اعمال شده است. همچنین باید در اعطای دسترسی به اسکیمای APEX_* بسیار محتاط بود.
جدول APEX_COLLECTIONS
Oracle یک API کامل برای کار با این جدول طراحی کرده که شامل:
- View: APEX_COLLECTIONS
- پکیج: APEX_COLLECTION
ساختار این جدول بهگونهای طراحی شده تا نیازهای متنوع توسعهدهندگان را پوشش دهد؛ برای همین دارای ۵۰ ستون VARCHAR2، پنج ستون NUMBER، پنج ستون DATE، یک ستون XMLTYPE، یک ستون BLOB و یک ستون CLOB است.
ایجاد کالکشن (Collection)
مثالهایی از روشهای مختلف برای ساخت کالکشن
declare
l_collection_name CONSTANT VARCHAR2(20) := ‘DEMO_COLLECTION’;
l_exists BOOLEAN;
begin
— Approach 1
l_exists := APEX_COLLECTION.COLLECTION_EXISTS (p_collection_name => l_collection_name);
if l_exists = false then
APEX_COLLECTION.CREATE_COLLECTION(
p_collection_name => l_collection_name,
p_truncate_if_exists => ‘NO’);
end if;
— Approach 2
APEX_COLLECTION.CREATE_COLLECTION(
p_collection_name => l_collection_name,
p_truncate_if_exists => ‘YES’);
— OR
APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(
p_collection_name => l_collection_name);
— Approach 3
begin
APEX_COLLECTION.CREATE_COLLECTION(
p_collection_name => l_collection_name,
p_truncate_if_exists => ‘NO’);
exception
when others then
null;
end;
end;
declare
l_collection_name CONSTANT VARCHAR2(20) := ‘DEMO_COLLECTION’;
l_seq NUMBER;
begin
l_seq := APEX_COLLECTION.ADD_MEMBER (
p_collection_name => l_collection_name,
p_c001 => ‘Text 1’,
p_c002 => ‘Text 2’,
p_c050 => ‘Text 50’,
p_n001 => 12345);
APEX_COLLECTION.UPDATE_MEMBER (
p_collection_name => l_collection_name,
p_seq => l_seq,
p_c001 => ‘Modified text’);
APEX_COLLECTION.DELETE_MEMBER (
p_collection_name => l_collection_name,
p_seq => l_seq);
end;
مشاهده دادههای کالکشن
SELECT SEQ_ID, C001, C002, C050, N001
FROM APEX_COLLECTIONS
WHERE COLLECTION_NAME = ‘DEMO_COLLECTION’
همچنین دادههای کالکشن را میتوان از طریق Session Viewer در محیط APEX نیز مشاهده کرد.
ساختار داخلی APEX_COLLECTIONS
در واقع APEX_COLLECTIONS یک View غیرقابل ویرایش است که بر اساس View سیستم داخلی WWV_FLOW_COLLECTIONS ساخته شده. این View اطلاعات را از جدولهای زیر میگیرد:
- WWV_FLOW_COLLECTIONS$
- WWV_FLOW_COLLECTION_MEMBERS$
و فقط دادههایی را نشان میدهد که متعلق به نشست جاری کاربر باشند. اطلاعاتی مانند FLOW_ID، COLLECTION_NAME، تاریخ ایجاد، و گروه امنیتی در آن ذخیره میشود.
select c.collection_name, m.seq_id, m.c001, m.c002, m.c003, m.c004, m.c005, m.c006, m.c007,
m.c008, m.c009, m.c010, m.c011, m.c012, m.c013, m.c014, m.c015, m.c016, m.c017,
m.c018, m.c019, m.c020, m.c021, m.c022, m.c023, m.c024, m.c025, m.c026, m.c027,
m.c028, m.c029, m.c030, m.c031, m.c032, m.c033, m.c034, m.c035, m.c036, m.c037,
m.c038, m.c039, m.c040, m.c041, m.c042, m.c043, m.c044, m.c045, m.c046, m.c047,
m.c048, m.c049, m.c050, m.clob001, m.blob001, m.xmltype001, m.n001, m.n002, m.n003,
m.n004, m.n005, m.d001, m.d002, m.d003, m.d004, m.d005, m.md5_original
from wwv_flow_current_sgid_for_dml sgid,
wwv_flow_collections$ c,
wwv_flow_collection_members$ m
where c.session_id = (select v(‘SESSION’) from sys.dual)
and c.security_group_id = sgid.security_group_id
and m.security_group_id = sgid.security_group_id
and c.id = m.collection_id
and c.flow_id = (select nv(‘FLOW_ID’) from sys.dual)
Also description of wwv_flow_collections$ table
Name Null? Type
—————— ——– ————-
ID NOT NULL NUMBER
SESSION_ID NOT NULL NUMBER
USER_ID NOT NULL VARCHAR2(255)
FLOW_ID NOT NULL NUMBER
COLLECTION_NAME NOT NULL VARCHAR2(255)
COLLECTION_CHANGED NOT NULL VARCHAR2(10)
CREATED_ON NOT NULL DATE
SECURITY_GROUP_ID NOT NULL NUMBER
جدول APEX_APPLICATION_TEMP_FILES
این جدول بیشتر برای مدیریت فایلهای آپلودی در APEX استفاده میشود. ساختار آن ساده بوده و شامل فیلدهایی مانند:
Name Null? Type
————– ——– ————-
ID NOT NULL NUMBER
APPLICATION_ID NOT NULL NUMBER
NAME NOT NULL VARCHAR2(400)
FILENAME VARCHAR2(400)
MIME_TYPE VARCHAR2(255)
CREATED_ON DATE
BLOB_CONTENT BLOB
مثالی از آپلود فایل
در آیتم صفحه با نوع File Upload و تنظیم نوع ذخیرهسازی روی APEX_APPLICATION_TEMP_FILES:
پس از انتخاب فایل، با اجرای Submit فایل در این جدول ذخیره میشود. اگر گزینه “Purge File at End of Request” فعال باشد، فایل بلافاصله پس از پایان درخواست حذف خواهد شد.
declare
l_cnt NUMBER := 0;
begin
APEX_DEBUG.ENABLE(apex_debug.c_log_level_info);
select count(1)
into l_cnt
from APEX_APPLICATION_TEMP_FILES;
APEX_DEBUG.INFO (p_message => ‘APEX_APPLICATION_TEMP_FILES has ‘ || l_cnt || ‘ row(s)’);
APEX_DEBUG.DISABLE;
end;
Result are under Debug tab in session info
Some Technical Stuff 🙂
Not surprised that APEX_APPLICATION_TEMP_FILES also public synonym that referred to WWV_FLOW_TEMP_FILES view. The source query for it
select id,
flow_id application_id,
name,
filename,
mime_type,
created_on,
blob_content
from wwv_flow_current_sgid_for_dml sgid,
wwv_flow_file_objects$ a
where a.security_group_id = sgid.security_group_id
and session_id = ( select nv(‘SESSION’) from sys.dual )
with check option
And description for wwv_flow_file_objects$ table
Name Null? Type
—————– ——– ————–
ID NOT NULL NUMBER
FLOW_ID NOT NULL NUMBER
NAME NOT NULL VARCHAR2(400)
PATHID NUMBER
FILENAME VARCHAR2(400)
TITLE VARCHAR2(255)
MIME_TYPE VARCHAR2(255)
DOC_SIZE NUMBER
DAD_CHARSET VARCHAR2(128)
CREATED_BY VARCHAR2(255)
CREATED_ON DATE
UPDATED_BY VARCHAR2(255)
UPDATED_ON DATE
DELETED_AS_OF NOT NULL DATE
LAST_UPDATED DATE
CONTENT_TYPE VARCHAR2(128)
BLOB_CONTENT BLOB
LANGUAGE VARCHAR2(30)
DESCRIPTION VARCHAR2(4000)
SECURITY_GROUP_ID NUMBER
FILE_TYPE VARCHAR2(255)
FILE_CHARSET VARCHAR2(128)
SESSION_ID NUMBER
You can see that pretty much useful information stored alongside with file, that can be used.
جمعبندی
Oracle با طراحی این جداول موقت در APEX، ابزار قدرتمند و سادهای برای مدیریت دادههای نشست در اختیار توسعهدهندگان قرار داده است. این قابلیت نه تنها انعطافپذیر است، بلکه حرفهایترین روش برای ذخیره و مدیریت دادههای موقتی در برنامههای APEX به شمار میرود.
