Cách Tạo Job Trong Oracle / Top 18 Xem Nhiều Nhất & Mới Nhất 9/2023 # Top Trend | Rafs.edu.vn

Tạo Job Schedule Backup Trong Oracle

DBMS_SCHEDULER là 1 package của Oracle (có từ version 10) cung cấp các procedure giúp tạo job.

 Tạo Oracle Job gồm 3 bước:

Tạo time schedule – dbms_scheduler.create_schedule

Tạo program declaration – dbms_scheduler.create program

Tạo job (conflation) – dbms_scheduler.create_job

Lưu ý

: login vào với vai trò sys và gán quyền cho user cần tạo job:

GRANT create any directory TO fhr; GRANT create procedure TO fhr; GRANT create table TO fhr;

GRANT create job TO fhr; GRANT manage scheduler TO fhr;

begin -- daily from Monday to Sunday at 22:00 (10:00 p.m.) dbms_scheduler.create_schedule -- run every hour, every day dbms_scheduler.create_schedule(   -- run every 5 minute, every day dbms_scheduler.create_schedule( -- run every minute, every day dbms_scheduler.create_schedule( -- run every Sunday at 18:00 (06:00 p.m.) dbms_scheduler.create_schedule end; begin -- Call a procedure of a database package dbms_scheduler.create_program ); end; begin -- Connect both dbms_scheduler parts by creating the final job dbms_scheduler.create_job end; begin -- change start time DBMS_SCHEDULER.SET_ATTRIBUTE( ); -- change repeat interval DBMS_SCHEDULER.SET_ATTRIBUTE( ); end; begin dbms_scheduler.run_job('JOB_COLLECT_SESS_DATA',TRUE); end; begin dbms_scheduler.disable('JOB_COLLECT_INST_INFO'); dbms_scheduler.enable('JOB_COLLECT_INST_INFO'); end; -- All jobs select * from user_scheduler_jobs; -- Get information to job select * from user_scheduler_job_log order by log_date desc; -- Show details on job run select * from user_scheduler_job_run_details; -- View all running jobs, Run the following query from SQL*Plus SELECT chúng tôi c.serial#, chúng tôi a.failures, to_char(a.this_date, 'mm/dd/yyyy hh:mi pm') startdatetime, b.what FROM dba_jobs_running a, dba_jobs b, v$session c WHERE chúng tôi = chúng tôi AND chúng tôi = chúng tôi order by a.this_date; -- View all jobs, Run the following query from SQL*Plus SELECT job, to_char(last_date, 'mm/dd/yyyy hh:mi pm') lastdate, to_char(next_date, 'mm/dd/yyyy hh:mi pm') nextdate, failures, broken, what FROM dba_jobs ORDER BY next_date;

Ý hay là khi muốn kill 1 job mà không muốn nó tự restart lại là hãy đánh dấu broken. Chạy lệnh sau từ SQL*Plus:

-- Võìi job_id lâìy týÌ câu truy vâìn “View all running jobs”. execute dbms_job.broken(job_id, true);

Sau đó, kill session bằng 1 trong 2 cách:

#1: (the best / fast way to kill a session)

-- Find the thread you want to kill SELECT sid, spid as thread, osuser, s.program FROM sys.v_$process p, sys.v_$session s WHERE chúng tôi = s.paddr; -- Run the following for Oracle on Linux, sid is the name given to the Oracle Instance -- (the name given in the chúng tôi fle) orakill sid thread

#2:

-- Run the following query from SQL*Plus -- sid and serial# came from the "View all running jobs" query. -- The problem with this option is it can sometimes take a long time to kill the session alter system kill session 'sid, serial#'

Để remove hoàn toàn job, chạy lệnh:

-- job_id is obtained from the "View all running jobs" query. execute dbms_job.remove(job_id)

Nếu chỉ muốn stop job để fix chứ không muốn remove hoàn toàn, hãy fix job và restart bằng lệnh:

-- job_id is obtained from the "View all running jobs" query execute dbms_job.broken(job_id, false);

Ghi chú: Khi nào job trở thành ‘broken’?

Oracle thực hiện job thành công sau 16 lần cố gắng thực hiện (có lỗi khi thực hiện job). hoặc

Người dùng đánh dấu job là ‘broken’, dùng proc DBMS_JOB.BROKEN.

Khi 1 job được đánh dấu là ‘broken’. Oracle sẽ không cố gắng thực hiện job nữa đến khi job được đánh dấu không còn ‘broken’ hoặc bị ép thực thi bằng lời gọi DBMS_JOB.RUN.

10. Tạo job mà không cần time scheduler và program declaration

begin dbms_scheduler.create_job ( end;

Cách Tạo Người Dùng Trong Oracle 11G Và Cấp Quyền

Như đã đề cập nhiều lần trong các nhận xét, việc sử dụng các vai trò CONNECT, RESOURCE và DBA không được Oracle khuyến khích.

Bạn phải kết nối với SYS để tạo vai trò và (các) người dùng được cung cấp vai trò này. Bạn có thể sử dụng SQL Developer hoặc SQL * Plus như bạn muốn. Đừng quên đề cập đến vai trò SYSDBA trong chuỗi đăng nhập. connect_identifier sử dụng các cú pháp khác nhau.

Giả sử bạn có 12cR1 giống như máy ảo được cung cấp dưới dạng ” Oracle Technology Network Developer Day”. Các chuỗi kết nối có thể (để kết nối với PDB cung cấp):

sqlplus sys/[email protected]/orcl as sysdba sqlplus[email protected]"127.0.0.1/orcl" as sysdba -- to avoid putting the pw in clear

Lưu ý rằng dưới Unix, có dấu ngoặc kép phải được thoát nếu không họ sẽ được tiêu thụ bởi vỏ. Do đó " trở thành ".

Sau đó, bạn tạo vai trò MYROLE và cấp cho nó vai trò hoặc đặc quyền khác. Tôi đã thêm gần mức tối thiểu để làm điều gì đó thú vị:

create role myrole not identified; grant create session to myrole; grant alter session to myrole; grant create table to myrole;

Tiếp theo tạo người dùng MYUSER. Chuỗi sau identified by là mật khẩu phân biệt chữ hoa chữ thường. Phần còn lại thì không. Bạn cũng có thể sử dụng các định danh phân cách SQL (được bao quanh bởi các dấu ngoặc kép ") thay vì các mã định danh thông thường được chuyển đổi từ chữ hoa và tùy thuộc vào một vài hạn chế.Hạn ngạch có thể là unlimited thay vì 20m.

create user myuser identified by myuser default tablespace users profile default account unlock; alter user myuser quota 20m on users; grant myrole to myuser;

Cuối cùng, bạn kết nối với tư cách người dùng mới. Vui lòng lưu ý rằng bạn cũng có thể thay đổi cấu hình mặc định hoặc cung cấp một số khác để tùy chỉnh một số cài đặt khi hết hạn mật khẩu, số lần đăng nhập không thành công được phép, v.v.

Cách Tạo Job Trong Sql Server Và Cách Tạo Bảng Động Định Kỳ

Như chúng ta đã biết đối với các hệ thống Logging thì dữ liệu luôn được cập nhật hàng tháng, hàng ngày vì vậy đòi hỏi CSDL phải tương thích có nghĩa là Log trong tháng nào thì hệ thống sẽ Insert vào tháng đó tương ứng tráng việc Insert nhiều trong cùng 1 bảng dẫn đến việc Select chậm khi trả về kết quả. Vì vậy đối với Log của mỗi tháng chúng ta sẽ tạo ra các bảng vd: Tháng 1 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_1_2010 Tháng 2 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_2_2010 … Tháng 12 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_12_2010 Như vậy làm sao để hệ thống có thể tự tạo ra các bảng tương ứng với năm và tháng như vậy ? Giải pháp của tôi là sử dụng SQL Job trong SQL Server, cái này bắt buộc bạn phải có Full quyền Administrator trên Server Database Các bước như sau:

B1: Trong SQL Server bạn kéo xuống dưới có phần SQL Server Agent bạn phải Start nó lên nếu nó đang Stop

B2: Tại đây bạn được yêu cầu nhập Name: Tên của Job ở đây tôi chọn là CreateTableLogging và owner là sa

Bạn chọn tiếp Database là tên Database bạn muốn thực thi Phần Command bạn gõ câu lệnh sau để tạo bảng động

DECLARE @strCreateTable AS VARCHAR(1000) SET @strCreateTable = ‘CREATE TABLE tbl_Month_’ SET @strCreateTable += Cast(MONTH(GETDATE()) as varchar) SET @strCreateTable += ‘_’ SET @strCreateTable += Cast(YEAR(GETDATE()) as varchar) SET @strCreateTable +='(‘ SET @strCreateTable +=’ID int PRIMARY KEY IDENTITY,’ SET @strCreateTable +=’Name nvarchar(50)’ SET @strCreateTable +=’)’ –PRINT(@strCreateTable) EXEC(@strCreateTable)

Sau đó bạn ấn OK

B4: Tiếp đến bạn chọn phần Schedules (để đặt lịch chạy cho Job) ban chọn New Schedule ở đây bạn được yêu cầu nhập Schedule Name cho Job tôi chọn là ScheduleCreateTable, Phần tần suất (Frequency) tôi chọn Occurs chạy vào ngày 15 hàng tháng (Monthly) lúc 12h đêm.

B5: sau đó bạn ấn OK để hoàn tất việc đặt lịch chạy cho Job và OK để hoàn tất Job và đây là kết quả

B7: Nếu nó báo thế này thì có nghĩa là Job của bạn đã chạy chính xác

B8: Kiểm tra

Như vậy mới hoàn thành xong phần tạo bảng bước tiếp chúng ta phải insert vào bảng đó thế nào

DECLARE @strValue AS NVARCHAR(50) DECLARE @strSQL AS VARCHAR(1000) SET @strValue += Cast(GETDATE() as varchar)

SET @strSQL = ‘INSERT INTO tbl_Month_’ SET @strSQL += Cast(MONTH(GETDATE()) as varchar) SET @strSQL += ‘_’ SET @strSQL += Cast(YEAR(GETDATE()) as varchar) SET @strSQL += ‘([Name]) VALUES(”’ SET @strSQL += @strValue SET @strSQL += ”’)’ –PRINT(@strSQL) EXEC(@strSQL)

trong bảng tbl_Month_xx_xxxx này tôi có 2 trường là ID (tự tăng) và Name sau khi insert xong dữ liệu của tôi sẽ là thế này

ID Name

Share this:

Twitter

Facebook

Like this:

Số lượt thích

Đang tải…

Hướng Dẫn Sử Dụng Tabular Form Trong Oracle Apex

Bạn đang xem tài liệu hướng dẫn lập trình Oracle APEX 5.0. Đây là tài liệu thứ 2 tiếp theo sau tài liệu:

Trong tài liệu này tôi sẽ hướng dẫn bạn tiếp tục với Oracle APEX Database Desktop Application, sử dụng Tabular Form.

Đăng nhập vào Oracle APEX với tài khoản người lập trình.

Vào mục “Database Application”.

Vào tiếp ứng dụng “Hello Database Desktop Application” mà bạn đã tạo trong tài liệu hướng dẫn trước.

Trang web của bạn đã được tạo ra, nhấn vào nút RUN để chạy thử trang vừa tạo.

Đây là hình ảnh trang 7 khi được chạy.

Ở đây, câu hỏi đặt ra là làm thế nào để thay đổi một số trường đầu vào (Input Fields) thành SELECT LIST hoặc POPUP LOV (List of values). Ví dụ: bạn muốn chọn Manager (MGR) thông qua POPUP LOV, và chọn Job thông qua SELECT LIST.

Trở lại màn hình thiết kế trang 7. Sét đặt các thuộc tính cho cột JOB để nó hiển thị như một danh sách lựa chọn (SELECT LIST).

STATIC: CLERK;CLERK, SALESMAN;SALESMAN, PRESIDENT;PRESIDENT, MANAGER;MANAGER, ANALYST;ANALYST

Cú pháp khai báo các giá trị tĩnh (Static Values):

STATIC:Display1;Return1,Display2;Return2

Tiếp theo bạn cần sét đặt các thuộc tính cho trường MGR để nó hiển thị dưới dạng POPUP LOV (List of values)

Tương tự sét đặt các thuộc tính cho DEPTNO, để nó hiển thị như là một POPUP LOV.

Save và chạy lại trang 7:

Ở trên tôi đã hướng dẫn bạn cách tạo Tabular Form sử dụng wizard của Oracle Apex. Tiếp theo chúng ta sẽ tạo Tabular Form hoàn toàn từ đầu, không sử dụng Wizard, nó sẽ giúp bạn hiểu hơn về Tabular Form & Oracle APEX.

Một trang rỗng đã được tạo ra.

Tạo Tabular Form trong vùng “Content Body”:

select EMPNO, EMPNO EMPNO_DISPLAY, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO from EMP

Bạn có thể chạy thử trang 8, kết quả có được:

Thêm một cột chứa các CheckBox, sử dụng để lựa chọn các dòng.

Sét đặt thuộc tính cho EMPNO, ẩn cột này, và sét đặt thuộc tính primary key cho nó.

STATIC: CLERK;CLERK, SALESMAN;SALESMAN, PRESIDENT;PRESIDENT, MANAGER;MANAGER, ANALYST;ANALYST

Identification Appearance Default

Cột SAL (Salary) là kiểu dữ liệu số, vì vậy bạn cần thêm validation:

Identification

Name: SAL must be numeric

Validation: Error

Chú ý:

#COLUMN_HEADER# là một cái có tác dụng giữ chỗ (Place Holder), nó sẽ được thay thế bởi tiêu đề của cột tương ứng tại thời gian chạy.

Tạo Validation cho COMM, COMM phải là dữ liệu số.

Identification

Name: COMM must be numeric

Validation: Error

Bước tiếp theo chúng ta cần thêm các xử lý bao gồm thêm mới, sửa, xóa các bản ghi.

Khi người dùng nhấn vào nút Cancel, trang web sẽ refresh lại trang hiện tại (Ở đây là trang 8).

4.1- Xử lý thêm mới bản ghi

Khi người dùng nhấn vào nút ADD, table trên trang sẽ tự động thêm một dòng mới, cho phép người dùng nhập dữ liệu. Bạn cần gọi hàm javascript để thực hiện điều này.

4.2- Xử lý lưu nhiều dòng dữ liệu

Nút SAVE cần phải thực hiện nhiệm vụ lưu thông tin của nhiều bản ghi cùng một lúc, bao gồm các bản ghi mới các các bản ghi có sửa đổi. Bạn cần phải khai báo một tiến trình (Process) sử lý việc này. Process này sẽ được chạy một lần ngay sau khi trang được gọi, nó sẽ update các bản ghi có thay đổi và insert các bản ghi mới.

Idetification Settings Execution Options Success Messages

Success Message: #MRU_COUNT# row(s) updated, #MRI_COUNT# row(s) inserted.

Condition

4.3- Xử lý xóa nhiều dòng ngay lập tức

Xử lý nút, để xóa ngay lập tức các bản ghi đã chọn, không cần hỏi:

Để xóa nhiều dòng bạn cần tạo một tiến trình (Process) sử lý việc này. Process này sẽ được thực thi một lần ngay khi trang web được gọi.

Idetification Settings Execution Options Success Messages

Success Message: #MRD_COUNT# row(s) deleted.

Condition

4.4- Xử lý xóa nhiều dòng – Hỏi trước khi xóa

Trước khi xóa các bản ghi, chương trình hỏi người dùng có đồng ý xóa hay không trước khi thực thi lệnh xóa.

apex.confirm(…) là hàm Javascript sử dụng để hỏi lại người dùng trước khi thực thi lệnh của button.

apex.confirm('Message ...', 'Button Name'); apex.confirm('Are you sure to delete?','MULTI_ROW_DELETE'); apex.confirm(htmldb_delete_message,'MULTI_ROW_DELETE'); var htmldb_delete_message='Would you like to perform this delete action?'; var htmldb_delete_message='"DELETE_CONFIRM_MSG"'; apex.confirm(htmldb_delete_message,'MULTI_ROW_DELETE');

Để xóa nhiều dòng bạn cần tạo một tiến trình (Process) sử lý việc này. Process này sẽ được thực thi một lần ngay khi trang web được gọi.

Idetification Settings Execution Options Success Messages

Success Message: #MRD_COUNT# row(s) deleted.

Condition

Execution Scope: For Created and Modified Rows

Type: Request = Value

Value: MULTI_ROW_DELETE

Execute Condition: Once

Hướng Dẫn Lập Trình Oracle Pl/Sql

Để có thể tiếp cận nhanh với PL/SQL bạn cần có một công cụ lập trình. Theo kinh nghiệm làm việc của tôi bạn có thể sử dụng PL/SQL Developer, đây là một công cụ trực quan làm việc với Oracle và để lập trình PL/SQL.

Bạn có thể xem hướng dẫn cài đặt và cấu hình PL/SQL tại:

Có một số khái niệm cần phải nắm vững khi lập trình với PL/SQL:

Mỗi lệnh SQL kềt thúc bằng dấu chấm phẩy (;)

Các lệnh thuộc “ngôn ngữ định nghĩa dữ liệu” (Data Definition Language – DDL) không được sử dụng trong PL/SQL

Lệnh SELECT .. INTO không trả về dòng nào có thể gây ra exception

Các lệnh thuộc “ngôn ngữ thao tác trên dữ liệu” (Data Manipulation Language – DML)có thể tác động trên nhiều dòng dữ liệu.

Sử dụng toán tử := để giá giá trị cho một biến.

-- Lệnh gán giá trị cho biến x := 1; -- Lệnh Insert: Insert into Department (Dept_Id, Dept_No, Dept_Name, Location) values (1, 'D1', 'HR', 'Chicago'); -- Bắt ngoại lệ: Begin Select Dept.Dept_Id into v_Dept_Id from Department Dep; Exception when too_many_rows then End; ......

PL/SQL được tổ chức theo từng khối lệnh, Một khối lệnh có thể có các khối lệnh con bên trong nó.

Declare -- Phần khai báo - Không bắt buộc- -- Khai báo các biến sử dụng trong phần thân v_Location Varchar2(100); Begin -- Phần thân của khối lệnh -- Đoạn lệnh thực hiện v_Location := 'Chicago'; -- .... Exception -- Phần xử lý lỗi - Không bắt buộc -- Bắt để sử lý các ngoại lệ khác nhau. When No_Data_Found Then -- Ngoại lệ khi câu lệnh SELECT .. INTO không trả về dòng nào -- (Không bắt buộc phải bắt) -- Hoặc để lệnh null nếu không cần sử lý. Null; When Too_Many_Rows Then -- Ngoại lệ khi câu lệnh SELECT .. INTO trả về nhiều dòng -- (Không bắt buộc phải bắt) Null; When Others Then -- Các ngoại lệ khác Null; End;

Ở đây tôi giới thiệu tổng quan về các lệnh cơ bản của PL/SQL. Bạn sẽ hiểu hơn về nó thông qua các ví dụ ở các phần tiếp theo.

Công việc 1; Công việc 2; ] [ELSE Công việc n + 1; ] END IF; If v_Option = 1 Then v_Action := 'Run'; Elsif v_Option = 2 Then v_Action := 'Backup'; Elsif v_Option = 3 Then v_Action := 'Stop'; Else v_Action := 'Invalid'; End If; 4.2- Vòng lặp không định trước (LOOP) LOOP END LOOP; x := 0; Loop x := x + 1; y := y - x; End Loop; 4.3- Vòng lặp có định trước (FOR LOOP) LOOP END LOOP; x := 0; For v_Idx In 1 .. 100 Loop x := x + 1; End Loop; 4.4- Vòng lặp while (WHILE) END LOOP; v_Text Varchar2(100); ... While Length(v_Text) < 50 Loop End Loop 5- Bắt đầu với PL/SQL sử dụng PL/SQL Developer

Trước hết bạn cần mở PL/SQL Developer, và đăng nhập vào user learningsql:

Trên PL/SQL Developer tạo mới một cửa sổ SQL:

Viết một đoạn code đơn giản tính tổng 2 số.

Declare v_Result Number; -- Khai báo một biến có giá trị 50 v_a Number := 50; -- Khai báo một biến có giá trị 100 v_b Number := 100; Begin -- In ra màn hình Console -- In ra màn hình Console -- Tính tổng v_Result := v_a + v_b; -- In ra màn hình Console End;

Nhấn biểu tượng

6- Các kiểu dữ liệu thông dụng và khai báo

Các kiểu dữ liệu số trong PL/SQL

PLS_INTEGER

Số tự nhiên có dấu 32 bit nằm trong khoảng -2,147,483,648 tới 2,147,483,647.

BINARY_INTEGER

Số tự nhiên có dấu 32 bit nằm trong khoảng -2,147,483,648 tới 2,147,483,647.

BINARY_FLOAT

Kiểu dấu chấm động số thực với độ chính xác đơn (Single-precision)

BINARY_DOUBLE

Kiểu dấu chấm động số thực với độ chính xác gấp đôi (Double-precision)

NUMBER(prec, scale)

Kiểu dấu chấm cố định (Fixed-point) với giá trị tuyệt đối từ 1E-130 tới (không bao gồm) 1.0E126. Một biến NUMBER cũng có thể mô tả 0.

NUMERIC(pre, secale)

Loại số thực (Floating type) với độ chính xác tối đa 38 số thập phân.

FLOAT

Loại số chấm động, số thực tiêu chuẩn ANSI và IBM với độ chính xác tối đa 126 số nhị phân (khoảng 38 số thập phân).

INTEGER

Kiểu số nguyên, tiêu chuẩn ANSI và IBM với độ chính xác 38 chữ số thập phân

SMALLINT

REAL

Kiểu số chấm động, số thực, với độ chính xác tối đa 63 số nhị phân (Khoảng 18 số thập phân).

Các kiểu số thông dụng nhất:

6.4- Kiểu dữ liệu một cột (%type)

Đây là cấu trúc bảng EMPLOYEE:

-- Khai báo một biến varchar2 độ dài 20. -- Biến này có thể lưu giá trị cho cột First_Name v_First_Name Varchar2(20); -- Gán giá trị vào biến v_First_Name lấy từ câu truy vấn. -- Ngoại lệ có thể xẩy ra khi độ dài lưu trữ của biến nhỏ -- hơn độ dài giá trị truyền vào. Select Emp.First_Name into v_First_Name From Employee Emp Where Emp.Emp_Id = 1; -- Khai báo một biến Varchar2 độ dài 30 -- Biến này cũng có thể lưu giá trị cho cột First_Name v_First_Name2 Varchar2(30); -- Cách khai báo an toàn: v_First_Name Employee.First_Name%Type; Declare v_Emp_Id Employee.Emp_Id%Type := 1; v_First_Name Employee.First_Name%Type; Begin Select Emp.First_Name Into v_First_Name From Employee Emp Where Emp.Emp_Id = v_Emp_Id; Exception When No_Data_Found Then -- Trường hợp câu lệnh SELECT .. INTO không trả về bản ghi nào End; 6.5- Kiểu dữ liệu một dòng (%Rowtype) -- Khai báo một biến. -- Là kiểu dữ liệu một dòng. v_Variable_name Table_Name%Rowtype; -- Ví dụ: v_Emp Employee%Rowtype; Declare v_Emp_Id Employee.Emp_Id%Type := 1; -- Khai báo một biến -- Là kiểu dữ liệu 1 dòng của bảng Employee. v_Emp Employee%Rowtype; Begin Select * Into v_Emp From Employee Emp Where Emp.Emp_Id = v_Emp_Id; Exception When No_Data_Found Then -- Trường hợp câu SELECT không trả về bản ghi nào End;

Bạn có thể định nghĩa ra kiểu dữ liệu Record, kiểu dữ liệu này chứa một vài cột. Cú pháp:

-- Khai báo một kiểu dữ liệu của bạn. TYPE Ten_kieu_Record IS RECORD ( ... ); -- Khai báo biến sử dụng kiểu dữ liệu trên: Ten_Bien Ten_kieu_Record; Declare v_Emp_Id Employee.Emp_Id%Type := 1; -- Định nghĩa một kiểu Record có 3 cột. Type Emp_Name_Type Is Record( Emp_First_Name Employee.First_Name%Type ,Emp_Last_Name Employee.Last_Name%Type ,Emp_Full_Name Varchar2(50)); -- Định nghĩa một biến có kiểu dữ liệu Emp_Name_Type v_Emp Emp_Name_Type; Begin Select Emp.First_Name ,Emp.Last_Name Into v_Emp From Employee Emp Where Emp.Emp_Id = v_Emp_Id; Exception When No_Data_Found Then -- Trường hợp câu SELECT không trả về bản ghi nào End;

Bạn có thể định nghĩa một kiểu dữ liệu mới, nó có thể lưu trữ nhiều phần tử, đó là kiểu TABLE.

Các đặc điểm của kiểu TABLE:

Kiểu dữ liệu TABLE giống như một mảng, nhưng có số phần tử không giới hạn.

Chỉ số của kiểu TABLE không nhất thiết liên tục. Ví dụ TABLE có 3 phần tử tại chỉ số 1, 3, 5.

-- Khai báo một kiểu table. INDEX BY BINARY_INTEGER; -- Ví dụ: -- Định nghĩa một kiểu TABLE chứa các phần tử kiểu Varchar2(50) TYPE My_Tbl IS TABLE OF Varchar2(50) INDEX BY BINARY_INTEGER; Declare -- Định nghĩa một kiểu TABLE. Type My_Tbl Is Table Of Varchar2(50) Index By Binary_Integer; -- Khai báo một biến sử dụng kiểu dữ liệu khai báo ở trên. v_Emps My_Tbl; Begin v_Emps(1) := 'One'; v_Emps(2) := 'Two'; v_Emps(3) := 'Three'; For i In v_Emps.First .. v_Emps.Last Loop End Loop; End; Declare -- Định nghĩa kiểu TABLE. Type t_City_Type Is Table Of Varchar2(30) Index By Binary_Integer; -- Khai báo biến sử dụng kiểu TABLE định nghĩa ở trên. t_City t_City_Type; v_City_Index Binary_Integer; v_e Boolean; Begin t_City(100) := 'Chicago'; t_City(101) := 'Chicago'; t_City(200) := 'Hanoi'; t_City(301) := 'Tokyo'; Begin -- Kiểm tra xem có tồn tại phần tử có chỉ số 500 không. v_e := t_City.Exists(500); If v_e Then Dbms_Output.Put_Line('Exists element At 500'); Else Dbms_Output.Put_Line('Not Exists element At 500'); End If; -- -- Xóa đi phần tử tại chỉ số 101 t_City.Delete(101); -- -- Chỉ số đầu tiên v_City_Index := t_City.First; -- Loop t_City(v_City_Index)); Exit When v_City_Index = t_City.Last; -- Lấy chỉ số tiếp theo của chỉ số cho bởi tham số. v_City_Index := t_City.Next(v_City_Index); End Loop; -- Ném ra ngoại lệ No_data_found Raise No_Data_Found; Exception When No_Data_Found Then Dbms_Output.Put_Line('the Last City Has Been Reached.'); End; End; 6.8- Kiểu dữ liệu mảng (Array) -- Khai báo một kiểu mảng IS VARRAY(n) -- Ví dụ khai báo một mảng 5 phần tử, và phẩn tử có kiểu Varchar2(10); TYPE cityarray IS VARRAY(5) OF Varchar2(10);

Một mảng có N phần tử. Các phần tử của mảng được đánh chỉ số liên tục bắt đầu từ 1 đến N.

Declare -- Định nghĩa kiểu dữ liệu Array -- chứa các dữ liệu kiểu VARCHAR2(50) Type Emp_Array Is Varray(5) Of Varchar2(50); -- Định nghĩa kiểu dữ liệu Array chứa các số Integer. Type Salary_Array Is Varray(5) Of Integer; --- v_Names Emp_Array; v_Salaries Salary_Array; v_Count Integer; Begin -- Khởi tạo giá trị các phần tử của mảng. v_Names := Emp_Array('KING' ,'JONES' ,'FORD' ,'SMITH' ,'BLAKE'); -- Khởi tạo giá trị các phần tử của mảng. v_Salaries := Salary_Array(5000 ,2975 ,3000 ,800 ,2850); -- Số phần tử. v_Count := v_Names.Count; --- For i In 1 .. v_Count Loop v_Salaries(i)); End Loop; End;

Cursor là kiểu biến có cấu trúc, cho phép bạn xử lý dữ liệu gồm nhiều dòng. Số dòng phụ thuộc vào câu lệnh truy vấn dữ liệu sau nó.Trong quá trình xử lý, bạn có thể thao tác với Cursor thông qua từng dòng dữ liệu. Dòng dữ liệu này được định vị bởi một con trỏ. Với việc dịch chuyển con trỏ, bạn có thể lấy được toàn bộ dữ liệu của một dòng hiện tại.

Cú pháp khai báo con trỏ:

-- Khai báo con trỏ có không có tham số: IS -- Khai báo con trỏ có tham số. IS -- Cursor declaration has no parameters: Cursor Emp_Cur Is Select Emp.Emp_Id ,Emp.First_Name ,Emp.Last_Name From Employee Emp; -- Cursor declaration has parameters: Cursor Emp_Cur(p_Dept_Id Number ,p_Branch_Id Number) Is Select Emp.Emp_Id ,Emp.First_Name ,Emp.Last_Name ,Emp.Assigned_Branch_Id ,Emp.Dept_Id From Employee Emp Where (Emp.Dept_Id = p_Dept_Id Or p_Dept_Id Is Null) And (Emp.Assigned_Branch_Id = p_Branch_Id Or p_Branch_Id Is Null);

Có hai loại con trỏ (Cursor):

Con trỏ tường minh

Con trỏ không tường minh.

Khái niệm tường minh ở đây có nghĩa là, khi sử dụng nó bạn cần phải viết lệnh mở con trỏ, và viết lệnh đóng con trỏ sau khi đã sử dụng xong một cách rõ ràng. Với trường hợp con trỏ không tường minh bạn có thể không cần viết lệnh đóng mở.

Các thuộc tính của Con trỏ:

7.2- Con trỏ tường minh (Explicit Cursor)

Các bước khai báo và sử dụng con trỏ tường minh:

Declare -- Khai báo một Cursor có 2 tham số. Cursor Emp_Cur ( p_Dept_Id Number ,p_Branch_Id Number ) Is Select Emp.Emp_Id ,Emp.First_Name ,Emp.Last_Name ,Emp.Assigned_Branch_Id ,Emp.Dept_Id From Employee Emp Where (Emp.Dept_Id = p_Dept_Id Or p_Dept_Id Is Null) And (Emp.Assigned_Branch_Id = p_Branch_Id Or p_Branch_Id Is Null); -- Khai báo một kiểu ROWTYPE dựa trên Cursor vừa tạo. v_Emp Emp_Cur%Rowtype; v_Dept_Id Number := 1; v_Branch_Id Number; v_Row Integer := 0; v_Open Boolean; Begin -- Kiểm tra xem cursor mở chưa If Emp_Cur%Isopen Then Dbms_Output.Put_Line('Cursor opened'); Else Dbms_Output.Put_Line('Cursor not open'); End If; -- Dbms_Output.Put_Line('Opening cursor...'); -- Mở Cursor (Truyền các giá trị tham số vào). Open Emp_Cur(v_Dept_Id, v_Branch_Id); -- Sử dụng vòng lặp. Loop -- Lấy dòng dữ liệu trên Cursor -- Mỗi lần Fetch con trỏ nhẩy lên 1 dòng. -- (Từ trên xuống dưới). Fetch Emp_Cur Into v_Emp; -- Điều kiện thoát khỏi vòng lặp. Exit When Emp_Cur%Notfound; -- Sử lý dữ liệu. v_Row := v_Row + 1; End Loop; -- Dbms_Output.Put_Line('Closing cursor...'); -- Đóng Cursor. Close Emp_Cur; End; 7.3- Con trỏ không tường minh (Implicit Cursor)

Con trỏ không tường minh bạn có thể không cần viết lệnh mở/đóng nó một cách rõ ràng.

Sử dụng lệnh For để duyệt trên con trỏ theo cú pháp:

-- Dùng lệnh For duyệt trên con trỏ không tường minh. -- Statements.. END LOOP; Declare -- Khai báo một Cursor có 2 tham số. Cursor Emp_Cur(p_Dept_Id Number ,p_Branch_Id Number) Is Select Emp.Emp_Id ,Emp.First_Name ,Emp.Last_Name ,Emp.Assigned_Branch_Id ,Emp.Dept_Id From Employee Emp Where (Emp.Dept_Id = p_Dept_Id Or p_Dept_Id Is Null) And (Emp.Assigned_Branch_Id = p_Branch_Id Or p_Branch_Id Is Null); v_Dept_Id Number := 1; v_Branch_Id Number; v_Row Integer := 0; Begin -- Kiểm tra xem cursor mở chưa If Emp_Cur%Isopen Then Dbms_Output.Put_Line('Cursor opened'); Else Dbms_Output.Put_Line('Cursor not open'); End If; -- -- Sử dụng vòng lặp để duyệt cursor -- Không cần open/close/fetch. -- For v_Emp In Emp_Cur(v_Dept_Id ,v_Branch_Id) Loop -- v_Row := v_Row + 1; End Loop; End;

Một nhóm các lệnh thực hiện chức năng nào đó có thể được gom lại trong một thủ tục (procedure) nhằm làm tăng khả năng xử lý,khả năng sử dụng chung, tăng tính bảo mật và an toàn dữ liệu,tiện ích trong phát triển. Thủ tục có thể được lưu giữ ngay trong database như một đối tượng của database, sẵn sàng cho việc tái sử dụng. Thủ tục lúc này được gọi là Stored procedure. Với các thủ tục, ngay khi lưu giữ (save), chúng đã được biên dịch thành dạng p-code vì thế có thể nâng cao khả năng thực hiện.

Thủ tục không trả về giá trị trực tiếp như hàm.

-- procedure_name: Tên thủ tục -- argument: Tên tham số -- mode: Loại tham số: IN hoặc OUT hoặc IN OUT, mặc định là IN -- datatype: Kiểu dữ liệu của tham số [ (argument1 [mode1] datatype1, argument2 [mode2] datatype2, ...) ] BEGIN -- PL/SQL Block; END; -- Ví dụ một thủ tục không tham số. CREATE OR REPLACE Procedure Do_Something AS Begin End; -- Ví dụ một thủ tục có tham số -- Vừa tham số đầu vào, vừa tham số đầu ra. CREATE OR REPLACE Procedure Do_Something(p_Param1 Varchar2, v_Param Out Varchar2) AS Begin End;

Hủy thủ tục (drop procedure):

-- Hủy một thủ tục:

Các bước thực hiện một thủ tục:

Ví dụ tạo một thủ tục:

Đây là một ví dụ tạo một thủ tục đầu tiên trên PL/SQL Developer. ví dụ này sẽ là khuôn mẫu giúp bạn vừa lập trình vừa kiểm tra lỗi nếu có vấn đề xẩy ra.

Tạo một thủ tục (Procedure)

Biên dịch thủ tục này

Chạy thủ tục

Debug thủ tục bằng PL/SQL Developer để xem chương trình chạy thế nào.

Tạo mới một thủ tục (Procedure):

Nhập vào tên của thủ tục, các tham số sẽ được viết sau:

Thủ tục đã được PL/SQL Developer tạo ra. Tuy nhiên bạn cần sửa lại danh sách tham số, và viết code cho thủ tục này.

Sửa thủ tục của bạn như sau:

-- Thủ tục truyền vào p_Emp_Id -- Và trả về v_First_Name, v_Last_Name, v_Dept_Id. Create Or Replace Procedure Get_Employee_Infos(p_Emp_Id Number ,v_First_Name Out Varchar2 ,v_Last_Name Out Varchar2 ,v_Dept_Id Out Number) Is Begin -- Ghi ra màn hình console. -- Dành cho người lập trình biết chương trình chạy thế nào. -- -- Nếu câu lệnh Select này nếu không có bản ghi nào -- nó sẽ ném ra Exception NO_DATA_FOUND: -- -- Câu lệnh Select ở này sẽ không trả về -- nhiều hơn 1 bản ghi vì Emp_Id là duy nhất -- trong bảng EMPLOYEE. -- Do vậy không xẩy ra ngoại lệ TOO_MANY_ROWS -- Select Emp.First_Name ,Emp.Last_Name ,Emp.Dept_Id Into v_First_Name ,v_Last_Name ,v_Dept_Id From Employee Emp Where Emp.Emp_Id = p_Emp_Id; -- -- Ghi ra màn hình Console. -- Dbms_Output.Put_Line('Found Record!'); Exception When No_Data_Found Then -- Ghi ra màn hình Console. End Get_Employee_Infos;

Nhấn vào biểu tượng Execute

hoặc F8 để biên dịch thủ tục. Trong trường hợp có lỗi code, PL/SQL Developer sẽ thông báo cho bạn.

8.1- Test thủ tục trên PL/SQL Developer

Nhấn phải chuột vào thủ tục Get_Employee_Infos chọn Test:

Nhập tham số đầu vào, ví dụ:

Kết quả thực thi thủ tục:

Xem trên màn hình Console:

Test trường hợp khác với các giá trị:

8.2- Debug thủ tục trên PL/SQL Developer

Debug trên PL/SQL Developer cho phép bạn xem một thủ tục, hàm đã được chạy thế nào, theo từng lệnh. Giúp bạn dễ dàng tìm ra các vị trí phát sinh lỗi. Bạn có thể xem hướng dẫn tại:

Tương tự như thủ tục, hàm (function) cũng là nhóm các lệnh PL/SQL thực hiện chức năng nào đó. Khác với thủ tục, các hàm sẽ trả về một giá trị ngay tại lời gọi của nó. Hàm cũng có thể được lưu giữ ngay trên database dưới dạng Stored procedure.

Với việc sử dụng hàm, trong một số trường hợp bạn có thể thấy được các lợi điểm như sau:

Cho phép thực hiện các thao tác phức tạp(các phép tìm kiếm, so sánh phứctạp) ngay trong mệnh đề của câu lệnh SQL mà nếu không sử dụng hàm bạn sẽ không thể nào thực hiện được

Tăng tính độc lập của dữ liệu do việc phân tích và xử lý dữ liệu được thực hiện ngay trên Server thay vì trả về dữ liệu trực tiếp cho ứng dụng dưới Client để chúng tiếp tục xử lý.

Tăng tính hiệu quả của câu lệnh truy vấn bằng việc gọi các hàm ngay trong câu lệnh SQL

Bạn có thể sử dụng hàm để thao tác trên các kiểu dữ liệu tự tạo. Cho phép thực hiện đồng thời các câu lệnh truy vấn

Một số hạn chế khi sử dụng hàm trong câu lệnh SQL

Chỉ các hàm do người dùng định nghĩa được lưu trên database mới có thể sử dụng được cho câu lệnh SQL.

Các hàm do người dùng định nghĩa chỉ được áp dụng cho điều kiện thực hiện trên các dòng dữ liệu (mệnh đề WHERE), không thể áp dụng cho các điều kiện thực hiện trên nhóm (mệnh đề GROUP).

Tham số sử dụng trong hàm chỉ có thể là loại IN, không chấp nhận giá trị OUT hay giá trị IN OUT.

Kiểu dữ liệu trả về của các hàm phải là kiểu dữ liệu DATE, NUMBER, NUMBER. Không cho phép hàm trả về kiểu dữ liệu như BOOLEAN, RECORD, TABLE. Kiểu dữ liệu trả về này phải tương thích với các kiểu dữ liệu bên trong Oracle Server .

Cú pháp tạo Hàm.

-- function_name: Tên hàm -- argument: Tên tham số -- mode: Loại tham số: IN hoặc OUT hoặc IN OUT, mặc định là IN -- datatype: Kiểu dữ liệu của tham số [ (argument1 [mode1] datatype1, argument2 [mode2] datatype2, ...) ] RETURN datatype BEGIN -- PL/SQL Block; END; -- Function has 1 parameter: CREATE OR REPLACE FUNCTION Sum(a Integer, b Integer) RETURN Integer AS Begin return a + b; End; -- A function with no parameters: CREATE OR REPLACE FUNCTION Get_Current_Datetime RETURN Date AS Begin return sysdate; End;

Hủy Function (Drop function):

-- Hủy Function -- Khi gọi hàm phải khai báo một biến trả về -- Khai báo một biến c. c Integer; .... -- Gọi hàm. c := Sum(10, 100);

Ví dụ tạo một hàm.

-- Hàm truyền vào mã hệ thống của nhân viên p_Emp_ID -- Và trả về First_Name của nhân viên. Create Or Replace Function Get_Emp_First_Name(p_Emp_Id Number) Return Varchar2 As -- Khai báo một biến v_Emp_First_Name v_Emp_First_Name Employee.First_Name%Type; Begin Begin Select Emp.First_Name Into v_Emp_First_Name From Employee Emp Where Emp.Emp_Id = p_Emp_Id; Exception When No_Data_Found Then -- Gán null trong trường hợp không tìm thấy Employee -- ứng với p_Emp_ID v_Emp_First_Name := Null; End; -- Return v_Emp_First_Name; End;

Các hàm không có tham số OUT, có thể tham gia vào câu lệnh SQL, ví dụ:

Select Emp.Emp_Id ,Get_Emp_First_Name(Emp.Emp_Id) Emp_First_Name From Employee Emp;

Kết quả chạy câu lệnh SQL trên:

Package là một tập hợp các kiểu dữ liệu, biến lưu giữ giá trị và các thủ tục,hàm có cùng một mối liên hệ với nhau, được gộp chung lại. Đặc điểm nổi bật nhất của package là khi một phần tử trong package được gọi tới thì toàn bộ nội dung của package sẽ được nạp vào trong hệ thống. Do đó, việc gọi tới các phần tử khác trong package sau này sẽ không phải mất thời gian nạp vào hệ thống nữa. Từ đó, nâng cao tốc độ thực hiện lệnh của toàn bộ hàm, thủ tục có trong package.

Một package được cấu trúc làm hai phần. Phần mô tả (specification) định nghĩa các giao tiếp có thể có của package với bên ngoài. Phần thân (body) là các cài đặt cho các giao tiếp có trong phần mô tả ở trên.

Trong cấu trúc của package bao gồm 5 thành phần:

Public variable (biến công cộng): là biến mà các ứng dụng bên ngoài có thể tham chiếu tới được (sử dụng được).

Public procedure (thủ tục công cộng): bao gồm các hàm, thủ tục của package có thể gọi từ các ứng dụng bên ngoài.

Private procedure (thủ tục riêng tư): là các hàm, thủ tục có trong package và chỉ có thể được gọi bởi các hàm hay thủ tục khác trong package đó mà thôi.

Global variable (biến tổng thể): là biến được khai báo dùng trong toàn bộ package, ứng dụng bên ngoài tham chiếu được tới biến này .

Private variable (biến riêng tư): là biến được khai báo trong một hàm, thủ tục thuộc package.Nó chỉ có thể được sử dụng trong nội bộ hàm hay thủ tục đó.

-- Khai báo Package Spec: -- Khai báo các kiểu (sẽ được sử dụng công khai) -- và các hàm thủ tục. -- Khai báo phần Body Package: -- Khai báo các kiểu chỉ sử dụng riêng trong package -- Triển khai nội dung của các hàm, thủ tục khai báo trong Package Spec 10.1- Tạo package trên PL/SQL Developer

Bạn có thể xóa hết các code tự tạo ra tự động bởi PL/SQL Developer để có một package rỗng:

-- -- Đây là Package Spec của Package PKG_EMP -- Nó khai báo 2 hàm (Trong khi Package Body có 2 hàm và 1 thủ tục). -- Những hàm hoặc thủ tục không được khai báo trên Package Spec -- nghĩa là chỉ được sử dụng trong nội bộ package. -- Create Or Replace Package Pkg_Emp Is -- Hàm trả về First_Name Function Get_First_Name(p_Emp_Id Employee.Emp_Id%Type) Return Employee.First_Name%Type; -- Hàm trả về tên phòng ban của nhân viên. Function Get_Dept_Name(p_Emp_Id Employee.Emp_Id%Type) Return Department.Name%Type; End Pkg_Emp; -- -- Đây là Package Body của Package PKG_EMP -- Create Or Replace Package Body Pkg_Emp Is -- ===================================================== -- Thủ tục trả về thông tin nhân viên -- Gồm 2 tham số đầu ra v_First_Name, v_Last_Name -- ===================================================== Procedure Get_Emp_Infos(p_Emp_Id Employee.Emp_Id%Type ,v_First_Name Out Employee.Emp_Id%Type ,v_Last_Name Out Employee.Last_Name%Type) As Begin Begin Select Emp.First_Name ,Emp.Last_Name Into v_First_Name ,v_Last_Name From Employee Emp Where Emp.Emp_Id = p_Emp_Id; Exception -- Không tìm thấy nhân viên ứng với p_Emp_Id When No_Data_Found Then v_First_Name := Null; v_Last_Name := Null; End; End; -- ===================================================== -- Hàm trả về First_Name ứng với Emp_ID cho bởi tham số. -- ===================================================== Function Get_First_Name(p_Emp_Id Employee.Emp_Id%Type) Return Employee.First_Name%Type As -- Khai báo một biến. v_First_Name Employee.First_Name%Type; v_Last_Name Employee.Last_Name%Type; Begin -- Gọi sử dụng thủ tục Get_Emp_Infos Get_Emp_Infos(p_Emp_Id ,v_First_Name -- Out ,v_Last_Name -- Out ); -- Return v_First_Name; End; -- ===================================================== -- Hàm trả về Dept_Name ứng với Emp_ID. -- (Trả về tên phòng ban của nhân viên) -- ===================================================== Function Get_Dept_Name(p_Emp_Id Employee.Emp_Id%Type) Return Department.Name%Type As -- Khai báo một biến. v_Dept_Name Department.Name%Type; Begin Begin Select Dept.Name Into v_Dept_Name From Employee Emp ,Department Dept Where Emp.Dept_Id = Dept.Dept_Id And Emp.Emp_Id = p_Emp_Id; Exception When No_Data_Found Then v_Dept_Name := Null; End; -- Return v_Dept_Name; End; End Pkg_Emp;

Cũng giống như thủ tục và hàm, bạn cũng có thể test các thủ tục/hàm trên Package, điều này giúp bạn phát hiện ra các lỗi trong quá trình lập trình.

Oracle Application Express (Oracle APEX), trước đây gọi là HTML DB, là một công cụ phát triển ứng dụng web nhanh chóng cho các cơ sở dữ liệu Oracle. Chỉ sử dụng một trình duyệt web và kinh nghiệm lập trình không cần nhiều, bạn có thể phát triển và triển khai các ứng dụng chuyên nghiệp mà cả hai nhanh chóng và bảo mật. Oracle Application Express kết hợp những phẩm chất của một cơ sở dữ liệu cá nhân, năng suất, dễ sử dụng, và tính linh hoạt với những phẩm chất của một cơ sở dữ liệu doanh nghiệp, bảo mật, toàn vẹn, khả năng mở rộng, tính sẵn có và xây dựng cho web. Application Express là một công cụ để xây dựng các ứng dụng dựa trên web và các môi trường phát triển ứng dụng cũng thuận tiện dựa trên web.