Part IV: SQL in PL/SQL
14.SQL in PL/SQL (SQL នៅក្នុង PL/SQL)
• ពន្យល់អំពីការប្រើ SQL statements (SELECT, INSERT,
UPDATE, DELETE) នៅក្នុង PL/SQL។
15.Dynamic SQL (SQL ថាមវន្ត)
• ពន្យល់អំពីការប្រើ Native Dynamic SQL (NDS) និង
DBMS_SQL។
16.DML and Transaction Management (DML និងការគ្រប់គ្រង
ប្រតិបត្តិការ)
• គ្របដណ្តប់លើការគ្រប់គ្រង transactions (COMMIT,
AN POLIN_ Exception Handlers 1
16.1 ទិដ្ឋភាពទូទៅនៃ DML និង Transaction
Management
DML (Data Manipulation Language) statements ដូចជា INSERT,
UPDATE, DELETE, និង MERGE ត្រូវបានប្រើដើម្បី manipulate
ទិន្នន័យនៅក្នុង database tables។ Transaction management
ពាក់ព័ន្ធនឹងការគ្រប់គ្រង changes ទៅលើ database ដោយប្រើ
COMMIT, ROLLBACK, និង SAVEPOINT ដើម្បីធានា data integrity និង
consistency។ នៅក្នុង PL/SQL, DML operations និង transaction
control ត្រូវបានរួមបញ្ចូលជាមួយ logic ដើម្បីគ្រប់គ្រង complex
AN POLIN_ Exception Handlers 2
business rules។
16.1.1 DML Operations
INSERT: បញ្ចូល rows ថ្មីទៅក្នុង table។
UPDATE: កែប្រែ rows ដែលមានស្រាប់។
DELETE: លុប rows ចេញពី table។
MERGE: Combine INSERT, UPDATE, និង DELETE
ដោយផ្អែកលើ conditions។
AN POLIN_ Exception Handlers 3
16.1.2 Transaction Management
Transaction: ជា sequence នៃ DML operations ដែលត្រូវបាន
treated ជា single unit of work។
COMMIT: Permanently save changes ទៅ database។
ROLLBACK: Undo changes ត្រឡប់ទៅ state មុន transaction។
SAVEPOINT: Mark point នៅក្នុង transaction ដើម្បី allow
partial rollback។
AN POLIN_ Exception Handlers 4
16.2 DML Operations នៅក្នុង PL/SQL
DML statements នៅក្នុង PL/SQL ត្រូវបានប្រើដើម្បី
manipulate data និងជាទូទៅរួមបញ្ចូលជាមួយ variables, records,
ឬ collections។
16.2.1 INSERT Operation
ឧទាហរណ៍: Insert employee record និង retrieve generated ID។
AN POLIN_ Exception Handlers 5
DECLARE
v_employee_id NUMBER := 999;
v_first_name VARCHAR2(50) := 'Sok Sophea';
v_salary NUMBER := 50000;
v_inserted_id NUMBER;
BEGIN
INSERT INTO employees (employee_id, first_name, salary, hire_date, department_id)
VALUES (v_employee_id, v_first_name, v_salary, SYSDATE, 10)
RETURNING employee_id INTO v_inserted_id;
DBMS_OUTPUT.PUT_LINE('Inserted employee ID: ' || v_inserted_id);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Error: Employee ID already exists');
END;
•/
លទ្ធផល:
Inserted employee ID: 999
AN POLIN_ Exception Handlers 6
16.2.2 UPDATE Operation
ឧទាហរណ៍: Update salary សម្រាប់ employee ជាក់លាក់។
DECLARE
v_employee_id NUMBER := 100;
v_new_salary NUMBER := 26000;
BEGIN
UPDATE employees
SET salary = v_new_salary,
last_modified = SYSDATE
WHERE employee_id = v_employee_id;
IF SQL%ROWCOUNT = 0 THEN
DBMS_OUTPUT.PUT_LINE('No employee updated');
ELSE
DBMS_OUTPUT.PUT_LINE('Updated salary for employee ID: ' || v_employee_id);
END IF;
END;
•/
លទ្ធផល:
Updated salary for employee ID: 100
AN POLIN_ Exception Handlers 7
16.2.3 DELETE Operation
ឧទាហរណ៍: Delete inactive employees។
DECLARE
v_inactive_date DATE := TO_DATE('01-JAN-2020', 'DD-MON-YYYY');
BEGIN
DELETE FROM employees
WHERE hire_date < v_inactive_date
AND status = 'INACTIVE';
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' inactive employees deleted');
END;
•/
លទ្ធផល:
5 inactive employees deleted
AN POLIN_ Exception Handlers 8
16.2.4 MERGE Operation
ឧទាហរណ៍: Merge employee data ពី staging table។
DECLARE
v_employee_id NUMBER := 998;
v_first_name VARCHAR2(50) := 'Chan Phea';
v_salary NUMBER := 60000;
BEGIN
MERGE INTO employees e
USING (SELECT v_employee_id AS employee_id, v_first_name AS first_name,
v_salary AS salary
FROM dual) s
ON (e.employee_id = s.employee_id)
WHEN MATCHED THEN
AN POLIN_ Exception Handlers 9
UPDATE SET e.first_name = s.first_name,
e.salary = s.salary,
e.last_modified = SYSDATE
WHEN NOT MATCHED THEN
INSERT (employee_id, first_name, salary, hire_date, department_id)
VALUES (s.employee_id, s.first_name, s.salary, SYSDATE, 20);
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rows merged');
END;
•/
លទ្ធផល:
1 rows merged
AN POLIN_ Exception Handlers 10
16.2.5 Best Practices សម្រាប់ DML Operations
បញ្ជាក់ Columns: លើកឡើង columns នៅក្នុង INSERT, UPDATE, និង
MERGE ដើម្បី clarity និង maintainability។
Check SQL%ROWCOUNT: Verify ចំនួន rows affected បន្ទាប់ពី
DML operation។
ប្រើ RETURNING Clause: Retrieve generated or updated values។
UPDATE employees SET salary = salary + 1000 RETURNING salary
INTO v_new_salary;
Handle Constraints: ចាប់ exceptions ដូចជា DUP_VAL_ON_INDEX
ឬ ORA-02291 (foreign key violation)។
Validate Input: ពិនិត្យ data មុនពេល execute DML statements។
AN POLIN_ Exception Handlers 11
16.3 Transaction Management
Transaction management ធានា data consistency ដោយ grouping
DML operations ទៅជា single unit of work។ Transactions ត្រូវបាន
controlled ដោយ COMMIT, ROLLBACK, និង SAVEPOINT។
16.3.1 COMMIT
COMMIT permanently saves changes ទៅ database និង ends
transaction។
ឧទាហរណ៍: Insert និង commit employee record។
AN POLIN_ Exception Handlers 12
DECLARE
v_employee_id NUMBER := 997;
v_first_name VARCHAR2(50) := 'Kim Srey';
BEGIN
INSERT INTO employees (employee_id, first_name, hire_date, department_id)
VALUES (v_employee_id, v_first_name, SYSDATE, 30);
COMMIT;
DBMS_OUTPUT.PUT_LINE('Employee ' || v_first_name || ' inserted and committed');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
Employee Kim Srey inserted and committed
AN POLIN_ Exception Handlers 13
16.3.2 ROLLBACK
ROLLBACK undoes changes ត្រឡប់ database ទៅ state មុន
transaction។
ឧទាហរណ៍: Attempt insert និង rollback ប្រសិនបើមាន error។
DECLARE
v_employee_id NUMBER := 997; -- Duplicate ID
BEGIN
INSERT INTO employees (employee_id, first_name, hire_date,
department_id)
VALUES (v_employee_id, 'Sok Sophea', SYSDATE, 30);
DBMS_OUTPUT.PUT_LINE('Insert successful');
COMMIT;
AN POLIN_ Exception Handlers 14
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Duplicate employee ID');
ROLLBACK;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
Duplicate employee ID
AN POLIN_ Exception Handlers 15
16.3.3 SAVEPOINT
SAVEPOINT marks point នៅក្នុង transaction ដើម្បី allow partial
rollback។
ឧទាហរណ៍: Use savepoint ដើម្បី rollback partial changes។
DECLARE
v_employee_id NUMBER := 996;
BEGIN
-- Start transaction
INSERT INTO employees (employee_id, first_name, hire_date,
department_id)
VALUES (v_employee_id, 'Chan Phea', SYSDATE, 40);
AN POLIN_ Exception Handlers 16
UPDATE employees
SET salary = 70000
WHERE employee_id = v_employee_id;
-- Simulate error
RAISE_APPLICATION_ERROR(-20001, 'Invalid update');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK TO after_insert;
DBMS_OUTPUT.PUT_LINE('Rolled back to after_insert');
COMMIT; -- Commit the insert
DBMS_OUTPUT.PUT_LINE('Insert committed');
END;
•/
លទ្ធផល:
Error: ORA-20001: Invalid update
Rolled back to after_insert
Insert committed
AN POLIN_ Exception Handlers 17
16.3.4 Autonomous Transactions
Autonomous transactions allow independent transactions
ដែលមិន affect main transaction។
ឧទាហរណ៍: Log error នៅក្នុង separate transaction។
CREATE TABLE error_log (
log_id NUMBER GENERATED ALWAYS AS IDENTITY,
error_message VARCHAR2(4000),
log_date DATE
);
/
AN POLIN_ Exception Handlers 18
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
v_error_message VARCHAR2(4000) := 'Invalid salary update';
BEGIN
INSERT INTO error_log (error_message, log_date)
VALUES (v_error_message, SYSDATE);
COMMIT; -- Commit in autonomous transaction
DBMS_OUTPUT.PUT_LINE('Error logged');
END;
/
AN POLIN_ Exception Handlers 19
DECLARE
v_employee_id NUMBER := 100;
BEGIN
UPDATE employees
SET salary = -1000 -- Invalid
WHERE employee_id = v_employee_id;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
-- Call autonomous transaction to log error
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
AN POLIN_ Exception Handlers 20
BEGIN
INSERT INTO error_log (error_message, log_date)
VALUES (SQLERRM, SYSDATE);
COMMIT;
END;
DBMS_OUTPUT.PUT_LINE('Error logged: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
Error logged: ORA-02290: check constraint (HR.SALARY_MIN)
AN POLIN_ Exception Handlers 21
16.3.5 Best Practices សម្រាប់ Transaction Management
Explicit COMMIT/ROLLBACK: បញ្ជាក់ COMMIT ឬ ROLLBACK
នៅចុងបញ្ចប់នៃ transaction ដើម្បី clarity។
Use SAVEPOINT for Complex Transactions: Allow partial
rollbacks នៅក្នុង long transactions។
Minimize Transaction Scope: Commit ញឹកញាប់នៅក្នុង batch
processes ដើម្បីកាត់បន្ថយ locking។
Handle Exceptions: តែងតែ ROLLBACK នៅក្នុង exception block
ដើម្បី prevent partial changes។
AN POLIN_ Exception Handlers 22
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
• RAISE;
Use Autonomous Transactions Sparingly: ប្រើ
autonomous transactions សម្រាប់ logging ឬ auditing ដើម្បី
avoid complexity។
AN POLIN_ Exception Handlers 23
16.4 ការប្រើ DML និង Transaction Management នៅក្នុង
Real-World Scenarios
16.4.1 Employee Data Update with Transaction Control
ឧទាហរណ៍: Update salary និង insert audit log នៅក្នុង transaction។
CREATE TABLE salary_audit (
audit_id NUMBER GENERATED ALWAYS AS IDENTITY,
employee_id NUMBER,
old_salary NUMBER,
new_salary NUMBER,
audit_date DATE
);
AN POLIN_ Exception Handlers 24
DECLARE
v_employee_id NUMBER := 100;
v_new_salary NUMBER := 27000;
v_old_salary NUMBER;
BEGIN
-- Get current salary
SELECT salary INTO v_old_salary
FROM employees
WHERE employee_id = v_employee_id;
-- Update salary
UPDATE employees
SET salary = v_new_salary
WHERE employee_id = v_employee_id;
AN POLIN_ Exception Handlers 25
-- Insert audit log
INSERT INTO salary_audit (employee_id, old_salary, new_salary, audit_date)
VALUES (v_employee_id, v_old_salary, v_new_salary, SYSDATE);
COMMIT;
DBMS_OUTPUT.PUT_LINE('Salary updated and audited for employee ID: ' || v_employee_id);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee not found');
ROLLBACK;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
Salary updated and audited for employee ID: 100
AN POLIN_ Exception Handlers 26
16.4.2 Bulk Data Processing
ឧទាហរណ៍: Update salaries សម្រាប់ department និង commit នៅក្នុង
batches។
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, salary
FROM employees
WHERE department_id = 20;
v_count NUMBER := 0;
BEGIN
FOR emp_rec IN emp_cursor LOOP
UPDATE employees
SET salary = emp_rec.salary * 1.05
WHERE employee_id = emp_rec.employee_id;
v_count := v_count + 1;
AN POLIN_ Exception Handlers 27
-- Commit every 10 updates
IF MOD(v_count, 10) = 0 THEN
COMMIT;
DBMS_OUTPUT.PUT_LINE('Committed ' || v_count || ' updates');
END IF;
END LOOP;
COMMIT; -- Final commit
DBMS_OUTPUT.PUT_LINE('Total ' || v_count || ' employees updated');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
Total 2 employees updated
AN POLIN_ Exception Handlers 28
16.4.3 Data Migration with MERGE
ឧទាហរណ៍: Migrate data ពី staging table ទៅ production table។
CREATE TABLE emp_staging (
employee_id NUMBER,
first_name VARCHAR2(50),
salary NUMBER
);
/
INSERT INTO emp_staging VALUES (995, 'Sok Sophea', 55000);
INSERT INTO emp_staging VALUES (100, 'Steven', 25000);
/
AN POLIN_ Exception Handlers 29
DECLARE
v_rows NUMBER;
BEGIN
MERGE INTO employees e
USING emp_staging s
ON (e.employee_id = s.employee_id)
WHEN MATCHED THEN
UPDATE SET e.first_name = s.first_name,
e.salary = s.salary,
e.last_modified = SYSDATE
WHEN NOT MATCHED THEN
INSERT (employee_id, first_name, salary, hire_date, department_id)
VALUES (s.employee_id, s.first_name, s.salary, SYSDATE, 10);
v_rows := SQL%ROWCOUNT;
AN POLIN_ Exception Handlers 30
COMMIT;
DBMS_OUTPUT.PUT_LINE(v_rows || ' rows merged');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
•/
លទ្ធផល:
2 rows merged
AN POLIN_ Exception Handlers 31
16.5 សេចក្តីសន្និដ្ឋាន
DML operations (INSERT, UPDATE, DELETE, MERGE) នៅក្នុង
PL/SQL អនុញ្ញាតឱ្យអ្នក manipulate database data ប្រកបដោយ
ប្រសិទ្ធភាព។ Transaction management (COMMIT, ROLLBACK,
SAVEPOINT) ធានា data integrity ដោយ controlling changes ជា single
unit of work។ PL/SQL បន្ថែម features ដូចជា exception handling,
SQL%ROWCOUNT, និង autonomous transactions ដើម្បី enhance
robustness។
AN POLIN_ Exception Handlers 32