Cleanup and Create QLNS Environment
Cleanup and Create QLNS Environment
PROMPT
=========================================================
PROMPT === FILE 1: CLEANUP QLNS ENVIRONMENT ===
PROMPT
=========================================================
-- Kill sessions
PROMPT
PROMPT Bước 1: Kill sessions
BEGIN
FOR s IN (
SELECT sid, serial#, username
FROM v$session
WHERE username IN
('QLNS','ADMIN','HOATV','MAIANH','NGUYEN','PHUONG','QUOC')
) LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION '''||[Link]||','||
[Link]#||''' IMMEDIATE';
DBMS_OUTPUT.PUT_LINE('>> Đã kill session: ' || [Link]);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('!! Không thể kill: ' || [Link]);
END;
END LOOP;
END;
/
-- Drop users
PROMPT
PROMPT Bước 2: Drop users
BEGIN
FOR u IN (
SELECT username FROM dba_users
WHERE username IN
('QLNS','ADMIN','HOATV','MAIANH','NGUYEN','PHUONG','QUOC')
) LOOP
BEGIN
EXECUTE IMMEDIATE 'DROP USER '||[Link]||' CASCADE';
DBMS_OUTPUT.PUT_LINE('>> Đã xóa user: ' || [Link]);
EXCEPTION WHEN OTHERS THEN NULL;
END;
END LOOP;
END;
/
-- Drop roles
PROMPT
PROMPT Bước 3: Drop roles
BEGIN
FOR r IN (
SELECT role FROM dba_roles
WHERE role IN
('ROLE_QUANLY_CAP_CAO','ROLE_NHANVIEN_GIAO_DICH','ROLE_NHAN
VIEN_KHO')
) LOOP
BEGIN
EXECUTE IMMEDIATE 'DROP ROLE '||[Link];
DBMS_OUTPUT.PUT_LINE('>> Đã xóa role: ' || [Link]);
EXCEPTION WHEN OTHERS THEN NULL;
END;
END LOOP;
END;
/
-- Drop profile
PROMPT
PROMPT Bước 5: Drop profile
BEGIN
EXECUTE IMMEDIATE 'DROP PROFILE MyPassword CASCADE';
DBMS_OUTPUT.PUT_LINE('>> Đã xóa profile MyPassword');
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
-- Drop tablespace
PROMPT
PROMPT Bước 6: Drop tablespace
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE QLNS_DATA INCLUDING
CONTENTS AND DATAFILES CASCADE CONSTRAINTS';
DBMS_OUTPUT.PUT_LINE('>> Đã xóa tablespace QLNS_DATA');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('!! Tablespace: ' || SQLERRM);
END;
/
PROMPT
PROMPT
=========================================================
PROMPT === FILE 1 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT Môi trường đã được dọn dẹp sạch sẽ
PROMPT Sẵn sàng chạy FILE 2
-- =========================================================
-- FILE 2: CREATE QLNS ENVIRONMENT
-- Tạo môi trường: Tablespace, Profile, Users, Roles
-- CHẠY AS: SYS (SYSDBA)
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
PROMPT
=========================================================
PROMPT === FILE 2: CREATE QLNS ENVIRONMENT ===
PROMPT
=========================================================
ALTER SESSION SET CONTAINER = ORCLPDB;
-- Tạo Tablespace
PROMPT
PROMPT Bước 1: Tạo Tablespace
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE QLNS_DATA INCLUDING
CONTENTS AND DATAFILES';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE TABLESPACE QLNS_DATA
DATAFILE 'C:\USERS\ADMINISTRATOR\
WINDOWS.X64_193000_DB_HOME\DATABASE\QLNS_DATA_01.DBF'
SIZE 100M
AUTOEXTEND ON NEXT 10M MAXSIZE 500M;
PROMPT >> Đã tạo tablespace QLNS_DATA
-- Tạo Profile
PROMPT
PROMPT Bước 2: Tạo Profile
BEGIN
EXECUTE IMMEDIATE 'DROP PROFILE MyPassword CASCADE';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;
CREATE PROFILE MyPassword LIMIT
SESSIONS_PER_USER UNLIMITED
CPU_PER_SESSION UNLIMITED
CONNECT_TIME 60
IDLE_TIME 30
LOGICAL_READS_PER_SESSION UNLIMITED
FAILED_LOGIN_ATTEMPTS 3
PASSWORD_LIFE_TIME 60
PASSWORD_REUSE_TIME 180
PASSWORD_LOCK_TIME 1
PASSWORD_GRACE_TIME 7;
PROMPT >> Đã tạo profile MyPassword
-- Kiểm tra
PROMPT
PROMPT Kiểm tra users
SELECT username, account_status, profile
FROM dba_users
WHERE username IN
('QLNS','ADMIN','HOATV','MAIANH','NGUYEN','PHUONG','QUOC');
PROMPT
PROMPT
=========================================================
PROMPT === FILE 2 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT Môi trường đã sẵn sàng
PROMPT Disconnect SYS, Connect QLNS để chạy FILE 3
-- =========================================================
-- FILE 3: CREATE SCHEMA QLNS
-- Tạo bảng, dữ liệu, functions, procedures, triggers, VPD
-- CHẠY AS: QLNS
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
PROMPT
=========================================================
PROMPT === FILE 3: CREATE SCHEMA QLNS ===
PROMPT
=========================================================
ALTER SESSION SET CONTAINER = ORCLPDB;
SHOW USER;
-- Xóa toàn bộ bảng cũ
PROMPT
PROMPT Bước 1: Xóa bảng cũ (nếu có)
BEGIN
FOR t IN (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'DROP TABLE ' || t.table_name || ' CASCADE
CONSTRAINTS';
END LOOP;
DBMS_OUTPUT.PUT_LINE('>> Đã xóa tất cả bảng cũ');
END;
/
-- Tạo bảng SACH
PROMPT
PROMPT Bước 2: Tạo bảng SACH
CREATE TABLE Sach (
MaSach VARCHAR2(10) CONSTRAINT PK_Sach PRIMARY KEY,
TenSach NVARCHAR2(100) NOT NULL,
TacGia NVARCHAR2(100),
NhaXuatBan NVARCHAR2(100),
NamXuatBan NUMBER(4) CHECK (NamXuatBan >= 1900),
TheLoai NVARCHAR2(50),
GiaBan NUMBER(10,2) CHECK (GiaBan >= 0),
SoLuongTon NUMBER(10) DEFAULT 0 CHECK (SoLuongTon >= 0),
MoTa NVARCHAR2(1000),
HinhBia NVARCHAR2(200),
TrangThaiKhuyenMai NVARCHAR2(50)
);
PROMPT >> Đã tạo bảng SACH
-- Tạo bảng KHACHHANG
PROMPT
PROMPT Bước 3: Tạo bảng KHACHHANG
CREATE TABLE KhachHang (
MaKH VARCHAR2(10) CONSTRAINT PK_KhachHang PRIMARY KEY,
HoTen NVARCHAR2(100) NOT NULL,
SoDienThoai VARCHAR2(15),
Email NVARCHAR2(100),
DiaChi NVARCHAR2(200),
DiemTichLuy NUMBER(10) DEFAULT 0 CHECK (DiemTichLuy >= 0),
NgayDangKy DATE DEFAULT SYSDATE
);
ALTER TABLE KhachHang ADD (
EMAIL_ENC1 VARCHAR2(1000),
EMAIL_ENC2 VARCHAR2(1000)
);
PROMPT >> Đã tạo bảng KHACHHANG
-- Tạo bảng NHANVIEN
PROMPT
PROMPT Bước 4: Tạo bảng NHANVIEN
CREATE TABLE NhanVien (
MaNV VARCHAR2(10) CONSTRAINT PK_NhanVien PRIMARY KEY,
HoTen NVARCHAR2(100) NOT NULL,
ChucVu NVARCHAR2(50),
TenDangNhap NVARCHAR2(50) UNIQUE NOT NULL,
MatKhau_HASH NVARCHAR2(256),
Salt NVARCHAR2(100) NOT NULL,
QuyenHan NVARCHAR2(10) DEFAULT 'User' CHECK (QuyenHan IN
('Admin','User')),
NgayVaoLam DATE DEFAULT SYSDATE,
MatKhau_Goc NVARCHAR2(256)
);
PROMPT >> Đã tạo bảng NHANVIEN
-- Tạo bảng HOADON
PROMPT
PROMPT Bước 5: Tạo bảng HOADON
CREATE TABLE HoaDon (
MaHD VARCHAR2(10) CONSTRAINT PK_HoaDon PRIMARY KEY,
NgayLap DATE DEFAULT SYSDATE,
MaKH VARCHAR2(10),
MaNV VARCHAR2(10),
TongTien NUMBER(12,2) DEFAULT 0 CHECK (TongTien >= 0),
ChietKhau NUMBER(5,2) DEFAULT 0 CHECK (ChietKhau BETWEEN 0 AND
100),
Thue NUMBER(5,2) DEFAULT 0 CHECK (Thue BETWEEN 0 AND 100),
TrangThai NVARCHAR2(30) DEFAULT 'CHO_XAC_NHAN',
ChuKyRSA CLOB,
NgayKy DATE,
CONSTRAINT FK_HoaDon_KhachHang FOREIGN KEY (MaKH) REFERENCES
KhachHang(MaKH) ON DELETE SET NULL,
CONSTRAINT FK_HoaDon_NhanVien FOREIGN KEY (MaNV) REFERENCES
NhanVien(MaNV) ON DELETE SET NULL
);
PROMPT >> Đã tạo bảng HOADON
-- Tạo bảng CHITIETHOADON
PROMPT
PROMPT Bước 6: Tạo bảng CHITIETHOADON
CREATE TABLE ChiTietHoaDon (
MaCTHD VARCHAR2(10) CONSTRAINT PK_ChiTietHoaDon PRIMARY KEY,
MaHD VARCHAR2(10) NOT NULL,
MaSach VARCHAR2(10) NOT NULL,
SoLuong NUMBER(10) DEFAULT 1 CHECK (SoLuong > 0),
DonGia NUMBER(10,2) CHECK (DonGia >= 0),
CONSTRAINT FK_CTHD_HoaDon FOREIGN KEY (MaHD) REFERENCES
HoaDon(MaHD) ON DELETE CASCADE,
CONSTRAINT FK_CTHD_Sach FOREIGN KEY (MaSach) REFERENCES
Sach(MaSach) ON DELETE SET NULL
);
PROMPT >> Đã tạo bảng CHITIETHOADON
-- Tạo bảng KEYSTORE
PROMPT
PROMPT Bước 7: Tạo bảng KEYSTORE
CREATE TABLE KeyStore (
KeyID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
PublicKey CLOB,
PrivateKey CLOB,
CreatedAt DATE DEFAULT SYSDATE
);
PROMPT >> Đã tạo bảng KEYSTORE
-- Tạo bảng LOGHEOTHONG
PROMPT
PROMPT Bước 8: Tạo bảng LOGHETHONG
CREATE TABLE LogHeThong (
MaLog VARCHAR2(10) CONSTRAINT PK_LogHeThong PRIMARY KEY,
ThaoTac NVARCHAR2(100),
ThoiGian DATE DEFAULT SYSDATE,
MaNV VARCHAR2(10),
MoTa NVARCHAR2(1000),
CONSTRAINT FK_Log_NhanVien FOREIGN KEY (MaNV) REFERENCES
NhanVien(MaNV) ON DELETE SET NULL
);
PROMPT >> Đã tạo bảng LOGHETHONG
-- Tạo Sequence + Trigger cho NHANVIEN
PROMPT
PROMPT Bước 9: Tạo sequence cho NHANVIEN
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE NhanVien_SEQ';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
CREATE SEQUENCE NhanVien_SEQ
START WITH 7
INCREMENT BY 1
NOCACHE
NOCYCLE;
PROMPT >> Đã tạo sequence NhanVien_SEQ
CREATE OR REPLACE TRIGGER TRG_NHANVIEN_AUTOMANV
BEFORE INSERT ON NhanVien
FOR EACH ROW
BEGIN
IF :[Link] IS NULL OR TRIM(:[Link]) = '' THEN
:[Link] := 'NV' || LPAD(NhanVien_SEQ.NEXTVAL, 3, '0');
END IF;
END;
/
PROMPT >> Đã tạo trigger TRG_NHANVIEN_AUTOMANV
-- Tạo hàm HASH password
PROMPT
PROMPT Bước 10: Tạo hàm hash password
-- Lệnh ALTER được comment vì cột MatKhau_HASH đã cho phép NULL từ
CREATE TABLE
-- ALTER TABLE NhanVien MODIFY (MatKhau_HASH NVARCHAR2(256)
NULL);
CREATE OR REPLACE FUNCTION FN_HASH_PASSWORD(p_password
VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN RAWTOHEX(DBMS_CRYPTO.HASH(
UTL_I18N.STRING_TO_RAW(p_password, 'AL32UTF8'),
DBMS_CRYPTO.HASH_SH256
));
END;
/
PROMPT >> Đã tạo function FN_HASH_PASSWORD
CREATE OR REPLACE PROCEDURE PROC_HASH_MATKHAU_NV
IS
BEGIN
FOR r IN (SELECT MaNV, MatKhau_Goc FROM NhanVien WHERE
MatKhau_Goc IS NOT NULL) LOOP
UPDATE NhanVien
SET MatKhau_HASH = FN_HASH_PASSWORD(r.MatKhau_Goc)
WHERE MaNV = [Link];
END LOOP;
COMMIT;
END;
/
PROMPT >> Đã tạo procedure PROC_HASH_MATKHAU_NV
-- Tạo hàm mã hóa AES
PROMPT
PROMPT Bước 11: Tạo hàm mã hóa AES
CREATE OR REPLACE FUNCTION encrypt_email_aes(p_email IN VARCHAR2)
RETURN CLOB
IS
l_key_raw RAW(32);
l_iv_raw RAW(16);
l_enc_raw RAW(32767);
l_enc_b64 VARCHAR2(32767);
l_key_b64 VARCHAR2(32767);
l_iv_b64 VARCHAR2(32767);
l_json CLOB;
BEGIN
l_key_raw := DBMS_CRYPTO.RANDOMBYTES(32);
l_iv_raw := DBMS_CRYPTO.RANDOMBYTES(16);
l_enc_raw := DBMS_CRYPTO.ENCRYPT(
src => UTL_I18N.STRING_TO_RAW(NVL(p_email, ''), 'AL32UTF8'),
typ => DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC +
DBMS_CRYPTO.PAD_PKCS5,
key => l_key_raw,
iv => l_iv_raw
);
l_enc_b64 :=
REPLACE(UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCOD
E(l_enc_raw)), CHR(10));
l_key_b64 :=
REPLACE(UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCOD
E(l_key_raw)), CHR(10));
l_iv_b64 :=
REPLACE(UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCOD
E(l_iv_raw)), CHR(10));
l_json := TO_CLOB('{"ciphertext_b64":"') || l_enc_b64 ||
'","aes_key_b64":"' || l_key_b64 ||
'","iv_b64":"' || l_iv_b64 || '"}';
RETURN l_json;
END;
/
PROMPT >> Đã tạo function encrypt_email_aes
PROMPT
PROMPT
=========================================================
PROMPT === PHẦN 1 HOÀN THÀNH: CẤU TRÚC BẢNG ===
PROMPT
=========================================================
-- =========================================================
-- PHẦN 2: INSERT DỮ LIỆU MẪU
-- =========================================================
-- Insert SACH
PROMPT
PROMPT Bước 12: Insert dữ liệu SACH
INSERT ALL
INTO Sach VALUES ('S001', N'Truyện Kiều', N'Nguyễn Du', N'NXB Văn Học',
2015, N'Truyện thơ', 55000, 30, N'Tác phẩm kinh điển', 'truyen_kieu.jpg', N'Không')
INTO Sach VALUES ('S002', N'Doraemon Tập 1', N'Fujiko F. Fujio', N'NXB Kim
Đồng', 2020, N'Thiếu nhi', 25000, 50, N'Truyện tranh Nhật Bản', '[Link]',
N'Không')
INTO Sach VALUES ('S003', N'Conan Tập 100', N'Aoyama Gosho', N'NXB Kim
Đồng', 2022, N'Truyện tranh', 28000, 40, N'Thám tử Conan', '[Link]', N'Giảm
giá')
INTO Sach VALUES ('S004', N'Lập Trình C# Cơ Bản', N'Nguyễn Văn A', N'NXB
CNTT', 2023, N'Giáo trình', 95000, 20, N'Học lập trình C#', '[Link]',
N'Không')
SELECT * FROM dual;
PROMPT >> Đã insert 4 sách
-- Insert KHACHHANG
PROMPT
PROMPT Bước 13: Insert dữ liệu KHACHHANG
INSERT ALL
INTO KhachHang VALUES ('KH001', N'Nguyễn Văn Minh', '0912345678',
'minh@[Link]', N'Hà Nội', 120, SYSDATE - 20, NULL, NULL)
INTO KhachHang VALUES ('KH002', N'Lê Thị Hạnh', '0987654321',
'hanh@[Link]', N'Đà Nẵng', 300, SYSDATE - 50, NULL, NULL)
INTO KhachHang VALUES ('KH003', N'Phạm Quốc Cường', '0905123456',
'cuong@[Link]', N'Hồ Chí Minh', 50, SYSDATE - 10, NULL, NULL)
SELECT * FROM dual;
PROMPT >> Đã insert 3 khách hàng
-- Insert NHANVIEN
PROMPT
PROMPT Bước 14: Insert dữ liệu NHANVIEN
INSERT ALL
INTO NhanVien VALUES ('NV001', N'Nguyễn Thị Lan', N'Quản lý', 'admin', NULL,
'salt_abc', 'Admin', SYSDATE - 100, 'admin')
INTO NhanVien VALUES ('NV002', N'Trần Văn Hòa', N'Nhân viên bán hàng',
'hoatv', NULL, 'salt_xyz', 'User', SYSDATE - 20, 'user01')
INTO NhanVien VALUES ('NV003', N'Phạm Mai Anh', N'Nhân viên kho', 'maianh',
NULL, 'salt_def', 'User', SYSDATE - 15, 'user01')
INTO NhanVien VALUES ('NV004', N'Trần Bảo Nguyên', N'Quản lý', 'Nguyen',
NULL, 'salt_ghi', 'Admin', SYSDATE - 15, '123')
INTO NhanVien VALUES ('NV005', N'Trần Thị Minh Phương', N'Quản lý', 'Phuong',
NULL, 'salt_jkl', 'Admin', SYSDATE - 15, '123')
INTO NhanVien VALUES ('NV006', N'Lê Hồng Quốc', N'Quản lý', 'Quoc', NULL,
'salt_mno', 'Admin', SYSDATE - 15, '123')
SELECT * FROM dual;
PROMPT >> Đã insert 6 nhân viên
-- Cập nhật QuyenHan
UPDATE NhanVien SET QuyenHan = 'Admin' WHERE TenDangNhap IN ('admin',
'Nguyen', 'Phuong', 'Quoc');
UPDATE NhanVien SET QuyenHan = 'User' WHERE TenDangNhap IN ('hoatv',
'maianh');
COMMIT;
PROMPT >> Đã cập nhật QuyenHan
-- Insert HOADON
PROMPT
PROMPT Bước 15: Insert dữ liệu HOADON
INSERT ALL
INTO HoaDon VALUES ('HD001', SYSDATE - 12, 'KH001', 'NV002', 150000, 0, 5,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD002', SYSDATE - 10, 'KH002', 'NV002', 28000, 10, 0,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD003', SYSDATE - 8, 'KH003', 'NV003', 110000, 5, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD004', SYSDATE - 7, 'KH001', 'NV005', 78000, 0, 0,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD005', SYSDATE - 6, 'KH002', 'NV004', 55000, 0, 10,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD006', SYSDATE - 5, 'KH003', 'NV001', 120000, 15, 5,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD007', SYSDATE - 4, 'KH001', 'NV002', 56000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD008', SYSDATE - 3, 'KH003', 'NV003', 75000, 0, 5,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD009', SYSDATE - 2, 'KH002', 'NV006', 205000, 5, 0,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD010', SYSDATE - 1, 'KH001', 'NV005', 95000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD011', SYSDATE, 'KH003', 'NV004', 55000, 0, 0,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD012', SYSDATE, 'KH002', 'NV002', 123000, 10, 5,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD013', SYSDATE, 'KH001', 'NV003', 80000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
SELECT * FROM dual;
PROMPT >> Đã insert 13 hóa đơn
-- Insert CHITIETHOADON
PROMPT
PROMPT Bước 16: Insert dữ liệu CHITIETHOADON
INSERT ALL
INTO ChiTietHoaDon VALUES ('CT001', 'HD001', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT002', 'HD001', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT003', 'HD002', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT004', 'HD003', 'S001', 2, 55000)
INTO ChiTietHoaDon VALUES ('CT005', 'HD004', 'S002', 2, 25000)
INTO ChiTietHoaDon VALUES ('CT006', 'HD004', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT007', 'HD005', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT008', 'HD006', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT009', 'HD006', 'S002', 1, 25000)
INTO ChiTietHoaDon VALUES ('CT010', 'HD007', 'S003', 2, 28000)
INTO ChiTietHoaDon VALUES ('CT011', 'HD008', 'S002', 3, 25000)
INTO ChiTietHoaDon VALUES ('CT012', 'HD009', 'S001', 2, 55000)
INTO ChiTietHoaDon VALUES ('CT013', 'HD009', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT014', 'HD010', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT015', 'HD011', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT016', 'HD012', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT017', 'HD012', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT018', 'HD013', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT019', 'HD013', 'S002', 1, 25000)
SELECT * FROM dual;
PROMPT >> Đã insert 19 chi tiết hóa đơn
COMMIT;
-- Hash mật khẩu
PROMPT
PROMPT Bước 17: Hash mật khẩu nhân viên
EXEC PROC_HASH_MATKHAU_NV;
PROMPT >> Đã hash mật khẩu
-- Kiểm tra dữ liệu
PROMPT
PROMPT Bước 18: Kiểm tra dữ liệu
SELECT COUNT(*) AS TOTAL_SACH FROM Sach;
SELECT COUNT(*) AS TOTAL_KHACHHANG FROM KhachHang;
SELECT COUNT(*) AS TOTAL_NHANVIEN FROM NhanVien;
SELECT COUNT(*) AS TOTAL_HOADON FROM HoaDon;
SELECT COUNT(*) AS TOTAL_CTHD FROM ChiTietHoaDon;
PROMPT
PROMPT
=========================================================
PROMPT === PHẦN 2 HOÀN THÀNH: DỮ LIỆU ===
PROMPT
=========================================================
-- =========================================================
-- FILE 3: CREATE SCHEMA QLNS
-- Tạo bảng, dữ liệu, functions, procedures, triggers, VPD
-- CHẠY AS: QLNS
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
PROMPT
=========================================================
PROMPT === FILE 3: CREATE SCHEMA QLNS ===
PROMPT
=========================================================
ALTER SESSION SET CONTAINER = ORCLPDB;
SHOW USER;
PROMPT
PROMPT
=========================================================
PROMPT === PHẦN 1 HOÀN THÀNH: CẤU TRÚC BẢNG ===
PROMPT
=========================================================
-- =========================================================
-- PHẦN 2: INSERT DỮ LIỆU MẪU
-- =========================================================
-- Insert SACH
PROMPT
PROMPT Bước 12: Insert dữ liệu SACH
INSERT ALL
INTO Sach VALUES ('S001', N'Truyện Kiều', N'Nguyễn Du', N'NXB Văn Học',
2015, N'Truyện thơ', 55000, 30, N'Tác phẩm kinh điển', 'truyen_kieu.jpg', N'Không')
INTO Sach VALUES ('S002', N'Doraemon Tập 1', N'Fujiko F. Fujio', N'NXB Kim
Đồng', 2020, N'Thiếu nhi', 25000, 50, N'Truyện tranh Nhật Bản', '[Link]',
N'Không')
INTO Sach VALUES ('S003', N'Conan Tập 100', N'Aoyama Gosho', N'NXB Kim
Đồng', 2022, N'Truyện tranh', 28000, 40, N'Thám tử Conan', '[Link]', N'Giảm
giá')
INTO Sach VALUES ('S004', N'Lập Trình C# Cơ Bản', N'Nguyễn Văn A', N'NXB
CNTT', 2023, N'Giáo trình', 95000, 20, N'Học lập trình C#', '[Link]',
N'Không')
SELECT * FROM dual;
PROMPT >> Đã insert 4 sách
-- Insert KHACHHANG
PROMPT
PROMPT Bước 13: Insert dữ liệu KHACHHANG
INSERT ALL
INTO KhachHang VALUES ('KH001', N'Nguyễn Văn Minh', '0912345678',
'minh@[Link]', N'Hà Nội', 120, SYSDATE - 20, NULL, NULL)
INTO KhachHang VALUES ('KH002', N'Lê Thị Hạnh', '0987654321',
'hanh@[Link]', N'Đà Nẵng', 300, SYSDATE - 50, NULL, NULL)
INTO KhachHang VALUES ('KH003', N'Phạm Quốc Cường', '0905123456',
'cuong@[Link]', N'Hồ Chí Minh', 50, SYSDATE - 10, NULL, NULL)
SELECT * FROM dual;
PROMPT >> Đã insert 3 khách hàng
-- Insert NHANVIEN
PROMPT
PROMPT Bước 14: Insert dữ liệu NHANVIEN
INSERT ALL
INTO NhanVien VALUES ('NV001', N'Nguyễn Thị Lan', N'Quản lý', 'admin',
NULL, 'salt_abc', 'Admin', SYSDATE - 100, 'admin')
INTO NhanVien VALUES ('NV002', N'Trần Văn Hòa', N'Nhân viên bán hàng',
'hoatv', NULL, 'salt_xyz', 'User', SYSDATE - 20, 'user01')
INTO NhanVien VALUES ('NV003', N'Phạm Mai Anh', N'Nhân viên kho',
'maianh', NULL, 'salt_def', 'User', SYSDATE - 15, 'user01')
INTO NhanVien VALUES ('NV004', N'Trần Bảo Nguyên', N'Quản lý', 'Nguyen',
NULL, 'salt_ghi', 'Admin', SYSDATE - 15, '123')
INTO NhanVien VALUES ('NV005', N'Trần Thị Minh Phương', N'Quản lý',
'Phuong', NULL, 'salt_jkl', 'Admin', SYSDATE - 15, '123')
INTO NhanVien VALUES ('NV006', N'Lê Hồng Quốc', N'Quản lý', 'Quoc', NULL,
'salt_mno', 'Admin', SYSDATE - 15, '123')
SELECT * FROM dual;
PROMPT >> Đã insert 6 nhân viên
-- Insert HOADON
PROMPT
PROMPT Bước 15: Insert dữ liệu HOADON
INSERT ALL
INTO HoaDon VALUES ('HD001', SYSDATE - 12, 'KH001', 'NV002', 150000, 0,
5, 'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD002', SYSDATE - 10, 'KH002', 'NV002', 28000, 10,
0, 'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD003', SYSDATE - 8, 'KH003', 'NV003', 110000, 5, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD004', SYSDATE - 7, 'KH001', 'NV005', 78000, 0, 0,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD005', SYSDATE - 6, 'KH002', 'NV004', 55000, 0, 10,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD006', SYSDATE - 5, 'KH003', 'NV001', 120000, 15,
5, 'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD007', SYSDATE - 4, 'KH001', 'NV002', 56000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD008', SYSDATE - 3, 'KH003', 'NV003', 75000, 0, 5,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD009', SYSDATE - 2, 'KH002', 'NV006', 205000, 5, 0,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD010', SYSDATE - 1, 'KH001', 'NV005', 95000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD011', SYSDATE, 'KH003', 'NV004', 55000, 0, 0,
'DA_THANH_TOAN', NULL, NULL)
INTO HoaDon VALUES ('HD012', SYSDATE, 'KH002', 'NV002', 123000, 10, 5,
'DA_XAC_NHAN', NULL, NULL)
INTO HoaDon VALUES ('HD013', SYSDATE, 'KH001', 'NV003', 80000, 0, 0,
'CHO_XAC_NHAN', NULL, NULL)
SELECT * FROM dual;
PROMPT >> Đã insert 13 hóa đơn
-- Insert CHITIETHOADON
PROMPT
PROMPT Bước 16: Insert dữ liệu CHITIETHOADON
INSERT ALL
INTO ChiTietHoaDon VALUES ('CT001', 'HD001', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT002', 'HD001', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT003', 'HD002', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT004', 'HD003', 'S001', 2, 55000)
INTO ChiTietHoaDon VALUES ('CT005', 'HD004', 'S002', 2, 25000)
INTO ChiTietHoaDon VALUES ('CT006', 'HD004', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT007', 'HD005', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT008', 'HD006', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT009', 'HD006', 'S002', 1, 25000)
INTO ChiTietHoaDon VALUES ('CT010', 'HD007', 'S003', 2, 28000)
INTO ChiTietHoaDon VALUES ('CT011', 'HD008', 'S002', 3, 25000)
INTO ChiTietHoaDon VALUES ('CT012', 'HD009', 'S001', 2, 55000)
INTO ChiTietHoaDon VALUES ('CT013', 'HD009', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT014', 'HD010', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT015', 'HD011', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT016', 'HD012', 'S003', 1, 28000)
INTO ChiTietHoaDon VALUES ('CT017', 'HD012', 'S004', 1, 95000)
INTO ChiTietHoaDon VALUES ('CT018', 'HD013', 'S001', 1, 55000)
INTO ChiTietHoaDon VALUES ('CT019', 'HD013', 'S002', 1, 25000)
SELECT * FROM dual;
PROMPT >> Đã insert 19 chi tiết hóa đơn
COMMIT;
PROMPT
PROMPT
=========================================================
PROMPT === PHẦN 2 HOÀN THÀNH: DỮ LIỆU ===
PROMPT
=========================================================
-- =========================================================
-- PHẦN 3: VPD/MAC (VIRTUAL PRIVATE DATABASE)
-- =========================================================
DBMS_SESSION.SET_CONTEXT('CTX_NHASACH','USER_QUYENHAN',v_qu
yenhan);
END;
/
PROMPT >> Đã tạo procedure PROC_SET_NHASACH_CTX
-- Tạo context
PROMPT
PROMPT Bước 21: Tạo context
CREATE OR REPLACE CONTEXT CTX_NHASACH USING
QLNS.PROC_SET_NHASACH_CTX;
PROMPT >> Đã tạo context CTX_NHASACH
ELSE
RETURN '1=2';
END IF;
END;
/
PROMPT >> Đã tạo function FNC_POLICY_HOADON
-- ROLE_NHANVIEN_GIAO_DICH
EXECUTE IMMEDIATE 'GRANT SELECT, INSERT, UPDATE, DELETE ON
[Link] TO ROLE_NHANVIEN_GIAO_DICH';
EXECUTE IMMEDIATE 'GRANT SELECT, INSERT, UPDATE, DELETE ON
[Link] TO ROLE_NHANVIEN_GIAO_DICH';
EXECUTE IMMEDIATE 'GRANT SELECT, UPDATE ON [Link] TO
ROLE_NHANVIEN_GIAO_DICH';
EXECUTE IMMEDIATE 'GRANT SELECT ON [Link] TO
ROLE_NHANVIEN_GIAO_DICH';
-- ROLE_NHANVIEN_KHO
EXECUTE IMMEDIATE 'GRANT SELECT, UPDATE ON [Link] TO
ROLE_NHANVIEN_KHO';
EXECUTE IMMEDIATE 'GRANT SELECT ON [Link] TO
ROLE_NHANVIEN_KHO';
EXECUTE IMMEDIATE 'GRANT SELECT ON [Link] TO
ROLE_NHANVIEN_KHO';
PROMPT
PROMPT
=========================================================
PROMPT === FILE 3 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT Đã tạo:
PROMPT - 8 bảng
PROMPT - Dữ liệu mẫu
PROMPT - Hash password
PROMPT - Encryption function
PROMPT - VPD/MAC policy
PROMPT
PROMPT MÔI TRƯỜNG QLNS ĐÃ SẴN SÀNG!
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT - Chạy CÂU 11 (OLS - 4 files)
PROMPT - Chạy CÂU 12 (Auditing - 3 files)
PROMPT
=========================================================
-- =========================================================
-- CÂU 11: ORACLE LABEL SECURITY - FILE 01
-- Cấp quyền OLS cho user QLNS
-- CHẠY AS: SYS (SYSDBA)
-- Thời gian: 1 phút
-- =========================================================
SET SERVEROUTPUT ON;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 11 - FILE 01: SETUP OLS ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Kiểm tra OLS đã cài chưa
PROMPT
=========================================================
SELECT comp_name, version, status
FROM dba_registry
WHERE comp_id = 'OLS';
PROMPT
PROMPT LƯU Ý: Nếu không có kết quả hoặc STATUS ≠ VALID:
PROMPT 1. Chạy trong SQL*Plus: @?/rdbms/admin/[Link]
PROMPT 2. Chạy: EXEC LBACSYS.CONFIGURE_OLS;
PROMPT 3. Chạy: EXEC LBACSYS.OLS_ENFORCEMENT.ENABLE_OLS;
PROMPT
PROMPT
PROMPT Bước 2: Cấp quyền OLS cho QLNS
PROMPT
=========================================================
-- Quyền 2: sa_components
GRANT EXECUTE ON LBACSYS.sa_components TO QLNS;
PROMPT ✓ sa_components
-- Quyền 3: sa_label_admin
GRANT EXECUTE ON LBACSYS.sa_label_admin TO QLNS;
PROMPT ✓ sa_label_admin
-- Quyền 5: sa_user_admin
GRANT EXECUTE ON LBACSYS.sa_user_admin TO QLNS;
PROMPT ✓ sa_user_admin
-- Quyền 6: sa_sysdba
GRANT EXECUTE ON LBACSYS.sa_sysdba TO QLNS;
PROMPT ✓ sa_sysdba
PROMPT
PROMPT
=========================================================
PROMPT === FILE 01 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT ✓ Đã cấp đầy đủ 7 quyền OLS cho user QLNS
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Disconnect SYS
PROMPT 2. Connect LBACSYS (username: LBACSYS, password: <tìm hoặc
reset>)
PROMPT 3. Chạy FILE 02
PROMPT
PROMPT Nếu không biết password LBACSYS:
PROMPT As SYS: ALTER USER LBACSYS IDENTIFIED BY lbacsys123;
PROMPT
-- =========================================================
-- CÂU 11: ORACLE LABEL SECURITY - FILE 02
-- Tạo OLS Policy và áp dụng vào bảng NHANVIEN
-- CHẠY AS: LBACSYS
-- Thời gian: 2 phút
-- =========================================================
SET SERVEROUTPUT ON;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 11 - FILE 02: CREATE POLICY ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Xóa policy cũ (nếu có)
PROMPT
=========================================================
BEGIN
-- Xóa policy
BEGIN
sa_sysdba.drop_policy(
policy_name => 'NHANSU_POL',
drop_column => TRUE
);
DBMS_OUTPUT.PUT_LINE('✓ Đã xóa policy cũ: NHANSU_POL');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12461 THEN
DBMS_OUTPUT.PUT_LINE('○ Policy NHANSU_POL chưa tồn tại');
ELSE
DBMS_OUTPUT.PUT_LINE('! ' || SQLERRM);
END IF;
END;
PROMPT
PROMPT Bước 2: Tạo policy NHANSU_POL
PROMPT
=========================================================
BEGIN
sa_sysdba.create_policy(
policy_name => 'NHANSU_POL',
column_name => 'OLS_LABEL',
default_options => 'NO_CONTROL'
);
DBMS_OUTPUT.PUT_LINE('✓ Policy: NHANSU_POL');
DBMS_OUTPUT.PUT_LINE(' Column: OLS_LABEL');
DBMS_OUTPUT.PUT_LINE(' Owner: LBACSYS');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12447 THEN
DBMS_OUTPUT.PUT_LINE('! Policy đã tồn tại, tiếp tục...');
ELSE
RAISE;
END IF;
END;
/
PROMPT
PROMPT Bước 3: Tạo 3 Levels (mức độ bảo mật)
PROMPT
=========================================================
BEGIN
-- Level 1: PUBLIC (1000)
BEGIN
sa_components.create_level(
policy_name => 'NHANSU_POL',
level_num => 1000,
short_name => 'PUB',
long_name => 'PUBLIC'
);
DBMS_OUTPUT.PUT_LINE('✓ Level 1: PUBLIC (1000)');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12422 THEN
DBMS_OUTPUT.PUT_LINE('○ Level PUBLIC đã tồn tại');
ELSE RAISE;
END IF;
END;
PROMPT
PROMPT Bước 4: Tạo 3 Compartments (phòng ban)
PROMPT
=========================================================
BEGIN
-- Compartment 1: Quản lý (100)
BEGIN
sa_components.create_compartment(
policy_name => 'NHANSU_POL',
comp_num => 100,
short_name => 'QL',
long_name => 'QUANLY'
);
DBMS_OUTPUT.PUT_LINE('✓ Compartment 1: QUANLY (100)');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12423 THEN
DBMS_OUTPUT.PUT_LINE('○ Compartment QUANLY đã tồn tại');
ELSE RAISE;
END IF;
END;
PROMPT
PROMPT Bước 5: Tạo 5 Data Labels
PROMPT
=========================================================
BEGIN
-- Label 1: PUBLIC (tag 10)
BEGIN
sa_label_admin.create_label(
policy_name => 'NHANSU_POL',
label_tag => 10,
label_value => 'PUB',
data_label => TRUE
);
DBMS_OUTPUT.PUT_LINE('✓ Label 10: PUB');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12424 THEN
DBMS_OUTPUT.PUT_LINE('○ Label PUB đã tồn tại');
ELSE RAISE;
END IF;
END;
PROMPT
PROMPT Bước 6: Áp dụng policy vào bảng NHANVIEN
PROMPT
=========================================================
BEGIN
BEGIN
LBAC_POLICY_ADMIN.apply_table_policy(
policy_name => 'NHANSU_POL',
schema_name => 'QLNS',
table_name => 'NHANVIEN',
table_options => 'READ_CONTROL',
label_function => NULL,
predicate => NULL
);
DBMS_OUTPUT.PUT_LINE('✓ Đã apply policy vào [Link]');
DBMS_OUTPUT.PUT_LINE(' Cột OLS_LABEL được thêm tự động');
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -12474 THEN
DBMS_OUTPUT.PUT_LINE('○ Policy đã được apply trước đó');
ELSE
DBMS_OUTPUT.PUT_LINE('! Lỗi: ' || SQLERRM);
RAISE;
END IF;
END;
END;
/
COMMIT;
PROMPT
PROMPT
=========================================================
PROMPT === FILE 02 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT ✓ Policy: NHANSU_POL (owner: LBACSYS)
PROMPT ✓ 3 Levels: PUB, CONF, SEC
PROMPT ✓ 3 Compartments: QL, BH, KHO
PROMPT ✓ 5 Labels: 10, 20, 30, 40, 50
PROMPT ✓ Applied to: [Link]
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Disconnect LBACSYS
PROMPT 2. Connect QLNS (username: QLNS, password: qlns)
PROMPT 3. Chạy FILE 03A (gán data labels)
PROMPT
-- =========================================================
-- CÂU 11: ORACLE LABEL SECURITY - FILE 03A
-- Gán OLS labels cho DỮ LIỆU (bảng NHANVIEN)
-- CHẠY AS: QLNS
-- Thời gian: 1 phút
-- =========================================================
SET SERVEROUTPUT ON;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 11 - FILE 03A: GÁN DATA LABELS ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Xem dữ liệu hiện tại
PROMPT
=========================================================
SELECT MANV, HOTEN, CHUCVU, TENDANGNHAP, QUYENHAN,
OLS_LABEL
FROM NHANVIEN
ORDER BY MANV;
PROMPT
PROMPT Bước 2: Gán OLS_LABEL cho từng nhân viên
PROMPT
=========================================================
COMMIT;
PROMPT
PROMPT Bước 3: Kiểm tra kết quả
PROMPT
=========================================================
SELECT
MANV,
HOTEN,
TENDANGNHAP,
OLS_LABEL,
LABEL_TO_CHAR(OLS_LABEL) AS LABEL_NAME
FROM NHANVIEN
ORDER BY OLS_LABEL DESC, MANV;
PROMPT
PROMPT
=========================================================
PROMPT === FILE 03A HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT ✓ Đã gán OLS_LABEL cho 6 nhân viên:
PROMPT - 4 admin (admin, Nguyen, Phuong, Quoc) → SEC (50)
PROMPT - 1 kho (hoatv) → CONF:KHO (30)
PROMPT - 1 bán hàng (maianh) → CONF:BH (20)
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Disconnect QLNS
PROMPT 2. Connect LBACSYS (username: LBACSYS)
PROMPT 3. Chạy FILE 03B (gán user labels)
PROMPT
-- =========================================================
-- CÂU 11: ORACLE LABEL SECURITY - FILE 03B
-- Gán OLS labels cho DATABASE USERS
-- CHẠY AS: LBACSYS
-- Thời gian: 1 phút
-- =========================================================
SET SERVEROUTPUT ON;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 11 - FILE 03B: GÁN USER LABELS ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Gán user labels cho 7 database users
PROMPT
=========================================================
BEGIN
-- User QLNS - Owner, thấy tất cả
sa_user_admin.set_user_labels(
policy_name => 'NHANSU_POL',
user_name => 'QLNS',
max_read_label => 'SEC',
max_write_label => 'SEC',
def_label => 'SEC',
row_label => 'SEC'
);
DBMS_OUTPUT.PUT_LINE('✓ QLNS → SEC (thấy tất cả)');
-- User ADMIN
sa_user_admin.set_user_labels(
policy_name => 'NHANSU_POL',
user_name => 'ADMIN',
max_read_label => 'SEC',
def_label => 'SEC',
row_label => 'SEC'
);
DBMS_OUTPUT.PUT_LINE('✓ ADMIN → SEC');
-- User NGUYEN
sa_user_admin.set_user_labels(
policy_name => 'NHANSU_POL',
user_name => 'NGUYEN',
max_read_label => 'SEC',
def_label => 'SEC',
row_label => 'SEC'
);
DBMS_OUTPUT.PUT_LINE('✓ NGUYEN → SEC');
-- User PHUONG
sa_user_admin.set_user_labels(
policy_name => 'NHANSU_POL',
user_name => 'PHUONG',
max_read_label => 'SEC',
def_label => 'SEC',
row_label => 'SEC'
);
DBMS_OUTPUT.PUT_LINE('✓ PHUONG → SEC');
-- User QUOC
sa_user_admin.set_user_labels(
policy_name => 'NHANSU_POL',
user_name => 'QUOC',
max_read_label => 'SEC',
def_label => 'SEC',
row_label => 'SEC'
);
DBMS_OUTPUT.PUT_LINE('✓ QUOC → SEC');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('! Lỗi: ' || SQLERRM);
RAISE;
END;
/
COMMIT;
PROMPT
PROMPT
=========================================================
PROMPT === FILE 03B HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT ✓ Đã gán user labels cho 7 database users:
PROMPT - 5 admin (QLNS, ADMIN, NGUYEN, PHUONG, QUOC) → SEC
PROMPT - 1 kho (HOATV) → CONF:KHO
PROMPT - 1 bán hàng (MAIANH) → CONF:BH
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Tạo 4 connections riêng để test:
PROMPT - QLNS / qlns
PROMPT - ADMIN / admin
PROMPT - HOATV / user01
PROMPT - MAIANH / user01
PROMPT 2. Chạy FILE 04 để test OLS
PROMPT
-- =========================================================
-- CÂU 12: STANDARD AUDITING & FGA - FILE 01
-- Setup Standard Auditing và FGA Policy
-- CHẠY AS: SYS (SYSDBA)
-- Thời gian: 30 giây
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 12 - FILE 01: SETUP AUDITING ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Kiểm tra auditing status
PROMPT
=========================================================
SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = 'audit_trail';
PROMPT
PROMPT Bước 2: Kiểm tra và enable Standard Auditing
PROMPT
=========================================================
BEGIN
DBMS_OUTPUT.PUT_LINE('○ Giả định auditing đã được enable (mặc định
Oracle 12c+)');
END;
/
PROMPT
PROMPT Bước 3: Tạo Standard Audit Policy cho QLNS schema
PROMPT
=========================================================
-- Audit tất cả SELECT, INSERT, UPDATE, DELETE trên NHANVIEN và
HOADON
AUDIT SELECT, INSERT, UPDATE, DELETE ON [Link] BY
ACCESS;
AUDIT SELECT, INSERT, UPDATE, DELETE ON QLNS.&HOADON BY
ACCESS;
-- Audit failed sessions cho QLNS (syntax chuẩn)
AUDIT SESSION BY QLNS WHENEVER NOT SUCCESSFUL;
BEGIN
DBMS_OUTPUT.PUT_LINE('✓ Standard Audit: NHANVIEN & HOADON
(ALL DML)');
DBMS_OUTPUT.PUT_LINE('✓ Standard Audit: Failed sessions for QLNS');
END;
/
PROMPT
PROMPT Bước 4: Setup Fine-Grained Auditing (FGA) cho NHANVIEN
PROMPT
=========================================================
-- Cấp quyền INSERT/SELECT LOGHETHONG cho SYS và PUBLIC (để handler
chạy)
BEGIN
EXECUTE IMMEDIATE 'GRANT INSERT, SELECT ON
[Link] TO SYS';
EXECUTE IMMEDIATE 'GRANT INSERT, SELECT ON
[Link] TO PUBLIC';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
-- Cấp quyền CREATE ANY DIRECTORY cho QLNS (cho Data Pump)
GRANT CREATE ANY DIRECTORY TO QLNS;
BEGIN
DBMS_OUTPUT.PUT_LINE('✓ Đã cấp quyền CREATE ANY DIRECTORY cho
QLNS (cho backup)');
END;
/
BEGIN
-- Drop FGA cũ nếu có
BEGIN
DBMS_FGA.DROP_POLICY(
object_schema => 'QLNS',
object_name => 'NHANVIEN',
policy_name => 'NHANSU_FGA_POLICY'
);
DBMS_OUTPUT.PUT_LINE('○ Đã xóa FGA policy cũ');
EXCEPTION WHEN OTHERS THEN
NULL; -- Bỏ qua nếu chưa tồn tại
END;
-- Tạo handler procedure cho FGA (trực tiếp, sửa tên cột THOIGIAN)
CREATE OR REPLACE PROCEDURE QLNS.FGA_AUDIT_HANDLER(
schema_name VARCHAR2,
table_name VARCHAR2,
policy_name VARCHAR2
) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO [Link] (MALOG, THAOTAC, THOIGIAN,
MANV, MOTA)
VALUES (SUBSTR(RAWTOHEX(SYS_GUID()), 1, 10), 'FGA_AUDIT:
UPDATE NHANVIEN', SYSDATE,
SYS_CONTEXT('USERENV', 'SESSION_USER'),
'FGA Update by ' || NVL(SYS_CONTEXT('USERENV', 'SESSION_USER'),
'UNKNOWN') || ' Policy: ' || policy_name);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
NULL; -- Tránh crash handler
END;
/
BEGIN
DBMS_OUTPUT.PUT_LINE('✓ FGA Handler: FGA_AUDIT_HANDLER (ghi
vào LOGHETHONG)');
END;
/
PROMPT
PROMPT
=========================================================
PROMPT === FILE 01 HOÀN THÀNH ===
PROMPT
=========================================================
PROMPT ✓ Standard Auditing: DML trên NHANVIEN/HOADON + Failed sessions
PROMPT ✓ FGA: UPDATE mật khẩu/quyền trên NHANVIEN (log vào
LOGHETHONG)
PROMPT ✓ Cấp quyền CREATE ANY DIRECTORY cho QLNS (cho backup)
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Disconnect SYS
PROMPT 2. Connect QLNS / qlns
PROMPT 3. Chạy FILE 02 (Sao lưu)
-- =========================================================
-- CÂU 12: STANDARD AUDITING & FGA - FILE 02
-- Nghiệp vụ cập nhật + Trigger ghi LOGHETHONG + Test FGA
-- CHẠY AS: QLNS
-- Thời gian: 3–5 phút
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
SET DEFINE OFF
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 12 - FILE 02: NGHIỆP VỤ + TRIGGER LOG ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Trigger ghi nhật ký trên bảng HOADON
PROMPT
=========================================================
PROMPT
PROMPT Bước 2: Thủ tục đổi mật khẩu nhân viên (kích hoạt FGA)
PROMPT
=========================================================
UPDATE NhanVien
SET MatKhau_Goc = p_matkhaumoi,
MatKhau_HASH = FN_HASH_PASSWORD(p_matkhaumoi)
WHERE MaNV = v_manv;
COMMIT;
END;
/
PROMPT ✓ PROC_DOI_MATKHAU_NV: Đổi mật khẩu + ghi LOGHETHONG +
kích hoạt FGA
PROMPT
PROMPT Bước 3: Thủ tục cập nhật quyền hạn nhân viên (kích hoạt FGA)
PROMPT
=========================================================
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE
PROC_CAPNHAT_QUYENHAN_NV';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
UPDATE NhanVien
SET QuyenHan = p_quyenmoi
WHERE MaNV = v_manv;
COMMIT;
END;
/
PROMPT ✓ PROC_CAPNHAT_QUYENHAN_NV: Cập nhật quyền + ghi
LOGHETHONG + kích hoạt FGA
PROMPT
PROMPT Bước 4: Chạy thử nghiệp vụ để phát sinh Audit / FGA
PROMPT
=========================================================
-- 4.3. Cập nhật quyền hạn cho 1 nhân viên: cũng kích hoạt Standard Audit + FGA
PROMPT ► Test 3: Nâng quyền maianh thành Admin
EXEC PROC_CAPNHAT_QUYENHAN_NV('maianh', 'Admin');
PROMPT
PROMPT Bước 5: Xem nhanh LOGHETHONG (ứng dụng dùng để giải trình)
PROMPT
=========================================================
COLUMN THAOTAC FORMAT A25
COLUMN MOTA FORMAT A60
PROMPT
PROMPT
=========================================================
PROMPT === FILE 02 HOÀN THÀNH – ĐÃ CÓ NGHIỆP VỤ + TRIGGER LOG
===
PROMPT
=========================================================
PROMPT ✓ Trigger TRG_HOADON_LOG ghi log mọi DML HOADON
PROMPT ✓ PROC_DOI_MATKHAU_NV &
PROC_CAPNHAT_QUYENHAN_NV kích hoạt FGA
PROMPT ✓ LOGHETHONG dùng để xem nhật ký ở mức ứng dụng
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Disconnect QLNS
PROMPT 2. Connect SYS (SYSDBA)
PROMPT 3. Chạy FILE 03 để xem nhật ký DBA_AUDIT_TRAIL,
DBA_FGA_AUDIT_TRAIL
-- =========================================================
-- CÂU 12: STANDARD AUDITING & FGA - FILE 03
-- Truy vấn nhật ký Standard Auditing + FGA + LOGHETHONG
-- CHẠY AS: SYS (SYSDBA)
-- Thời gian: 2–3 phút
-- =========================================================
SET SERVEROUTPUT ON;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT === CÂU 12 - FILE 03: XEM VÀ GIẢI TRÌNH NHẬT KÝ ===
PROMPT === Đang login as:
SHOW USER;
PROMPT
=========================================================
PROMPT
PROMPT Bước 1: Standard Audit – thao tác trên NHANVIEN / HOADON
PROMPT
=========================================================
COLUMN USERNAME FORMAT A12
COLUMN OBJ_NAME FORMAT A12
COLUMN ACTION_NAME FORMAT A15
COLUMN RETURN_CODE FORMAT 999999
COLUMN EXTENDED_TIMESTAMP FORMAT A30
SELECT
USERNAME,
OBJ_NAME,
ACTION_NAME,
TO_CHAR(EXTENDED_TIMESTAMP, 'DD/MM/YYYY HH24:MI:SS') AS
THOIGIAN,
RETURNCODE AS RETURN_CODE
FROM DBA_AUDIT_TRAIL
WHERE OWNER = 'QLNS'
AND OBJ_NAME IN ('NHANVIEN','HOADON')
ORDER BY EXTENDED_TIMESTAMP DESC;
PROMPT
PROMPT Bước 2: FGA Audit – cập nhật MATKHAU_HASH / QUYENHAN
PROMPT
=========================================================
COLUMN DB_USER FORMAT A12
COLUMN OBJECT_SCHEMA FORMAT A8
COLUMN OBJECT_NAME FORMAT A10
COLUMN STATEMENT_TYPE FORMAT A10
COLUMN POLICY_NAME FORMAT A18
SELECT
DB_USER,
OBJECT_SCHEMA,
OBJECT_NAME,
STATEMENT_TYPE,
POLICY_NAME,
TO_CHAR(EXTENDED_TIMESTAMP, 'DD/MM/YYYY HH24:MI:SS') AS
THOIGIAN
FROM DBA_FGA_AUDIT_TRAIL
WHERE OBJECT_SCHEMA = 'QLNS'
AND OBJECT_NAME = 'NHANVIEN'
ORDER BY EXTENDED_TIMESTAMP DESC;
PROMPT
PROMPT Bước 3: Xem LOGHETHONG của ứng dụng (FGA handler + Trigger)
PROMPT
=========================================================
COLUMN THAOTAC FORMAT A25
COLUMN MOTA FORMAT A60
SELECT MaLog, ThaoTac, ThoiGian, MaNV, MoTa
FROM [Link]
ORDER BY ThoiGian DESC;
PROMPT
PROMPT
=========================================================
PROMPT === FILE 03 HOÀN THÀNH – BÁO CÁO GIẢI TRÌNH ===
PROMPT
=========================================================
PROMPT ✓ DBA_AUDIT_TRAIL: DML trên NHANVIEN/HOADON (Standard
Auditing)
PROMPT ✓ DBA_FGA_AUDIT_TRAIL: UPDATE
MATKHAU_HASH/QUYENHAN (FGA)
PROMPT ✓ [Link]: Nhật ký nghiệp vụ từ Trigger + Handler
PROMPT
PROMPT ==> Câu 12 đã đầy đủ: Standard Auditing + Trigger + FGA + màn hình giải
trình
-- =========================================================
-- CÂU 13 - FILE 01: BACKUP SCHEMA QLNS
-- Sử dụng DBMS_DATAPUMP (không cần CMD)
-- CHẠY AS: SYS (SYSDBA) trong SQL Developer
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT CÂU 13 - FILE 01: BACKUP
SHOW USER;
PROMPT
=========================================================
-- Cấp quyền
GRANT READ, WRITE ON DIRECTORY BACKUP_DIR TO QLNS;
GRANT READ, WRITE ON DIRECTORY BACKUP_DIR TO SYSTEM;
GRANT DATAPUMP_EXP_FULL_DATABASE TO QLNS;
GRANT DATAPUMP_IMP_FULL_DATABASE TO QLNS;
PROMPT ✓ Đã cấp quyền
DECLARE
v_handle NUMBER;
v_status VARCHAR2(20);
v_job_state VARCHAR2(30);
BEGIN
-- Mở Data Pump job
v_handle := DBMS_DATAPUMP.OPEN(
operation => 'EXPORT',
job_mode => 'SCHEMA',
job_name => 'QLNS_BACKUP_JOB'
);
-- File log
DBMS_DATAPUMP.ADD_FILE(
handle => v_handle,
filename => 'QLNS_BACKUP.log',
directory => 'BACKUP_DIR',
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE
);
-- Đóng job
DBMS_DATAPUMP.DETACH(v_handle);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -31626 THEN
-- Job đã tồn tại, drop và thử lại
BEGIN
DBMS_DATAPUMP.STOP_JOB(
DBMS_DATAPUMP.ATTACH('QLNS_BACKUP_JOB', 'SYS')
);
EXCEPTION WHEN OTHERS THEN NULL;
END;
DBMS_OUTPUT.PUT_LINE('! Job đã tồn tại, vui lòng chạy lại script');
ELSE
DBMS_OUTPUT.PUT_LINE('! Lỗi: ' || SQLERRM);
IF v_handle IS NOT NULL THEN
DBMS_DATAPUMP.DETACH(v_handle);
END IF;
END IF;
END;
/
PROMPT
PROMPT
=========================================================
PROMPT FILE 01 HOÀN THÀNH
PROMPT
=========================================================
PROMPT ✓ Backup thành công
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Kiểm tra file: C:\oracle_backup\QLNS_BACKUP.dmp
PROMPT 2. Xem log: C:\oracle_backup\QLNS_BACKUP.log
PROMPT 3. Chạy: CAU13_02_RESTORE.sql
PROMPT
=========================================================
-- =========================================================
-- CÂU 13 - FILE 02: RESTORE SCHEMA
-- Sử dụng DBMS_DATAPUMP (không cần CMD)
-- CHẠY AS: SYS (SYSDBA) trong SQL Developer
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT CÂU 13 - FILE 02: RESTORE
SHOW USER;
PROMPT
=========================================================
BEGIN
FOR s IN (SELECT sid, serial# FROM v$session WHERE username =
'QLNS_RESTORE') LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || [Link] || ',' ||
[Link]# || ''' IMMEDIATE';
EXCEPTION WHEN OTHERS THEN NULL;
END;
END LOOP;
END;
/
BEGIN
EXECUTE IMMEDIATE 'DROP USER QLNS_RESTORE CASCADE';
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
DECLARE
v_handle NUMBER;
v_status VARCHAR2(20);
v_job_state VARCHAR2(30);
BEGIN
-- Mở Data Pump job
v_handle := DBMS_DATAPUMP.OPEN(
operation => 'IMPORT',
job_mode => 'SCHEMA',
job_name => 'QLNS_RESTORE_JOB'
);
-- File log
DBMS_DATAPUMP.ADD_FILE(
handle => v_handle,
filename => 'QLNS_RESTORE.log',
directory => 'BACKUP_DIR',
filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE
);
-- Đóng job
DBMS_DATAPUMP.DETACH(v_handle);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -31626 THEN
-- Job đã tồn tại, drop và thử lại
BEGIN
DBMS_DATAPUMP.STOP_JOB(
DBMS_DATAPUMP.ATTACH('QLNS_RESTORE_JOB', 'SYS')
);
EXCEPTION WHEN OTHERS THEN NULL;
END;
DBMS_OUTPUT.PUT_LINE('! Job đã tồn tại, vui lòng chạy lại script');
ELSE
DBMS_OUTPUT.PUT_LINE('! Lỗi: ' || SQLERRM);
IF v_handle IS NOT NULL THEN
DBMS_DATAPUMP.DETACH(v_handle);
END IF;
END IF;
END;
/
PROMPT
PROMPT
=========================================================
PROMPT FILE 02 HOÀN THÀNH
PROMPT
=========================================================
PROMPT ✓ Restore thành công
PROMPT
PROMPT BƯỚC TIẾP THEO:
PROMPT 1. Xem log: C:\oracle_backup\QLNS_RESTORE.log
PROMPT 2. Chạy: CAU13_03_KIEM_TRA.sql
PROMPT
=========================================================
-- =========================================================
-- CÂU 13 - FILE 03: KIỂM TRA KẾT QUẢ
-- Kiểm tra backup và restore
-- CHẠY AS: SYS (SYSDBA) trong SQL Developer
-- =========================================================
SET SERVEROUTPUT ON SIZE 1000000;
ALTER SESSION SET CONTAINER = ORCLPDB;
PROMPT
=========================================================
PROMPT CÂU 13 - FILE 03: KIỂM TRA KẾT QUẢ
SHOW USER;
PROMPT
=========================================================
-- So sánh số bảng
PROMPT
PROMPT 2. So sánh số lượng bảng:
SELECT 'QLNS' AS SCHEMA, COUNT(*) AS SO_BANG
FROM DBA_TABLES WHERE OWNER = 'QLNS'
UNION ALL
SELECT 'QLNS_RESTORE', COUNT(*)
FROM DBA_TABLES WHERE OWNER = 'QLNS_RESTORE';
-- So sánh records
PROMPT
PROMPT 3. So sánh số lượng records:
SELECT
'SACH' AS BANG,
(SELECT COUNT(*) FROM [Link]) AS QLNS,
(SELECT COUNT(*) FROM QLNS_RESTORE.SACH) AS RESTORE,
CASE WHEN (SELECT COUNT(*) FROM [Link]) = (SELECT
COUNT(*) FROM QLNS_RESTORE.SACH)
THEN 'OK' ELSE 'SAI' END AS KET_QUA
FROM DUAL
UNION ALL
SELECT 'KHACHHANG',
(SELECT COUNT(*) FROM [Link]),
(SELECT COUNT(*) FROM QLNS_RESTORE.KHACHHANG),
CASE WHEN (SELECT COUNT(*) FROM [Link]) = (SELECT
COUNT(*) FROM QLNS_RESTORE.KHACHHANG)
THEN 'OK' ELSE 'SAI' END
FROM DUAL
UNION ALL
SELECT 'NHANVIEN',
(SELECT COUNT(*) FROM [Link]),
(SELECT COUNT(*) FROM QLNS_RESTORE.NHANVIEN),
CASE WHEN (SELECT COUNT(*) FROM [Link]) = (SELECT
COUNT(*) FROM QLNS_RESTORE.NHANVIEN)
THEN 'OK' ELSE 'SAI' END
FROM DUAL
UNION ALL
SELECT 'HOADON',
(SELECT COUNT(*) FROM [Link]),
(SELECT COUNT(*) FROM QLNS_RESTORE.HOADON),
CASE WHEN (SELECT COUNT(*) FROM [Link]) = (SELECT
COUNT(*) FROM QLNS_RESTORE.HOADON)
THEN 'OK' ELSE 'SAI' END
FROM DUAL
UNION ALL
SELECT 'CHITIETHOADON',
(SELECT COUNT(*) FROM [Link]),
(SELECT COUNT(*) FROM QLNS_RESTORE.CHITIETHOADON),
CASE WHEN (SELECT COUNT(*) FROM [Link]) =
(SELECT COUNT(*) FROM QLNS_RESTORE.CHITIETHOADON)
THEN 'OK' ELSE 'SAI' END
FROM DUAL;
PROMPT
PROMPT 5. Dữ liệu mẫu NHANVIEN:
SELECT MANV, HOTEN, CHUCVU, TENDANGNHAP
FROM QLNS_RESTORE.NHANVIEN
WHERE ROWNUM <= 3
ORDER BY MANV;
PROMPT
PROMPT 6. Dữ liệu mẫu HOADON:
SELECT MAHD, NGAYLAP, MAKH, MANV, TONGTIEN
FROM QLNS_RESTORE.HOADON
WHERE ROWNUM <= 3
ORDER BY MAHD;
-- So sánh objects
PROMPT
PROMPT 7. So sánh objects:
SELECT
NVL(o1.OBJECT_TYPE, o2.OBJECT_TYPE) AS OBJECT_TYPE,
NVL([Link], 0) AS QLNS,
NVL([Link], 0) AS RESTORE
FROM
(SELECT OBJECT_TYPE, COUNT(*) AS CNT
FROM DBA_OBJECTS
WHERE OWNER = 'QLNS'
AND OBJECT_TYPE IN
('TABLE','VIEW','PROCEDURE','FUNCTION','TRIGGER','SEQUENCE')
GROUP BY OBJECT_TYPE) o1
FULL OUTER JOIN
(SELECT OBJECT_TYPE, COUNT(*) AS CNT
FROM DBA_OBJECTS
WHERE OWNER = 'QLNS_RESTORE'
AND OBJECT_TYPE IN
('TABLE','VIEW','PROCEDURE','FUNCTION','TRIGGER','SEQUENCE')
GROUP BY OBJECT_TYPE) o2
ON o1.OBJECT_TYPE = o2.OBJECT_TYPE
ORDER BY OBJECT_TYPE;
DECLARE
v_qlns_tables NUMBER;
v_restore_tables NUMBER;
v_match_count NUMBER := 0;
v_qlns_cnt NUMBER;
v_restore_cnt NUMBER;
BEGIN
SELECT COUNT(*) INTO v_qlns_tables FROM DBA_TABLES WHERE
OWNER = 'QLNS';
SELECT COUNT(*) INTO v_restore_tables FROM DBA_TABLES WHERE
OWNER = 'QLNS_RESTORE';
DBMS_OUTPUT.PUT_LINE('======================================
===================');
DBMS_OUTPUT.PUT_LINE('BACKUP:');
DBMS_OUTPUT.PUT_LINE(' Schema: QLNS');
DBMS_OUTPUT.PUT_LINE(' So bang: ' || v_qlns_tables);
DBMS_OUTPUT.PUT_LINE(' File: C:\oracle_backup\QLNS_BACKUP.dmp');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('RESTORE:');
DBMS_OUTPUT.PUT_LINE(' Schema: QLNS_RESTORE');
DBMS_OUTPUT.PUT_LINE(' So bang: ' || v_restore_tables);
DBMS_OUTPUT.PUT_LINE(' File: C:\oracle_backup\QLNS_RESTORE.log');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('KET QUA:');
DBMS_OUTPUT.PUT_LINE(' Bang khop: ' || v_match_count || '/5');
DBMS_OUTPUT.PUT_LINE('======================================
===================');
DBMS_OUTPUT.PUT_LINE('*** CAU 13 HOAN THANH: BACKUP &
RESTORE THANH CONG! ***');
DBMS_OUTPUT.PUT_LINE('======================================
===================');
ELSE
DBMS_OUTPUT.PUT_LINE(' Trang thai: CAN KIEM TRA LAI');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('======================================
===================');
DBMS_OUTPUT.PUT_LINE('! CAU 13 CAN KIEM TRA LAI');
DBMS_OUTPUT.PUT_LINE('======================================
===================');
END IF;
END;
/
PROMPT
PROMPT Tuy chon: Xoa user QLNS_RESTORE sau khi test xong
PROMPT DROP USER QLNS_RESTORE CASCADE;
PROMPT
-- =========================================================
-- CÂU 11: ORACLE LABEL SECURITY - FILE 04
-- Test OLS Policy với nhiều database users
-- CHẠY AS: Tạo nhiều connections riêng biệt
-- Thời gian: 3-5 phút
-- =========================================================
-- =========================================================
-- HƯỚNG DẪN SETUP:
-- =========================================================
-- Trong SQL Developer, tạo 5 connections riêng:
--
-- Connection 1: QLNS
-- Username: QLNS
-- Password: qlns
-- Role: Default
-- Service: ORCLPDB
--
-- Connection 2: ADMIN
-- Username: ADMIN
-- Password: admin
-- Role: Default
-- Service: ORCLPDB
--
-- Connection 3: HOATV (nhân viên kho)
-- Username: HOATV
-- Password: user01
-- Role: Default
-- Service: ORCLPDB
--
-- Connection 4: MAIANH (nhân viên bán hàng)
-- Username: MAIANH
-- Password: user01
-- Role: Default
-- Service: ORCLPDB
--
-- Connection 5: NGUYEN (quản lý)
-- Username: NGUYEN
-- Password: 123
-- Role: Default
-- Service: ORCLPDB
-- =========================================================
PROMPT
=========================================================
PROMPT CÂU 11 - FILE 04: TEST OLS POLICY
PROMPT
=========================================================
PROMPT
PROMPT === ĐANG LOGIN AS:
SHOW USER;
PROMPT
=========================================================
-- =========================================================
-- PHẦN 1: KIỂM TRA USER LABEL CỦA MÌNH
-- =========================================================
PROMPT
PROMPT 1. Kiểm tra user label của bạn:
PROMPT
=========================================================
BEGIN
DBMS_OUTPUT.PUT_LINE('User hiện tại: ' || USER);
DBMS_OUTPUT.PUT_LINE('Session user: ' || SYS_CONTEXT('USERENV',
'SESSION_USER'));
DBMS_OUTPUT.PUT_LINE('Max Read Label: ' ||
SA_SESSION.MAX_READ_LABEL('NHANSU_POL'));
DBMS_OUTPUT.PUT_LINE('Current Label: ' ||
SA_SESSION.LABEL('NHANSU_POL'));
END;
/
-- =========================================================
-- PHẦN 2: XEM DỮ LIỆU NHANVIEN (BỊ GIỚI HẠN BỞI OLS)
-- =========================================================
PROMPT
PROMPT 2. Xem dữ liệu NHANVIEN (có OLS policy):
PROMPT
=========================================================
SELECT
MANV,
HOTEN,
CHUCVU,
TENDANGNHAP,
QUYENHAN,
OLS_LABEL,
LABEL_TO_CHAR(OLS_LABEL) AS LABEL_NAME
FROM [Link]
ORDER BY OLS_LABEL DESC, MANV;
PROMPT
PROMPT 3. Đếm số records nhìn thấy:
PROMPT
=========================================================
-- =========================================================
-- PHẦN 3: GIẢI THÍCH KẾT QUẢ
-- =========================================================
PROMPT
PROMPT
=========================================================
PROMPT GIẢI THÍCH KẾT QUẢ THEO USER:
PROMPT
=========================================================
PROMPT
PROMPT ** QLNS (owner, label SEC) **
PROMPT → Nhìn thấy: 6/6 nhân viên (tất cả)
PROMPT → Lý do: Owner có quyền cao nhất
PROMPT
PROMPT ** ADMIN (label SEC) **
PROMPT → Nhìn thấy: 6/6 nhân viên (tất cả)
PROMPT → Lý do: Label SEC >= tất cả data labels (PUB, CONF:*, SEC)
PROMPT
PROMPT ** NGUYEN (label SEC) **
PROMPT → Nhìn thấy: 6/6 nhân viên (tất cả)
PROMPT → Lý do: Label SEC >= tất cả data labels
PROMPT
PROMPT ** PHUONG (label SEC) **
PROMPT → Nhìn thấy: 6/6 nhân viên (tất cả)
PROMPT → Lý do: Label SEC >= tất cả data labels
PROMPT
PROMPT ** QUOC (label SEC) **
PROMPT → Nhìn thấy: 6/6 nhân viên (tất cả)
PROMPT → Lý do: Label SEC >= tất cả data labels
PROMPT
PROMPT ** HOATV (label CONF:KHO) **
PROMPT → Nhìn thấy: 1/6 nhân viên (chỉ chính mình)
PROMPT → Lý do:
PROMPT - Có compartment KHO → thấy records có label CONF:KHO (30)
PROMPT - KHÔNG có compartment BH → không thấy CONF:BH (20)
PROMPT - KHÔNG có level SECRET → không thấy SEC (50)
PROMPT - Có level CONFIDENTIAL >= PUBLIC → thấy PUB (10) nếu có
PROMPT
PROMPT ** MAIANH (label CONF:BH) **
PROMPT → Nhìn thấy: 1/6 nhân viên (chỉ chính mình)
PROMPT → Lý do:
PROMPT - Có compartment BH → thấy records có label CONF:BH (20)
PROMPT - KHÔNG có compartment KHO → không thấy CONF:KHO (30)
PROMPT - KHÔNG có level SECRET → không thấy SEC (50)
PROMPT - Có level CONFIDENTIAL >= PUBLIC → thấy PUB (10) nếu có
PROMPT
PROMPT
=========================================================
-- =========================================================
-- PHẦN 4: BẢNG TỔNG HỢP KẾT QUẢ
-- =========================================================
PROMPT
PROMPT
=========================================================
PROMPT BẢNG TỔNG HỢP KẾT QUẢ MONG ĐỢI:
PROMPT
=========================================================
PROMPT
PROMPT +-------------+---------------+---------------------+
PROMPT | User | User Label | Nhìn thấy (records) |
PROMPT +-------------+---------------+---------------------+
PROMPT | QLNS | SEC | 6/6 (tất cả) |
PROMPT | ADMIN | SEC | 6/6 (tất cả) |
PROMPT | NGUYEN | SEC | 6/6 (tất cả) |
PROMPT | PHUONG | SEC | 6/6 (tất cả) |
PROMPT | QUOC | SEC | 6/6 (tất cả) |
PROMPT | HOATV | CONF:KHO | 1/6 (chỉ hoatv) |
PROMPT | MAIANH | CONF:BH | 1/6 (chỉ maianh) |
PROMPT +-------------+---------------+---------------------+
PROMPT
PROMPT Data Labels trong NHANVIEN:
PROMPT - 4 admin users (admin, Nguyen, Phuong, Quoc) → SEC (50)
PROMPT - 1 kho (hoatv) → CONF:KHO (30)
PROMPT - 1 bán hàng (maianh) → CONF:BH (20)
PROMPT
PROMPT
=========================================================
-- =========================================================
-- PHẦN 5: TEST THÊM - THỬ INSERT (CHỈ CHO ADMIN/OWNER)
-- =========================================================
PROMPT
PROMPT
=========================================================
PROMPT PHẦN 5: TEST INSERT (tùy chọn - chỉ chạy nếu là ADMIN/QLNS)
PROMPT
=========================================================
PROMPT
PROMPT LƯU Ý: Nếu bạn là HOATV hoặc MAIANH, INSERT sẽ BỊ LỖI
PROMPT vì không có quyền INSERT trên NHANVIEN
PROMPT
PROMPT Bỏ comment dòng dưới để test INSERT:
PROMPT
-- INSERT INTO [Link] (MANV, HOTEN, CHUCVU,
TENDANGNHAP, SALT, MATKHAU_GOC, OLS_LABEL)
-- VALUES ('NV999', 'Test User', 'Test', 'testuser', 'salt_test', 'test123', 30);
-- ROLLBACK;
PROMPT
PROMPT (Script đã ROLLBACK để không làm thay đổi dữ liệu)
PROMPT
-- =========================================================
-- PHẦN 6: KIỂM TRA CONTEXT
-- =========================================================
PROMPT
PROMPT
=========================================================
PROMPT PHẦN 6: KIỂM TRA CONTEXT (debug info)
PROMPT
=========================================================
SELECT
SYS_CONTEXT('CTX_NHASACH', 'USER_MANV') AS MY_MANV,
SYS_CONTEXT('CTX_NHASACH', 'USER_QUYENHAN') AS
MY_QUYENHAN,
SYS_CONTEXT('USERENV', 'SESSION_USER') AS SESSION_USER,
SYS_CONTEXT('USERENV', 'CURRENT_USER') AS CURRENT_USER
FROM DUAL;
PROMPT
PROMPT
=========================================================
PROMPT === FILE 04 HOÀN THÀNH - KẾT QUẢ TEST OLS ===
PROMPT
=========================================================
PROMPT
PROMPT ĐÃ TEST:
PROMPT ✓ User label của từng user
PROMPT ✓ Số lượng records nhìn thấy trong NHANVIEN
PROMPT ✓ Context values
PROMPT
PROMPT KẾT LUẬN:
PROMPT ✓ OLS Policy hoạt động đúng
PROMPT ✓ Users với SEC thấy tất cả (6/6)
PROMPT ✓ Users với CONF:KHO chỉ thấy KHO (1/6)
PROMPT ✓ Users với CONF:BH chỉ thấy BH (1/6)
PROMPT
PROMPT ==> CÂU 11 HOÀN THÀNH: OLS POLICY HOẠT ĐỘNG ĐÚNG!
PROMPT
=========================================================