go to http://oracle.in.th
Showing posts with label plsql. Show all posts
Showing posts with label plsql. Show all posts

Friday, December 25, 2009

ความเป็นมาและประสิทธิภาพของ PL/SQL

PL/SQL เป็นการนำคำสองคำคือ PL และ SQL มารวมกัน

PL ย่อมาจาก Procedure Language พัฒนาโดย Oracle เพื่อเป็นส่วนเพิ่ม (extension) ใน standard SQL ให้ทำงานแบบ procedural กับฐานข้อมูล PL/SQL เป็นตัวเชื่อมระหว่าง database technology และ procedural programming language, PL/SQL เป็นเครื่องมือใช้พัฒนาระบบงานที่เพิ่มความสามารถให้กับ SQL ของ Oracle ทำให้พัฒนาระบบงานที่สลับซับซ้อน และเข้าถึงจัดการข้อมูลในฐานข้อมูลได้เป็นอย่างดี ด้วยความสามารถของ PL/SQL เราสามารถใช้คำสั่ง
DML เช่น insert, delete, update, select กับข้อมูล ใช้คำสั่ง loop ทำงานแบบวนซ้ำ ใช้ if และ case ตรวจสอบเงื่อนไข

คำสั่ง SQL นำมาใช้ใน PL/SQL ได้ ใน PL/SQL block มีได้หลาย SQL statements เมื่อส่ง SQL statements ไปประมวลผลที่ตัวจัดการฐานข้อมูลมันถูกส่งไปในลักษณะของ block SQL (Structured Query Language) คือภาษาที่มีลักษณะเหมือนประโยคบรรยายถึงสิ่งที่ต้องการ โดยไม่สนใจวิธีเพื่อให้ได้มาของสิ่งที่ต้องการว่าเป็นอย่างไร

ข้อดีคือทำให้ระบบงานที่พัฒนาไม่สนใจว่าข้อมูลจัดเก็บจริงอย่างไร (physically stored) การทำงานของ SQL เกือบทั้งหมดกระทำที่ database server แต่ SQL มีข้อจำกัดคือในการทำงานจริงบางอย่าง การทำงานให้เสร็จโดยใช้ SQL query เพียงประโยคเดียวอาจทำได้ยาก หรือทำไม่ได้นักพัฒนาระบบงานพบว่าบ่อยครั้งต้อง execute หลาย queries เพื่อให้ได้ผลลัพธ์ที่ต้องการ และอาจต้องประมวลผลผลลัพธ์ที่ได้จาก query หนึ่งก่อนที่จะทำงานในขั้นตอนต่อไปได้

ประสิทธิภาพของ PL/SQL
ถ้าไม่มี PL/SQL, RDBMS จะประมวลผล SQL statement ครั้งละ 1 statement ทำให้ประมวลผลล่าช้า ถ้าทำงานบน network มีผู้ใช้หลายคนสั่ง run SQL statement พร้อมกันในเวลาเดียวกันจะทำให้เพิ่ม traffic บน network และ disk I/O ทำงานเพิ่มขึ้น ถ้ามี PL/SQL เราส่ง SQL statement ในลักษณะของ block (มีหลาย SQL statements ในหนึ่ง block) ไปประมวลผลที่ RDBMS engine วิธีนี้ทำให้ลดการติดต่อสื่อสารระหว่างโปรแกรมที่พัฒนากับ RDBMS และลด traffic บน network ไปในตัว

SQL statement
จากรูป เปรียบเทียบการส่ง SQL statement ไปประมวลผลระหว่าง PL/SQL ของ Oracle กับ SQL ของโปรดักท์อื่น Oracle ส่งไปเป็น block ใน block ประกอบด้วยหลาย SQL statements เมื่อตัวจัดการฐานข้อมูล (RDBMS) ได้รับ SQL code ที่มาเป็น block ทำให้การประมวลผลทำได้เร็วกว่ารับมาครั้งละ statement แล้วประมวลผล วิธีนี้ทำให้ PL/SQL เพิ่มประสิทธิภาพการประมวลของ RDBMS

อ้างอิ​งจากหนังสือ​ของคุณบรรศักดิ์​ ​เกิดชัยฤทธิ์
เล่ม "พัฒนา​ Web Applications ​ด้วย​ Oracle Developer Suite 10g"

ปล. ดูเนื้อหาหนังสือที่แจกฟรี 16 บทได้ที่นี้ครับ
ข้อเขียนนี้ช่วยฉัน:  

Monday, November 2, 2009

ส่งเมล์ง่าย ๆ ด้วย PL/SQL โดยใช้ UTL_MAIL

utl_mail package เป็น feature ที่มีเพิ่มเข้ามาตั้งแต่ oracle database version 10g เป็นต้นไป
จุดเด่นที่สำคัญของมัน คือ ทำให้การส่ง email สะดวกและง่ายมากขึ้น จาก version ก่อนที่ใช้ utl_smtp และ utl_tcp ซึ่งการเรียกใช้ค่อนข้างยุ่งยาก

โดยปกติ utl_mail package ยังไม่สามารถใช้งานได้ทันที หลังจากการติดตั้ง oracle database จำเป็นที่จะต้องติดตั้งเพิ่ม โดยมีขั้นตอน ดังต่อไปนี้
  • ติดต่อเชื่อมต่อ oracle database ด้วย sys
  • $ sqlplus sys/manager1@db as sysdba
  • run ORACLE_HOME/rdbms/admin/utlmail.sql
  • SQL>@ORACLE_HOME/rdbms/admin/utlmail.sql
  • grant สิทธิ์ให้กับ user ที่จะใช้ utl_mail package
  • SQL>grant execute to test_app;
เท่านี้ ก็จะสามารถใช้งาน utl_mail package ได้แล้ว ต่อไปเราจะมาดูรายละเอียดของ utl_mail กัน

ภายใน utl_mail package จะประกอบไปด้วย 3 procedure ดังนี้

1. send ใช้สำหรับส่ง email ทั่วไป โดยไม่ได้มีการแนบไฟล์
utl_mail.send(
sender        IN    VARCHAR2 CHARACTER SET ANY_CS,
recipients    IN    VARCHAR2 CHARACTER SET ANY_CS,
cc            IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
bcc           IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
subject       IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
message       IN    VARCHAR2 CHARACTER SET ANY_CS,
mime_type     IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT 'text/plain;charset=us-ascii',
priority      IN    PLS_INTEGER DEFAULT 3);
ตัวอย่าง
begin
execute immediate 'ALTER SESSION SET smtp_out_server = 'localhost';';
UTL_MAIL.send('test1@test.com',
'test2@test.com',
null,
null,
'Hello Send',
'Hello,How are you?',
'text; charset=us-ascii',
null);
end;
ใีนการอ้างอิง File ใน utl_file package เราจะต้องสร้าง
directory เพื่อ อ้างอิง location หรือ path ดังนี้
SQL>CREATE DIRECTORY d_file_path AS '/file/';

SQL>GRANT READ,WRITE ON DIRECTORY d_file_path TO test_app;

2. send_attach_raw ใช้สำหรับส่ง email ที่มีการแนบไฟล์
utl_mail.send_attach_raw (
sender  IN    VARCHAR2 CHARACTER SET ANY_CS,
recipients      IN    VARCHAR2 CHARACTER SET ANY_CS,
cc              IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
bcc             IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
subject         IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
message         IN    VARCHAR2 CHARACTER SET       ANY_CS DEFAULT NULL,
mime_type       IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT 'text/plain;charset=us-ascii',
priority        IN    PLS_INTEGER DEFAULT 3,
attachment      IN    RAW,
att_inline      IN    BOOLEAN DEFAULT TRUE,
att_mime_type   IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT 'text/plain; charset=us-ascii',
att_filename    IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL);
ตัวอย่าง
declare
v_file  utl_file.file_type;
v_raw_file RAW(32767);
v_file_length NUMBER;
v_block_size NUMBER;
v_exist  BOOLEAN;
v_location VARCHAR2(50):='d_file_path';
v_file_name VARCHAR2(50):='test.pdf';
begin
execute immediate 'ALTER SESSION SET smtp_out_server = 'localhost';';

utl_file.fgetattr(v_location,v_file_name,v_exist,v_file_length,v_block_size);
v_file:=utl_file.fopen(v_location,v_file_name,'R');
utl_file.get_raw(v_file,v_raw_file,v_file_length);
utl_file.fclose(v_file);

utl_mail.send_attach_raw('test1@test.com',
'test2@test.com',
null,
null,
'Hello Send Attach Raw',
'Hello,How are you?',
'text; charset=us-ascii',
null,
v_raw_file,
FALSE,
'text; charset=us-ascii',
v_file_name);
end;

3. send_attach_varchar2 ใช้สำหรับส่ง email ที่มีการแนบไฟล์ที่เป็น text

utl_mail.send_attach_varchar2(
sender         IN    VARCHAR2 CHARACTER SET ANY_CS,
recipients     IN    VARCHAR2 CHARACTER SET ANY_CS,
cc             IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
bcc            IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
subject        IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
message        IN    VARCHAR2 CHARACTER SET       ANY_CS DEFAULT NULL,
mime_type      IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT 'text/plain;charset=us-ascii',
priority       IN    PLS_INTEGER DEFAULT 3,
attachment     IN    VARCHAR2 CHARACTER SET ANY_CS,
att_inline     IN    BOOLEAN DEFAULT TRUE,
att_mime_type   IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT 'text/plain; charset=us-ascii,
att_filename    IN    VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL);
ตัวอย่าง
declare
v_file  utl_file.file_type;
v_raw_file RAW(32767);
v_file_length NUMBER;
v_block_size NUMBER;
v_exist  BOOLEAN;
v_location VARCHAR2(50):='d_file_path';
v_file_name VARCHAR2(50):='test.txt';
begin
execute immediate 'ALTER SESSION SET smtp_out_server = 'localhost';';

utl_file.fgetattr(v_location,v_file_name,v_exist,v_file_length,v_block_size);
v_file:=utl_file.fopen(v_location,v_file_name,'R');
utl_file.get_raw(v_file,v_raw_file,v_file_length);
utl_file.fclose(v_file);

utl_mail.send_attach_varchar2('test1@test.com',
'test2@test.com',
null,
null,
'Hello Send Attach Varchar2',
'Hello,How are you?',
'text; charset=us-ascii',
null,
v_raw_file,
FALSE,
'text; charset=us-ascii',
v_file_name);
end;
ข้อเขียนนี้ช่วยฉัน: