Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Basics Oracle

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 54

Main Table

SQL> create table myaudit( 2 id VARCHAR2(4 BYTE) NOT NULL, 3 old_value VARCHAR2(40 BYTE), 4 new_value VARCHAR2(40 BYTE) 5 ); Table created. SQL> SQL> -- create demo table SQL> create table Employee( 2 ID VARCHAR2(4 BYTE) T NULL, 3 First_Name VARCHAR2(10 BYTE), 4 Last_Name VARCHAR2(10 BYTE), 5 Start_Date DATE, 6 End_Date DATE, 7 Salary Number(8,2), 8 City VARCHAR2(10 BYTE), 9 Description VARCHAR2(15 BYTE) 10 ) 11 / ID FIRST_NAME LAST_NAME START_DAT ION ---- ---------- ---------- --------------01 Jason Martin 25-JUL-96 06 1234.56 Toronto Programmer 02 Alison Mathews 21-MAR-76 03 James Smith 12-DEC-78 04 Celia Rice 24-OCT-82 05 Robert Black 15-JAN-84 06 Linda Green 30-JUL-87 07 David Larry 31-DEC-90 08 James Cat 17-SEP-96 END_DATE SALARY CITY

NO

DESCRIPT

--------- ---------- ---------- -------25-JUL21-FEB-86 15-MAR-90 21-APR-99 08-AUG-98 04-JAN-96 12-FEB-98 15-APR-02 6661.78 6544.78 2344.78 2334.78 4322.78 7897.78 1232.78 Vancouver Vancouver Vancouver Vancouver New York New York Vancouver Tester Tester Manager Tester Tester Manager Tester

CURSOR
You use a cursor when you have a SELECT statement that returns more than one row from the database. A cursor is basically a set of rows that you can access one at a time. You retrieve the rows into the cursor using your SELECT statement and then fetch the rows from the cursor. You may follow five steps when using a cursor: 1. 2. 3. 4. 5. 6. Declare variables to store the column values from the SELECT statement. Declare the cursor, specifying your SELECT statement. Open the cursor. Fetch the rows from the cursor. Close the cursor. The syntax for declaring a cursor is as follows:

CURSOR cursor_name IS SELECT_statement; where cursor_name specifies the name of the cursor.

SELECT_statement is a SELECT statement. You open a cursor using the OPEN statement, which must be placed in the executable section of the block. To read each row from the cursor, you can use the FETCH statement. The FETCH statement reads the column values into the variables that you specify;
FETCH uses the following syntax: FETCH cursor_name INTO variable[, variable ...];

where 1. cursor_name specifies the name of the cursor. 2. variable is a previously declared variable into which values from the cursor's SELECT statement are stored. Once you've finished with the cursor, the final step is to close the cursor using the CLOSE statement. Closing your cursors frees up system resources.

DECLARE 2 -- step 1: declare the variables 3 v_id employee. id%TYPE; 4 v_name employee.first_name%TYPE; 5 v_salary employee.salary%TYPE; 6 7 -- step 2: declare the cursor 8 CURSOR cv_employee_cursor IS 9 SELECT id, first_name, salary 10 FROM employee 11 ORDER BY id; 12 13 BEGIN 14 15 -- step 3: open the cursor 16 OPEN cv_employee_cursor; 17 18 LOOP 19 20 -- step 4: fetch the rows from the cursor 21 FETCH cv_employee_cursor 22 INTO v_id, v_name, v_salary; 23 24 -- exit the loop when there are no more rows, as indicated by 25 -- the Boolean variable NOTFOUND (= true when 26 -- there are no more rows) 27 EXIT WHEN cv_employee_cursor%NOTFOUND; 28 -- use DBMS_OUTPUT.PUT_LINE() to display the variables 29 DBMS_OUTPUT.PUT_LINE( 30 'v_id = ' || v_id || ', v_name = ' || v_name || 31 ', v_salary = ' || v_salary 32 ); 33 34 END LOOP; 35 36 -- step 5: close the cursor 37 CLOSE cv_employee_cursor; 38 39 END;

Nested cursor
SQL> CREATE TABLE emp ( 2 id NUMBER PRIMARY KEY, 3 fname VARCHAR2(50), 4 lname VARCHAR2(50) 5 ); Table created.

SQL> SQL> INSERT INTO emp (id, fname, lname)VALUES (1, 'A', 'B'); 1 row created. SQL> INSERT INTO emp (id, fname, lname)VALUES (2, 'C', 'D'); 1 row created. SQL> INSERT INTO emp (id, fname, lname)VALUES (3, 'Enn', 'F'); 1 row created. SQL> INSERT INTO emp (id, fname, lname)VALUES (4, 'G', 'H'); 1 row created. SQL> INSERT INTO emp (id, fname, lname)VALUES (5, 'G', 'Z'); 1 row created. SQL> SQL> SQL> CREATE TABLE books ( 2 isbn CHAR(10) PRIMARY KEY, 3 category VARCHAR2(20), 4 title VARCHAR2(100), 5 num_pages NUMBER, 6 price NUMBER, 7 copyright NUMBER(4), 8 emp1 NUMBER, 9 emp2 NUMBER, 10 emp3 NUMBER 11 ); Table created.

SQL> INSERT INTO books (isbn, category, title, num_pages, price, copyright, e mp1, emp2, emp3) 2 VALUES ('1', 'Database', 'Oracle', 563, 39.99, 2009, 1, 2, 3) ; 1 row created. SQL> INSERT INTO books (isbn, category, title, num_pages, price, copyright, e mp1, emp2) 2 VALUES ('2', 'Database', 'MySQL', 765, 44.99, 2009, 4, 5);

1 row created. SQL> INSERT INTO books (isbn, category, title, num_pages, price, copyright, e mp1, emp2, emp3) 2 VALUES ('3', 'Database', 'SQL Server', 404, 39.99, 2001, 6, 7 , 8); 1 row created. SQL> SQL> SET SERVEROUTPUT ON ESCAPE OFF SQL>

SQL> DECLARE
2 3 4 5 6 7 8 cv_emp SYS_REFCURSOR; v_title BOOKS.TITLE%TYPE; v_emp emp%ROWTYPE; v_counter PLS_INTEGER := 0; CURSOR book_cur IS SELECT b.title,

CURSOR (SELECT * FROM emp a WHERE a.id = b.emp1 OR a.id = b.emp2 OR a.id = b. emp3) 9 FROM books b 10 WHERE isbn = '1'; 11 12 BEGIN 13 14 DBMS_OUTPUT.ENABLE(1000000); 15 16 OPEN book_cur; 17 18 LOOP 19 FETCH book_cur INTO v_title, cv_emp; 20 EXIT WHEN book_cur%NOTFOUND; 21 22 v_counter := 0; 23 24 DBMS_OUTPUT.PUT_LINE('Title from the main cursor: '||v_title); 25 26 LOOP 27 FETCH cv_emp INTO v_emp; 28 EXIT WHEN cv_emp%NOTFOUND; 29 30 v_counter := v_counter + 1; 31 32 DBMS_OUTPUT.PUT_LINE('emp'||v_counter||': '||v_emp.fname||' '|| v_emp.lname); 33 END LOOP;

34 END LOOP; 35 36 CLOSE book_cur; 37 38 END; 39 / Title from the main cursor: Oracle emp1: Enn F emp2: C D emp3: A B

A Cursor for counting


2 3 4 5 6 7 8 9 declare cursor c_countEmps is select count(*) from employee; v_out NUMBER; begin open c_countEmps; fetch c_countEmps into v_out; close c_countEmps; DBMS_OUTPUT.put_line('number of emps is:'||v_out); end;

http://www.java2s.com/Tutorial/Oracle/0500__Cursor/Cursortoreferencewholetable.htm

Create a cursor for update


DECLARE 2 3 4 5 BEGIN 6 7 8 9 10 11 12 END; CURSOR product_cur IS SELECT * FROM product FOR UPDATE OF product_price; FOR product_rec IN product_cur LOOP UPDATE product SET product_price = (product_rec.product_price * 0.97) WHERE CURRENT OF product_cur; END LOOP;

Procedures
You can create a procedure that contains a group of SQL and PL/SQL statements. Procedures allow you to centralize your business logic in the database. Procedures may be used by any program that accesses the database. You create a procedure using the CREATE PROCEDURE statement. The simplified syntax for the CREATE PROCEDURE statement is as follows:
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter_name [IN | OUT | IN OUT] type [, ...])] {IS | AS} BEGIN procedure_body END procedure_name;

where 1. 2. 3. 4. 5. 6. OR REPLACE specifies the procedure is to replace an existing procedure if present. You can use this option when you want to modify a procedure. A procedure may be passed multiple parameters. IN | OUT | IN OUT specifies the mode of the parameter. type specifies the type of the parameter. procedure_body contains the SQL and PL/SQL statements to perform the procedure's task.

You may pick one of the following modes for each parameter: 1. 2. 3. 4. 5. IN is the default mode for a parameter. IN parameters already have a value when the procedure is run. The value of IN parameters may not be changed in the body. OUT is specified for parameters whose values are only set in the body. IN OUT parameters may already have a value when the procedure is called, but their value may also be changed in the body.
create or replace procedure hello_world 2 as 3 begin 4 dbms_output.put_line('Hello World!'); 5 end; 6 /

Execute a procedure
SQL> set serveroutput on

SQL> 2 3 4 5 6 7

CREATE or replace PROCEDURE my_first_proc IS greetings VARCHAR2(20); BEGIN greetings := 'Hello World'; dbms_output.put_line(greetings); END my_first_proc; /

SQL> SQL> EXECUTE Hello World

my_first_proc;

Wrapping a task into a procedure


SQL> declare 2 v VARCHAR2(50):= 'I just printed my <in> line!'; 3 procedure p_print(i_string in VARCHAR2, i_replace in VARCHAR2 := 'ne w') is 4 begin 5 DBMS_OUTPUT.put_line(replace(i_string,'<in>', i_replace)); 6 end; 7 begin 8 p_print (v,'first'); 9 p_print (v,'second'); 10 p_print (v); 11 end; 12 / I just printed my first line! I just printed my second line! I just printed my new line! PL/SQL procedure successfully completed.

Demonstration of a nested procedure block


SQL> SET ECHO ON SQL> SET SERVEROUTPUT ON SQL> SQL> DECLARE 2 first_number NUMBER; 3 second_number NUMBER; 4 5 PROCEDURE swapn (num_one IN OUT NUMBER, num_two IN OUT NUMBER) IS 6 temp_num NUMBER; 7 BEGIN 8 temp_num := num_one;

9 num_one := num_two; 10 num_two := temp_num ; 11 END; 12 13 BEGIN 14 15 first_number := 10; 16 second_number := 20; 17 DBMS_OUTPUT.PUT_LINE('First Number = ' || TO_CHAR (first_number)); 18 DBMS_OUTPUT.PUT_LINE('Second Number = ' || TO_CHAR (second_number)); 19 20 --Swap the values 21 DBMS_OUTPUT.PUT_LINE('Swapping the two values now.'); 22 swapn(first_number, second_number); 23 24 --Display the results 25 DBMS_OUTPUT.PUT_LINE('First Number = ' || to_CHAR (first_number)); 26 DBMS_OUTPUT.PUT_LINE('Second Number = ' || to_CHAR (second_number)); 27 END; 28 / First Number = 10 Second Number = 20 Swapping the two values now. First Number = 20 Second Number = 10 PL/SQL procedure successfully completed.

Package:

Insert data into table with inheritecd columns


SQL> SQL> SQL> CREATE Or Replace TYPE AddressType AS OBJECT ( 2 street VARCHAR2(15), 3 city VARCHAR2(15), 4 state CHAR(2), 5 zip VARCHAR2(5) 6 ) 7 / Type created. SQL> SQL> CREATE Or Replace TYPE PersonType AS OBJECT ( 2 id NUMBER, 3 first_name VARCHAR2(10), 4 last_name VARCHAR2(10), 5 dob DATE, 6 phone VARCHAR2(12), 7 address AddressType 8 ) NOT FINAL; 9 / Type created. SQL> SQL> CREATE Or replace TYPE business_PersonType UNDER PersonType ( 2 title VARCHAR2(20), 3 company VARCHAR2(20) 4 ) 5 / Type created. SQL> SQL> SQL> CREATE TABLE object_business_customers OF business_PersonType 2 / Table created. SQL> SQL> SQL> INSERT INTO object_business_customers VALUES ( 2 business_PersonType(1, 'John', 'Brown', '01-FEB-1933', '800-555-3333', 3 AddressType('2 Ave', 'town', 'MA', '12345'),'Manager', 'XYZ Corp') 4 ); 1 row created. SQL>

SQL> SQL> SQL> SELECT * 2 FROM object_business_customers; ID FIRST_NAME LAST_NAME DOB PHONE --- -------------------- -------------------- --------- -----------ADDRESS(STREET, CITY, STATE, ZIP) -------------------------------------------------------------------TITLE COMPANY -------------------- -------------------1 John Brown 01-FEB-33 800-555-3333 ADDRESSTYPE('2 Ave', 'town', 'MA', '12345') Manager XYZ Corp SQL> SQL> SQL> drop table object_business_customers; Table dropped. SQL> SQL> SQL> drop type business_PersonType; Type dropped. SQL> SQL> drop type persontype; Type dropped. SQL> SQL> drop type addresstype; Type dropped.

Packages
1. 2. 3. 4. 5. 6. 7. Packages encapsulate related functionality into one self-contained unit. Packages are typically made up of two components: a specification and a body. The package specification contains information about the package. The package specification lists the available procedures and functions. These are potentially available to all database users. The package specification generally doesn't contain the code. The package body contains the actual code.

You create a package body using the CREATE PACKAGE BODY statement. The simplified syntax for the CREATE PACKAGE BODY statement is as follows:
SQL> CREATE [OR REPLACE] PACKAGE BODY package_name 2 {IS | AS} 3 package_body 4 END package_name;

Where package_name specifies the name of the package, which must match the package name previously set in the package specification. package_body specifies the code for the procedures and functions, along with any variables and cursors. Creating a Package Specification

You create a package specification using the CREATE PACKAGE statement. The simplified syntax for the CREATE PACKAGE statement is as follows:
CREATE [OR REPLACE] PACKAGE package_name {IS | AS} package_specification END package_name;

package_specification specifies the list of procedures and functions (along with any variables, type definitions, and cursors) that are available to your package's users.
SQL> CREATE OR REPLACE PACKAGE employee_package AS 2 TYPE t_ref_cursor IS REF CURSOR; 3 FUNCTION get_employee_ref_cursor RETURN t_ref_cursor;

4 5 6 7 8 9

PROCEDURE update_salary ( p_id IN VARCHAR2, p_factor IN NUMBER ); END employee_package; /

CREATE OR REPLACE PACKAGE command:


SQL> 2 3 4 5 6 7 8 create or replace package pkg_test1 as function getArea (i_rad NUMBER) return NUMBER; procedure p_print (i_str1 VARCHAR2 :='hello', i_str2 VARCHAR2 :='world', i_end VARCHAR2 :='!' ); end; /

Package created. SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 create or replace package body pkg_test1 as function getArea (i_rad NUMBER)return NUMBER is v_pi NUMBER:=3.14; begin return v_pi * (i_rad ** 2); end; procedure p_print(i_str1 VARCHAR2 :='hello', i_str2 VARCHAR2 :='world', i_end VARCHAR2 :='!' ) is begin DBMS_OUTPUT.put_line(i_str1||','||i_str2||i_end); end; end; /

A Package Specification and its body

create demo table SQL> create table Employee( 2 ID VARCHAR2(4 BYTE) 3 First_Name VARCHAR2(10 BYTE), 4 Last_Name VARCHAR2(10 BYTE), 5 Start_Date DATE, 6 End_Date DATE, 7 Salary Number(8,2), 8 City VARCHAR2(10 BYTE), 9 Description VARCHAR2(15 BYTE) 10 ) 11 / Table created.

NOT NULL,

SQL> SQL> -- prepare data SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values ('01','Jason', 'Martin', to_date('19960725','YYY YMMDD'), to_date('20060725','YYYYMMDD'), 1234.56, 'Toronto', 'Programmer') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('02','Alison', 'Mathews', to_date('19760321','YYY YMMDD'), to_date('19860221','YYYYMMDD'), 6661.78, 'Vancouver','Tester') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('03','James', 'Smith', to_date('19781212','YYY YMMDD'), to_date('19900315','YYYYMMDD'), 6544.78, 'Vancouver','Tester') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('04','Celia', 'Rice', to_date('19821024','YYY YMMDD'), to_date('19990421','YYYYMMDD'), 2344.78, 'Vancouver','Manager') 3 / 1 row created.

SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('05','Robert', 'Black', to_date('19840115','YYY YMMDD'), to_date('19980808','YYYYMMDD'), 2334.78, 'Vancouver','Tester') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('06','Linda', 'Green', to_date('19870730','YYY YMMDD'), to_date('19960104','YYYYMMDD'), 4322.78,'New York', 'Tester') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('07','David', 'Larry', to_date('19901231','YYY YMMDD'), to_date('19980212','YYYYMMDD'), 7897.78,'New York', 'Manager') 3 / 1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('08','James', 'Cat', to_date('19960917','YYY YMMDD'), to_date('20020415','YYYYMMDD'), 1232.78,'Vancouver', 'Tester') 3 / 1 row created. SQL> SQL> SQL> SQL> -- display data in the table SQL> select * from Employee 2 / ID FIRST_NAME LAST_NAME CITY DESCRIPTION ---- -------------------- ----------------------------- --------------01 Jason Martin 06 1234.56 Toronto Programmer 02 Alison Mathews 86 6661.78 Vancouver Tester 03 James Smith 90 6544.78 Vancouver Tester START_DAT END_DATE SALARY

--------- --------- ---------25-JUL-96 25-JUL21-MAR-76 21-FEB12-DEC-78 15-MAR-

04 99 05 98 06 96 07 98 08 02

Celia 2344.78 Robert 2334.78 Linda 4322.78 David 7897.78 James 1232.78

Vancouver Vancouver New York New York Vancouver

Rice Manager Black Tester Green Tester Larry Manager Cat Tester

24-OCT-82 21-APR15-JAN-84 08-AUG30-JUL-87 04-JAN31-DEC-90 12-FEB17-SEP-96 15-APR-

8 rows selected. SQL> SQL> SQL> SQL> CREATE OR REPLACE PACKAGE EmployeePackage AS 2 PROCEDURE AddEmployee(p_EmployeeID IN Employee.id%TYPE, 3 p_first_name IN Employee.first_name%TYPE, 4 p_last_name IN Employee.last_name%TYPE); 5 6 -- Removes the specified student from the specified class. 7 PROCEDURE RemoveEmployee(p_EmployeeID IN Employee.id%TYPE, 8 p_first_name IN Employee.first_name%TYPE, 9 p_last_name IN Employee.last_name%TYPE); 10 11 -- Exception raised by RemoveEmployee. 12 e_EmployeeNotRegistered EXCEPTION; 13 14 -- Table type used to hold student info. 15 TYPE t_EmployeeIDTable IS TABLE OF Employee.id%TYPE INDEX BY BINARY_IN TEGER; 16 17 -- Returns a PL/SQL table containing the Employee currently 18 -- in the specified class. 19 PROCEDURE EmployeeList(p_first_name IN Employee.first_name%TYPE, 20 p_last_name IN Employee.last_name%TYPE, 21 p_IDs OUT t_EmployeeIDTable, 22 p_NumEmployees IN OUT BINARY_INTEGER); 23 END EmployeePackage; 24 / SP2-0808: Package created with compilation warnings SQL> SQL> CREATE OR REPLACE PACKAGE BODY EmployeePackage AS 2 PROCEDURE AddEmployee(p_EmployeeID IN Employee.id%TYPE, 3 p_first_name IN Employee.first_name%TYPE, 4 p_last_name IN Employee.last_name%TYPE) IS

BEGIN INSERT INTO Employee (id, first_name, last_name) VALUES (p_EmployeeI D, p_first_name, p_last_name); 7 COMMIT; 8 END AddEmployee; 9 10 PROCEDURE RemoveEmployee(p_EmployeeID IN Employee.id%TYPE, 11 p_first_name IN Employee.first_name%TYPE, 12 p_last_name IN Employee.last_name%TYPE) I S 13 BEGIN 14 DELETE FROM Employee 15 WHERE id = p_EmployeeID 16 AND first_name = p_first_name 17 AND last_name = p_last_name; 18 19 -- Check to see if the DELETE operation was successful. If 20 -- it didn't match any rows, raise an error. 21 IF SQL%NOTFOUND THEN 22 RAISE e_EmployeeNotRegistered; 23 END IF; 24 25 COMMIT; 26 END RemoveEmployee; 27 28 29 -- Returns a PL/SQL table containing the Employee currently 30 -- in the specified class. 31 PROCEDURE EmployeeList(p_first_name IN Employee.first_name%TYPE, 32 p_last_name IN Employee.last_name%TYPE, 33 p_IDs OUT t_EmployeeIDTable, 34 p_NumEmployees IN OUT BINARY_INTEGER) IS 35 36 v_EmployeeID Employee.id%TYPE; 37 38 -- Local cursor to fetch the registered Employee. 39 CURSOR c_RegisteredEmployees IS 40 SELECT id 41 FROM Employee 42 WHERE first_name = p_first_name 43 AND last_name = p_last_name; 44 BEGIN 45 /* p_NumEmployees will be the table index. It will start at 46 0, and be incremented each time through the fetch loop. 47 At the end of the loop, it will have the number of rows 48 fetched, and therefore the number of rows returned in 49 p_IDs. */ 50 p_NumEmployees := 0; 51

5 6

52 53 54 55 56 57 58 59 60 61 62

OPEN c_RegisteredEmployees; LOOP FETCH c_RegisteredEmployees INTO v_EmployeeID; EXIT WHEN c_RegisteredEmployees%NOTFOUND; p_NumEmployees := p_NumEmployees + 1; p_IDs(p_NumEmployees) := v_EmployeeID; END LOOP; END EmployeeList; END EmployeePackage; /

SP2-0810: Package Body created with compilation warnings SQL> SQL> --Calling a Packaged Procedure SQL> DECLARE 2 v_HistoryEmployees EmployeePackage.t_EmployeeIDTable; 3 v_NumEmployees BINARY_INTEGER := 20; 4 BEGIN 5 EmployeePackage.EmployeeList('James', 'Cat', v_HistoryEmployees,v_NumE mployees); 6 7 -- Insert these Employee into temp_table. 8 FOR v_LoopCounter IN 1..v_NumEmployees LOOP 9 DBMS_OUTPUT.put_line(v_HistoryEmployees(v_LoopCounter)); 10 END LOOP; 11 END; 12 / 08 PL/SQL procedure successfully completed.

Overloading Packaged Subprograms

SQL> CREATE OR REPLACE PACKAGE EmployeePackage AS 2 PROCEDURE AddEmployee(p_EmployeeID IN Employee.id%TYPE, 3 p_first_name IN Employee.first_name%TYPE, 4 p_last_name IN Employee.last_name%TYPE); 5 6 PROCEDURE AddEmployee(p_FirstName IN Employee.first_name%TYPE, 7 p_LastName IN Employee.last_name%TYPE, 8 p_city IN Employee.city%TYPE); 9 10 END EmployeePackage; 11 / Package created. SQL> SQL> CREATE OR REPLACE PACKAGE BODY EmployeePackage AS 2 3 PROCEDURE AddEmployee(p_EmployeeID IN Employee.id%TYPE, 4 p_first_name IN Employee.first_name%TYPE, 5 p_last_name IN Employee.last_name%TYPE) IS 6 BEGIN 7 INSERT INTO Employee (id, first_name, last_name) 8 VALUES (p_EmployeeID, p_first_name, p_last_name); 9 COMMIT; 10 END AddEmployee; 11 12 -- Add a new student by name, rather than ID. 13 PROCEDURE AddEmployee(p_FirstName IN Employee.first_name%TYPE, 14 p_LastName IN Employee.last_name%TYPE, 15 p_city IN Employee.city%TYPE) IS 16 v_EmployeeID Employee.ID%TYPE; 17 BEGIN 18 SELECT ID 19 INTO v_EmployeeID 20 FROM Employee 21 WHERE first_name = p_FirstName 22 AND last_name = p_LastName; 23 24 -- Now we can add the student by ID. 25 INSERT INTO Employee (id, first_name, city) 26 VALUES (v_EmployeeID, p_firstname, p_city); 27 COMMIT; 28 END AddEmployee; 29 30 END EmployeePackage; 31 /

Calls procedure in a package

CREATE OR REPLACE PACKAGE employee_package AS 2 TYPE t_ref_cursor IS REF CURSOR; 3 FUNCTION get_employee_ref_cursor RETURN t_ref_cursor; 4 PROCEDURE update_salary (p_id IN VARCHAR2,p_factor IN NUMBER 5 ); 6 END employee_package; 7 / Package created. SQL> SQL> SQL> CREATE OR REPLACE PACKAGE BODY employee_package AS 2 FUNCTION get_employee_ref_cursor 3 RETURN t_ref_cursor IS 4 employee_ref_cursor t_ref_cursor; 5 BEGIN 6 -- get the REF CURSOR 7 OPEN employee_ref_cursor FOR 8 SELECT id, first_name, salary 9 FROM employee; 10 -- return the REF CURSOR 11 RETURN employee_ref_cursor; 12 END get_employee_ref_cursor; 13 14 PROCEDURE update_salary (p_id IN VARCHAR2,p_factor IN NUMBER 15 ) AS 16 v_employee_count INTEGER; 17 BEGIN 18 -- count the number of employees with the 19 -- supplied id (should be 1 if the employee exists) 20 SELECT COUNT(*) 21 INTO v_employee_count 22 FROM employee 23 WHERE id = p_id; 24 -- if the employee exists (v_employee_count = 1) then 25 -- update that employee's pass1 26 IF v_employee_count = 1 THEN 27 UPDATE employee 28 SET salary = salary * p_factor 29 WHERE id = p_id; 30 COMMIT; 31 END IF; 32 EXCEPTION 33 WHEN OTHERS THEN 34 -- perform a rollback when an exception occurs 35 ROLLBACK; 36 END update_salary; 37 END employee_package;

38

Package body created. SQL> SQL> SQL> CALL employee_package.update_salary(3, 1.25);

Calling a Cursor Declared in a Different Package


create or replace package pkg_Util is cursor c_emp is select * from employee; r_emp c_emp%ROWTYPE; end; / ge created. --Here is a different package that references the cursor create or replace package body pkg_aDifferentUtil is procedure p_printEmps is begin open pkg_Util.c_emp; loop fetch pkg_Util.c_emp into pkg_Util.r_emp; exit when pkg_Util.c_emp%NOTFOUND; DBMS_OUTPUT.put_line(pkg_Util.r_emp.first_Name); end loop; close pkg_Util.c_emp; end; end;

Creating Packages and call its functions


After the specification is created, you create the body of the package. The body of a package is a collection of schema objects that was declared in the specification. If you perform any initialization in the package body, it is executed once when the package is initially referenced. To reference the package's subprograms and objects, you must use dot notation.

The Syntax for Dot Notation


SQL> CREATE OR REPLACE PACKAGE inv_pck_spec as 2 FUNCTION inv_count(qty integer) RETURN integer; 3 PROCEDURE inv_adjust(qty integer); 4 END inv_pck_spec; 5 / Package created. SQL> SQL> CREATE OR REPLACE PACKAGE BODY inv_pck_spec is 2 FUNCTION inv_count(qty integer)RETURN integer is 3 new_qty integer; 4 BEGIN 5 new_qty:= qty*6; 6 INSERT into employee (id,salary) values ('01',new_qty); 7 RETURN(new_qty); 8 END inv_count; 9 10 PROCEDURE inv_adjust(qty integer) is 11 BEGIN 12 DELETE from employee WHERE salary<qty; 13 END; 14 BEGIN -- package initialization begins here 15 INSERT into employee (id, first_name)values('01', 'new'); 16 17 END inv_pck_spec; 18 / Package body created. SQL> SQL> --call inv_pck_spec.inv_count(2); SQL> SQL> call inv_pck_spec.inv_adjust(2000); Call completed. SQL> SQL> select * from employee; ID FIRST_NAME ION ---- ---------------02 Alison 03 James 04 Celia LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPT

---------- --------- --------- ---------- ---------- -------Mathews Smith Rice 21-MAR-76 21-FEB-86 12-DEC-78 15-MAR-90 24-OCT-82 21-APR-99 6661.78 Vancouver 6544.78 Vancouver 2344.78 Vancouver Tester Tester Manager

05 06 07 01

Robert Linda David new

Black Green Larry

15-JAN-84 08-AUG-98 30-JUL-87 04-JAN-96 31-DEC-90 12-FEB-98

2334.78 Vancouver 4322.78 New York 7897.78 New York

Tester Tester Manager

7 rows selected. ___________________________________________________________________________

System Privileges
A system privilege allows a user to perform certain actions within the database-such as executing DDL statements. Commonly Used System Privileges are System Privilege Allows You to CREATE SESSION Connect to a database. CREATE SEQUENCE Create a sequence. CREATE SYNONYM Create a synonym. CREATE TABLE Create a table. CREATE ANY TABLE Create a table in any schema. DROP TABLE Drop a table. DROP ANY TABLE Drop a table from any schema. CREATE PROCEDURE Create a stored procedure. EXECUTE ANY PROCEDURE Execute a procedure in any schema. CREATE USER Create a user. DROP USER Drop a user. CREATE VIEW Create a view.

Object privilege
An object privilege allows a user to perform certain actions on database objects, such as executing DML statements on tables. Commonly Used Object Privileges Object Privilege Allows a User to SELECT Perform a select INSERT Perform an insert

UPDATE DELETE EXECUTE

Perform an update Perform a delete Execute a stored procedure

Unlocking (or locking) accounts


alter user YOUR_USER account [unlock|lock];

Using the DECODE() Function


DECODE(value, search_value, result, default_value) compares value with search_value. If the values are equal, DECODE() returns result, otherwise default_value is returned. DECODE() allows you to perform if-then-else logic in SQL without having to use PL/SQL.

Pass multiple search and result parameters to DECODE()


> SELECT id, 2 DECODE(id, 1, 'A', 3 2, 'B', 4 3, 'C', 5 4, 'D', 6 'Default') 7 FROM employee;

Use decode as if statement and output 'high' or 'low'


select job, 2 , 3 4 from 5 where 6 order ename decode(greatest(sal,2500) ,2500,'cheap','expensive') as class emp bdate <date '1964-01-01' by decode(job,'Designer',1,'Designer',2,3);

DECODE in the GROUP BY clause


select 2 decode( sign( (salary - avg_sal ) ), 3 1, '> Average of ' || to_char(avg_sal, '99.99') , 4 0, '= Average of ' || to_char(avg_sal, '99.99'), 5 -1, '< Average of ' || to_char(avg_sal, '99.99') 6 count(*) 7 from emp, avg_sal 8 group by 9 decode( sign( (salary - avg_sal ) ), 10 1, '> Average of ' || to_char(avg_sal, '99.99') , 11 0, '= Average of ' || to_char(avg_sal, '99.99'), 12 -1, '< Average of ' || to_char(avg_sal, '99.99')

) sal_desc,

Demo range comparison with DECODE


select lastname, salary, 2 decode( sign( salary - avg_sal ), 3 1, '> Average of ' || to_char(avg_sal, '99.99') , 4 0, '= Average of ' || to_char(avg_sal, '99.99'), 5 -1, '< Average of ' || to_char(avg_sal, '99.99') 6 from emp, avg_sal

) sal_desc

The null may be made more explicit with a DECODE statement


SELECT count(*), DECODE(city,null,'Null',city) CITY 2 FROM employee 3 GROUP BY city; COUNT(*) ---------2 2 1 3 CITY ---------Null New York Toronto Vancouver

Use NVL() to convert date columns


SELECT id, first_name, last_name, NVL(start_date, '01-JAN2000') FROM employee;

NVL() converts a null to a known value.


SELECT id, NVL(first_name, 'Unknown first name') FROM employee; ID ---01 02 03 04 05 06 07 08 NVL(FIRST_NAME,'UN -----------------Jason Alison James Celia Robert Linda David Unknown first name

NVL2(x, value1, value2) returns value1 if x is not null.


SELECT id, NVL2(first_name, 'Known', 'Unknown') FROM employee;

Use nvl2 to deal with null salary


select ename, sal, comm 2 , nvl2(comm,12*sal+comm,12*sal) as yearsal 3 from emp 4 where ename like '%T%';

Use coalesce during the table join


SQL> SQL> 2 3 4 5 6 7 8 9 10

create table empno , ename , init , job , mgr , bdate , msal , comm , deptno

employees( NUMBER(4) VARCHAR2(8) VARCHAR2(5) VARCHAR2(8) NUMBER(4) DATE NUMBER(6,2) NUMBER(6,2) NUMBER(2) ) ;

Table created. SQL> SQL>

SQL> insert into employees values(1,'Jason', 5-12-18', 800 , NULL, 10); 1 row created. SQL> insert into employees values(2,'Jerry', 6-11-19', 1600, 300, 10); 1 row created. SQL> insert into employees values(3,'Jord', 7-10-21', 1700, 500, 20); 1 row created. SQL> insert into employees values(4,'Mary', 8-09-22', 1800, NULL, 20); 1 row created. SQL> insert into employees values(5,'Joe', 9-08-23', 1900, 1400, 30); 1 row created. SQL> insert into employees values(6,'Black', 0-07-24', 2000, NULL, 30); 1 row created. SQL> insert into employees values(7,'Red', 1-06-25', 2100, NULL, 40); 1 row created. SQL> insert into employees values(8,'White', 2-05-26', 2200, NULL, 40); 1 row created.

'N',

'TRAINER', 2,

date '196

'J',

'SALESREP',3,

date '196

'T' , 'SALESREP',4,

date '196

'J',

'MANAGER', 5,

date '196

'P',

'SALESREP',6,

date '196

'R',

'MANAGER', 7,

date '197

'A',

'MANAGER', 8,

date '197

'S',

'TRAINER', 9,

date '197

SQL> insert into employees values(9,'Yellow', 'C', 3-04-27', 2300, NULL, 20); 1 row created. SQL> insert into employees values(10,'Pink', 4-03-28', 2400, 0, 30); 1 row created. 'J',

'DIRECTOR',10,

date '197

'SALESREP',null,date '197

SQL> SQL> SQL> 2 3 4 5

create table ( course , begindate , trainer , location

course_schedule VARCHAR2(6) DATE NUMBER(4) VARCHAR2(20)) ;

Table created. SQL> SQL> SQL> insert into course_schedule values ('SQL',date '1999-0412',1,'VANCOUVER' ); 1 row created. SQL> insert into course_schedule values ('OAU',date '1999-0810',2,'CHICAGO'); 1 row created. SQL> insert into course_schedule values ('SQL',date '1999-1004',3,'SEATTLE'); 1 row created. SQL> insert into course_schedule values ('SQL',date '1999-1213',4,'DALLAS' ); 1 row created. SQL> insert into course_schedule values ('JAV',date '1999-1213',5,'SEATTLE'); 1 row created. SQL> insert into course_schedule values ('XML',date '2000-0203',6,'VANCOUVER' ); 1 row created. SQL> insert into course_schedule values ('JAV',date '2000-0201',7,'DALLAS' ); 1 row created. SQL> insert into course_schedule values ('PLS',date '2000-09-

11',8,'VANCOUVER' ); 1 row created. SQL> insert into course_schedule values ('XML',date '2000-0918',NULL,'SEATTLE'); 1 row created. SQL> insert into course_schedule values ('OAU',date '2000-0927',9,'DALLAS' ); 1 row created. SQL> insert into course_schedule values ('ERM',date '2001-0115',10, NULL ); 1 row created. SQL> insert into course_schedule values ('PRO',date '2001-0219',NULL,'VANCOUVER' ); 1 row created. SQL> insert into course_schedule values ('RSD',date '2001-0224',8,'CHICAGO'); 1 row created. SQL> SQL> SQL> 2 3 4 5

create table courses ( code VARCHAR2(6) , description VARCHAR2(30) , category CHAR(3) , duration NUMBER(2)) ;

Table created. SQL> SQL> SQL> insert into courses values('SQL','SQL course', 1 row created. SQL> insert into courses values('OAU','Oracle course', 'GEN',1); 1 row created.

'GEN',4);

SQL> insert into courses values('JAV','Java course', 1 row created.

'BLD',4);

SQL> insert into courses values('PLS','PL/SQL course', 'BLD',1); 1 row created. SQL> insert into courses values('XML','XML course', 1 row created. SQL> insert into courses values('ERM','ERM course', 1 row created. SQL> insert into courses values('PMT','UML course', 1 row created. SQL> insert into courses values('RSD','C# course', 1 row created. SQL> insert into courses values('PRO','C++ course', 1 row created. SQL> insert into courses values('GEN','GWT course', 1 row created. 'DSG',4); 'DSG',5); 'DSG',2); 'DSG',1); 'DSG',3); 'BLD',2);

SQL> 2 3 4 5 6 7 8 9 10 11 12

select , , ,

from , , where and

DISTINCT c.code o.begindate c.duration case when o.trainer is not null then e.ename else null end as trainer employees e courses c course_schedule o coalesce(o.trainer,-1) in (e.empno,-1) o.course = c.code;

CODE BEGINDATE DURATION TRAINER ------ --------- ---------- -------JAV 13-DEC-99 4 Joe

OAU JAV RSD OAU PRO SQL ERM XML PLS SQL SQL XML

27-SEP-00 01-FEB-00 24-FEB-01 10-AUG-99 19-FEB-01 04-OCT-99 15-JAN-01 18-SEP-00 11-SEP-00 13-DEC-99 12-APR-99 03-FEB-00

1 4 2 1 5 4 3 2 1 4 4 2

Yellow Red White Jerry Jord Pink White Mary Jason Black

13 rows selected.

Triggers

A trigger is a procedure that is run automatically by the database when a specified SQL DML INSERT, UPDATE, or DELETE statement is run against a table. Triggers are useful for doing things like advanced auditing of changes made to column values in a table. When a Trigger Runs 1. A trigger can fire before or after the SQL statement runs. 2. A trigger can may be run once for every row affected. Such a trigger is known as a rowlevel trigger. 3. A trigger can may be run for all the rows. Such trigger is known as a statement-level trigger. 4. A row-level trigger has access to the old and new column values when the trigger fires as a result of an UPDATE statement on that column. 5. The firing of a trigger may also be limited using a trigger condition. Different events may fire a trigger, but these events are always divided into three groups: 1. DML triggers, 2. INSTEAD OF triggers, and 3. system event triggers.

A row-level trigger
FOR EACH ROW clause identifies this as a row-level trigger

SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14

CREATE OR REPLACE TRIGGER before_employee_salary_update BEFORE UPDATE OF salary ON employee FOR EACH ROW WHEN (new.salary < old.salary * 0.75) BEGIN dbms_output.put_line('id = ' || :old.id); dbms_output.put_line('Old salary = ' || :old.salary); dbms_output.put_line('New salary = ' || :new.salary); dbms_output.put_line('The salary reduction is more than 25%'); INSERT INTO Myaudit ( id, old_value, new_value ) VALUES ( :old.id, :old.salary, :new.salary

15 16 17

); END before_employee_salary_update; /

Trigger created. SQL> SQL> update employee set salary = 0; 8 rows updated.

An after statement level trigger and an after row level trigger


SQL> CREATE TABLE to_table 2 (col1 NUMBER); Table created. SQL> SQL> SQL> SQL> 2 3 4 5 6

CREATE OR REPLACE TRIGGER statement_trigger AFTER INSERT ON to_table BEGIN DBMS_OUTPUT.PUT_LINE('After Insert Statement Level'); END; /

Trigger created. SQL> SQL> 2 3 4 5 6 7

CREATE OR REPLACE TRIGGER row_trigger AFTER INSERT ON to_table FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('After Insert Row Level'); END; /

Trigger created.

BEFORE INSERT OR UPDATE OF id

SQL> CREATE OR REPLACE TRIGGER CheckID 2 BEFORE INSERT OR UPDATE OF id 3 ON employee 4 FOR EACH ROW 5 DECLARE 6 v_ID NUMBER(5); 7 BEGIN 8 SELECT id 9 into v_ID 10 FROM employee 11 where id = :new.id; 12 EXCEPTION 13 WHEN NO_DATA_FOUND THEN 14 RAISE_APPLICATION_ERROR(20000, :new.id || ' is not a ' ||' valid ID'); 15 END CheckID; 16 / Trigger created. SQL> SQL> SQL> update employee set salary = 1000; 8 rows updated. SQL> SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) 2 values('99','James', 'Cat', to_date('19960917','YYY YMMDD'), to_date('20020415','YYYYMMDD'), 1232.78,'Vancouver', 'Tester') 3 / insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description) * ERROR at line 1: ORA-20000: 99 is not a valid ID ORA-06512: at "JAVA2S.CHECKID", line 10 ORA-04088: error during execution of trigger 'JAVA2S.CHECKID'

Convert character values to upper case

SQL> 2 3 4 5 6 7 8 9 10

create trigger employee_name before update or insert on employee for each row begin /* convert character values to upper case */ :new.lastname := upper( :new.lastname ); :new.firstname := upper( :new.firstname ); dbms_output.put_line('trigger fired'); end; /

Trigger created. SQL> SQL> SQL> 2 3 4

insert into employee (empl_no, firstname, lastname) values (3423, 'dave', 'anderson');

1 row created. SQL> SQL> select firstname, lastname 2 from employee 3 where empl_no = 3423; FIRSTNAME LASTNAME --------------- -------------------DAVE ANDERSON

Implementing Autonumbering Functionality


SQL> CREATE SEQUENCE idSeq; Sequence created. SQL> SQL> CREATE TABLE myTable (Name VARCHAR(50) PRIMARY KEY NOT NULL, 2 PhoneNo VARCHAR(15)); Table created. SQL> SQL> CREATE TABLE myTableAudit 2 (id INT PRIMARY KEY NOT NULL, 3 Operation VARCHAR(10), 4 RecordedOn DATE DEFAULT SysDate, 5 OldName VARCHAR(50),

6 7 8

NewName VARCHAR(50), OldPhone VARCHAR(15), NewPhone VARCHAR(15));

Table created. SQL> SQL> 2 3 4 5 6 7 8

CREATE OR REPLACE TRIGGER idAutonumberTrigger BEFORE INSERT ON myTableAudit FOR EACH ROW BEGIN SELECT idSeq.NEXTVAL INTO :NEW.id FROM DUAL; END; /

Trigger created.

Fire a trigger before an update of the table


SQL> create table myaudit( 2 id VARCHAR2(4 BYTE) NOT NULL, 3 old_value VARCHAR2(40 BYTE), 4 new_value VARCHAR2(40 BYTE) 5 ); SQL> SQL> 2 3 4 5 6 7 8 9 10 11 -- create demo table create table Employee( ID VARCHAR2(4 BYTE) First_Name VARCHAR2(10 BYTE), Last_Name VARCHAR2(10 BYTE), Start_Date DATE, End_Date DATE, Salary Number(8,2), City VARCHAR2(10 BYTE), Description VARCHAR2(15 BYTE) ) /

NOT NULL,

See Code Of Row Level Trigger

Check and change new value in a before-insert trigger


SQL> SQL> CREATE TABLE incremented_values 2 (value_inserted NUMBER, 3 value_incremented NUMBER); Table created.

SQL> SQL> 2 3 4 5 6 7

CREATE OR REPLACE TRIGGER increment_by_one BEFORE INSERT ON incremented_values FOR EACH ROW BEGIN :new.value_incremented := :new.value_incremented + 1; END; /

Trigger created. SQL> SQL> 2 3 4 5 6 7 8 9 CREATE OR REPLACE TRIGGER increment_by_two BEFORE INSERT ON incremented_values FOR EACH ROW BEGIN IF :new.value_incremented > 1 THEN :new.value_incremented := :new.value_incremented + 2; END IF; END; /

Trigger created. SQL> SQL> INSERT INTO incremented_values VALUES(1,1); 1 row created. SQL> SQL> SELECT * FROM incremented_values; VALUE_INSERTED VALUE_INCREMENTED -------------- ----------------1 2 SQL> SQL> SQL> DROP TABLE incremented_values; Table dropped. SQL>

Trigger that logs actions for inserting actions

SQL> create table employee 2 ( 3 emp_no 4 ,lastname 5 ,firstname 6 ,midinit 7 ,street 8 ,city 9 ,state 10 ,zip 11 ,zip_4 12 ,area_code 13 ,phone 14 ,salary 15 ,birthdate 16 ,hiredate 17 ,title 18 ,dept_no 19 ,mgr 20 ,region 21 ,division 22 ,total_sales 23 ); Table created.

integer primary key varchar2(20) not null varchar2(15) not null varchar2(1) varchar2(30) varchar2(20) varchar2(2) varchar2(5) varchar2(4) varchar2(3) varchar2(8) number(5,2) date date varchar2(20) integer integer number number number

SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dep t_no, mgr, region, division, total_sales) 2 values (2,'Anderson','Lucy','J','33 Ave','New York','NY','43552','6633', '212','234-4444',7.75,'21-mar-1951','1-feb1994','Sales Manager',2,1,100,10,40000); 1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate,title, dept _no, mgr, region, division, total_sales) 2 values (3,'Somers','Ingrid','E','12 Ave','New York','NY','76822','8763', '212','867-6893',7.75,'14-feb-1963','15-mar1995','Sales Clerk',2,2,100,10,10000); 1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip,zip_4, area_code, phone, salary, birthdate, hiredate, title, dept _no, mgr, region, division, total_sales) 2 values (4,'Washington','Georgia','J','13th Street','New York','NY','4312

2','4333','212','340-4365',11.50,'2-jul-1963','21-apr1994','Designer',1,1,100,10,40000); 1 row created. SQL> SQL> insert into employee(emp_no, lastname, firstname, midinit, street, city, state, zip, zip_4, area_code, phone, salary, birthdate, hiredate, title, dep t_no, mgr, region, division, total_sales) 2 values (5,'Doright','Dudley','J','56 Langer Street','Staten Island','NY' ,'23332','4983','718','777-4365',21.65,'15-may-1958','2-aug1994','Designer',1,1,100,10,40000); 1 row created. SQL> CREATE TABLE logit( event Table created. SQL> SQL> SQL> create or replace trigger tr_trans_log 2 BEFORE INSERT OR UPDATE OR DELETE ON employee 3 DECLARE 4 v_msg varchar2(200) ; 5 PRAGMA AUTONOMOUS_TRANSACTION; 6 BEGIN 7 IF inserting THEN 8 v_msg := ' Insert into employee @ ' || to_char(sysdate, 'mm/dd/yyyy hh:mi') || ' by ' || user ; 9 ELSIF updating THEN 10 v_msg := ' Update of employee @ ' || to_char(sysdate, 'mm/dd/yyyy hh :mi') || ' by ' || user ; 11 ELSIF deleting THEN 12 v_msg := ' Delete of employee @ ' || to_char(sysdate, 'mm/dd/yyyy hh :mi') || ' by ' || user ; 13 END IF; 14 INSERT INTO logit VALUES(v_msg); 15 COMMIT; 16 END; 17 / Trigger created. VARCHAR2(400) );

Is updating a certain column


SQL> CREATE TABLE account_transaction 2 (transaction_id NUMBER NOT NULL PRIMARY KEY, 3 account_id NUMBER NOT NULL,

4 5 6

transaction_type VARCHAR2(3) NOT NULL, transaction_amount NUMBER NOT NULL, comments VARCHAR2(30));

Table created. SQL> SQL> SQL> 2 3 4 5 6 7 8 9

CREATE OR REPLACE TRIGGER validate_update BEFORE UPDATE ON account_transaction FOR EACH ROW BEGIN IF UPDATING('ACCOUNT_ID') THEN DBMS_OUTPUT.put_line ('ERROR'); END IF; END; /

Trigger created. SQL> show error

Character String Functions

INSTR: INSTR(x, find_string [, start] [, occurrence]) searchs for find_string in x

INSTR() returns the position at which find_string occurs. The 'start position' is optional. The 'start position' specifies the position to start the search in x. The 'Occurrence' is also optional. The 'Occurrence' indicates which occurrence of find_string should be returned. The following example selects the first_name column and displays the position where the string J occurs in the name column.
SQL> SELECT first_name, INSTR(first_name, 'J') FROM employee; FIRST_NAME INSTR(FIRST_NAME,'J') ---------- --------------------Jason 1 Alison 0 James 1 Celia 0 Robert 0 Linda 0 David 0 James 1

If search pattern is not in the string, the INSTR function returns 0


SQL> SELECT INSTR('This is a test','abc',1,2)FROM dual 2

Using SUBSTR and INSTR together


SQL> SELECT SUBSTR('H, J E', INSTR('H, J E',', ')+2) FROM dual; SUB --J E

If the INSTR pattern is not found, then the entire string would be returned
SQL> SELECT SUBSTR('H, J E', INSTR('H,J E','z')) FROM dual; SUBSTR -----H, J E

unistr('\0300')
SQL> select unistr('\0300') from dual;

substr(,) and substr(,,)


SQL> 2 3 4 5 6 create table departments ( deptno NUMBER(2) , dname VARCHAR2(10) , location VARCHAR2(20) , mgr NUMBER(4) ) ; 2);

Table created. SQL> insert into departments values (10,'ACCOUNTING','NEW YORK' , 1 row created. SQL> insert into departments values (20,'TRAINING', SQL> 2 3 4 select , , from dname substr(dname,4) substr(dname,4,3) departments; SUBSTR1 ------OUNTING INING ES SUBSTR2 ------OUN INI ES as substr1 as substr2 'VANCOUVER',

3);

DNAME ---------ACCOUNTING TRAINING SALES HR

substr birthday
SQL> 2 3 4 5 6 7 8 9 10 create table empno , ename , init , job , mgr , bdate , msal , comm , deptno employees( NUMBER(4) VARCHAR2(8) VARCHAR2(5) VARCHAR2(8) NUMBER(4) DATE NUMBER(6,2) NUMBER(6,2) NUMBER(2) ) ;

Table created. SQL> insert into employees values(1,'Jason', 5-12-18', 800 , NULL, 10); 1 row created. SQL> insert into employees values(2,'Jerry', 6-11-19', 1600, 300, 10); 1 row created. SQL> insert into employees values(3,'Jord', 7-10-21', 1700, 500, 20); 'T' , 'SALESREP',4, date '196 'J', 'SALESREP',3, date '196 'N', 'TRAINER', 2, date '196

1 row created. QL> select ename, substr(bdate,8)+16 2 from employees; ENAME SUBSTR(BDATE,8)+16 -------- -----------------Jason 81 Jerry 82 Jord 83

Padding based on value length


SQL> 2 3 4 5 6 7 8 9 10 11 create table emp ( empno NUMBER(4) , ename VARCHAR2(8) , init VARCHAR2(5) , job VARCHAR2(8) , mgr NUMBER(4) , bdate DATE , sal NUMBER(6,2) , comm NUMBER(6,2) , deptno NUMBER(2) ) ; constraint E_PK primary key

default 10

Table created. SQL> insert into emp values(1,'Tom','N', 17', 800 , NULL, 20); 1 row created. SQL> insert into emp values(2,'Jack','JAM', 'Tester',6,date '1961-0220', 1600, 300, 30); 1 row created. SQL> insert into emp values(3,'Wil','TF' , 22', 1250, 500, 30); 1 row created. SQL> select lpad(sal,4)||' '|| 2 rpad('o',sal/100,'o') as histogram 3 from emp 4 where deptno = 30; HISTOGRAM ------------------------------------------------------------------------------1600 oooooooooooooooo 1250 oooooooooooo 1250 oooooooooooo 2850 oooooooooooooooooooooooooooo 'Tester',6,date '1962-02'Coder', 13,date '1965-12-

1500 ooooooooooooooo 800 oooooooo 6 rows selected.

left padding the name of department


SQL> 2 3 4 5 6 create table departments ( deptno NUMBER(2) , dname VARCHAR2(10) , location VARCHAR2(20) , mgr NUMBER(4) ) ; 2);

SQL> insert into departments values (10,'ACCOUNTING','NEW YORK' , 1 row created. SQL> insert into departments values (20,'TRAINING', 1 row created. SQL> insert into departments values (30,'SALES', 1 row created. SQL> select dname 2 , lpad(dname,9,'>') 3 from departments; DNAME ---------ACCOUNTING TRAINING SALES HR LPAD(DNAM --------ACCOUNTIN >TRAINING >>>>SALES >>>>>>>HR 'CHICAGO', 'VANCOUVER',

3);

4);

Rtrim removes a set of characters from the right of a string


SQL> SELECT RTRIM('Computers', 's') FROM dual; RTRIM('C -------Computer

Call RPAD function in PL/SQL


SQL> 2 3 4 5 6 CREATE OR REPLACE FUNCTION rulerstr (len IN INTEGER) RETURN VARCHAR2 IS digits CHAR(10) := '1234567890'; BEGIN RETURN RPAD (digits, len, digits); END;

Function created. SQL> SQL> select rulerstr(3) from dual; RULERSTR(3) --------------------------------------------------------------------------------------------------123

Use both lpad() and rpad() to create a string


SQL> 2 3 4 5 6 7 8 9 10 create table empno , ename , init , job , mgr , bdate , msal , comm , deptno employees( NUMBER(4) VARCHAR2(8) VARCHAR2(5) VARCHAR2(8) NUMBER(4) DATE NUMBER(6,2) NUMBER(6,2) NUMBER(2) ) ;

Table created. SQL> insert into employees values(1,'Jason', 5-12-18', 800 , NULL, 10); 1 row created. SQL> insert into employees values(2,'Jerry', 6-11-19', 1600, 300, 10); 1 row created. SQL> insert into employees values(3,'Jord', 7-10-21', 1700, 500, 20); 1 row created. SQL> insert into employees values(4,'Mary', 8-09-22', 1800, NULL, 20); 1 row created. 'J', 'MANAGER', 5, date '196 'T' , 'SALESREP',4, date '196 'J', 'SALESREP',3, date '196 'N', 'TRAINER', 2, date '196

SQL> select lpad(msal,4)||' '|| 2 rpad('o',msal/100,'o') as histogram 3 from employees; HISTOGRAM --------------------------------------------------------------------------------------------------800 oooooooo 1600 oooooooooooooooo 1700 ooooooooooooooooo 1800 oooooooooooooooooo 1900 ooooooooooooooooooo 2000 oooooooooooooooooooo 2100 ooooooooooooooooooooo 2200 oooooooooooooooooooooo 2300 ooooooooooooooooooooooo 2400 oooooooooooooooooooooooo 10 rows selected.

Simplifying Joins with the USING Keyword

SQL/92 allows you to further simplify the join condition through the USING clause, but only when your query has the following limitations: Your query must use an equijoin. The columns in your equijoin have the same name. Don't use a table name or alias when referencing columns used in a USING clause.
SQL> SELECT e.ename, j.jobtitle FROM employee e INNER JOIN job j USING (empno ); ENAME --------------Jason John Joe JOBTITLE -------------------Tester Accountant Developer

Perform outer joins in combination with self joins, employee and job tables
SQL> -- create demo table SQL> create table Employee( 2 EMPNO NUMBER(3), 3 ENAME VARCHAR2(15 BYTE),

4 5 6 7 8 9 10

HIREDATE ORIG_SALARY CURR_SALARY REGION MANAGER_ID ) /

DATE, NUMBER(6), NUMBER(6), VARCHAR2(1 BYTE), NUMBER(3)

Table created. SQL> SQL> create table job ( 2 EMPNO NUMBER(3), 3 jobtitle VARCHAR2(20 BYTE) 4 ) 5 / Table created. SQL> SQL> insert into job (EMPNO, Jobtitle) values (1,'Tester'); 1 row created. SQL> insert into job (EMPNO, Jobtitle) values (2,'Accountant'); 1 row created. SQL> insert into job (EMPNO, Jobtitle) values (3,'Developer'); 1 row created.

SQL> insert into Employee(EMPNO, EName, HIREDATE, OR IG_SALARY, CURR_SALARY, REGION, MANAGER_ID) 2 values (1, 'Jason', to_date('19960725','YYYYMMDD'), 12 34, 8767, 'E', 2) 3 / 1 row created. SQL> insert into Employee(EMPNO, EName, HIREDATE, OR IG_SALARY, CURR_SALARY, REGION, MANAGER_ID) 2 values (2, 'John', to_date('19970715','YYYYMMDD'), 23 41, 3456, 'W', 3) 3 / 1 row created.

SQL> insert into Employee(EMPNO, EName, HIREDATE, OR IG_SALARY, CURR_SALARY, REGION, MANAGER_ID) 2 values (3, 'Joe', to_date('19860125','YYYYMMDD'), 43 21, 5654, 'E', 3) 3 /

SQL> SELECT w.ename || ' works for ' || 2 NVL(m.ename, 'the shareholders') 3 FROM employee w, employee m 4 WHERE w.manager_id = m.empno; W.ENAME||'WORKSFOR'||NVL(M.ENAME,'THESHARE -----------------------------------------Jason works for John Joe works for Joe John works for Joe

Right outer join with group by


SQL> select deptno, count(*) 2 from employees e 3 right outer join 4 departments d 5 using (deptno) 6 group by deptno; DEPTNO COUNT(*) ---------- ---------30 3 20 3 40 2 10 2

Example outer join with (+)


SQL> SELECT a.dname, b.empno, b.ename 2 FROM dept a, emp b 3 WHERE a.deptno=b.deptno(+) 4 ORDER BY deptno;

LEFT OUTER JOIN vs RIGHT OUTER JOIN


SQL> SELECT p.pro_name, ph.time_log_date, ph.hours_logged 2 FROM project p LEFT OUTER JOIN server_usage ph 3 ON p.pro_id = ph.pro_id;

LEFT OUTER JOIN tableName ON joined columns


SQL> CREATE TABLE emps ( 2 emp varchar(30) 3 ,title varchar(30) 4 ); Table created. SQL> SQL> INSERT INTO emps VALUES ('Tom','Programmer'); 1 row created. SQL> INSERT INTO emps VALUES ('Jack','Tester'); 1 row created. SQL> INSERT INTO emps VALUES ('Mary','Technician'); 1 row created. SQL> SQL> CREATE TABLE JobLevel ( 2 title varchar(30) 3 ,rank varchar(30) 4 ); Table created. SQL> SQL> INSERT INTO JobLevel VALUES ('Programmer','Level1'); 1 row created. SQL> INSERT INTO JobLevel VALUES ('Tester','Level2'); 1 row created. SQL> INSERT INTO JobLevel VALUES ('Technician','Level3'); 1 row created. SQL> SQL> CREATE TABLE salary ( 2 rank varchar(30) 3 ,payment DECIMAL(10,2) 4 ); Table created. SQL> SQL> INSERT INTO salary VALUES ('Level1',2000.00); 1 row created.

SQL> INSERT INTO salary VALUES ('Level2',3000.00); 1 row created. SQL> INSERT INTO salary VALUES ('Level3',5000.00); 1 row created. SQL> INSERT INTO salary VALUES ('Level4',6000.00); 1 row created. SQL> SQL> select * from emps;

EMP -----------------------------TITLE -----------------------------Tom Programmer Jack Tester Mary Technician 3 rows selected. SQL> select * from JobLevel;

TITLE -----------------------------RANK -----------------------------Programmer Level1 Tester Level2 Technician Level3 3 rows selected. SQL> select * from salary;

RANK -----------------------------Level1 Level2 Level3 Level4 4 rows selected.

PAYMENT ---------2000 3000 5000 6000

SQL> SQL> SQL> SELECT salary.rank 2 FROM salary LEFT OUTER JOIN JobLevel ON (salary.rank = JobLevel.rank) 3 WHERE JobLevel.rank IS NULL;

RANK -----------------------------Level4

Using Inner Joins


SQL> CREATE TABLE Room ( 2 RoomID INT NOT NULL PRIMARY KEY, 3 Comments VARCHAR(50), 4 Capacity INT); Table created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (1,'Main hall',500); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (2,'Science Departmen t',200); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (3,'Science Room 1',1 00); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (4,'Languages Block', 300); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (5,'Languages Room 1' ,75); 1 row created. SQL> SQL> SQL>

SQL> CREATE TABLE Class ( 2 ClassID INT NOT NULL PRIMARY KEY, 3 CourseID INT NOT NULL, 4 InstructorID INT NOT NULL, 5 RoomID INT NOT NULL, 6 Time VARCHAR(50)); Table created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (1, 1,1,6,'Mon 09:00-11:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (2, 2,1,5,'Mon 11:00-12:00, Thu 09:00-11:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (3, 3,2,3,'Mon 14:00-16:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (4, 4,3,2,'Tue 10:00-12:00, Thu 14:00-15:00'); 1 row created. SQL> SQL> SELECT Room.RoomID, Class.Time 2 FROM Room 3 INNER JOIN Class 4 ON Room.RoomID = Class.RoomID 5 ORDER BY Room.RoomID; ROOMID ---------2 3 5 TIME -------------------------------------------------Tue 10:00-12:00, Thu 14:00-15:00 Mon 14:00-16:00 Mon 11:00-12:00, Thu 09:00-11:00

3 rows selected.

Inner and Outer Joins


SQL> CREATE TABLE Room ( 2 RoomID INT NOT NULL PRIMARY KEY, 3 Comments VARCHAR(50), 4 Capacity INT); Table created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (1,'Main hall',500); 1 row created.

SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (2,'Science Departmen t',200); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (3,'Science Room 1',1 00); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (4,'Languages Block', 300); 1 row created. SQL> INSERT INTO Room (RoomID,Comments,Capacity) VALUES (5,'Languages Room 1' ,75); 1 row created. SQL> SQL> SQL> SQL> CREATE TABLE Class ( 2 ClassID INT NOT NULL PRIMARY KEY, 3 CourseID INT NOT NULL, 4 InstructorID INT NOT NULL, 5 RoomID INT NOT NULL, 6 Time VARCHAR(50)); Table created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (1, 1,1,6,'Mon 09:00-11:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (2, 2,1,5,'Mon 11:00-12:00, Thu 09:00-11:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (3, 3,2,3,'Mon 14:00-16:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (4, 4,3,2,'Tue 10:00-12:00, Thu 14:00-15:00'); 1 row created. SQL> INSERT INTO Class (ClassID,CourseID,InstructorID,RoomID,Time) VALUES (5, 5,2,9,'Tue 14:00-16:00');

1 row created. SQL> SQL> SQL> SQL> 2 3 4 5 6 7

SELECT Class.ClassID, Class.CourseID, Class.Time, Room.Comments AS RoomName FROM Class INNER JOIN Room ON Class.RoomID = Room.RoomID ORDER BY ClassID;

CLASSID COURSEID TIME ---------- ---------- -------------------------------------------------ROOMNAME -------------------------------------------------2 2 Mon 11:00-12:00, Thu 09:00-11:00 Languages Room 1 3 Science Room 1 4 Science Department 3 rows selected. 3 Mon 14:00-16:00 4 Tue 10:00-12:00, Thu 14:00-15:00

Self join a table


SQL> 2 3 4 5 6 7 8 select e.ename as employee , m.ename as manager from employees m JOIN employees e ON e.mgr = m.empno where e.bdate > date '1965-01-01' order by employee; MANAGER -------Red Jerry Jord Black Mary Joe White Yellow Pink

EMPLOYEE -------Black Jason Jerry Joe Jord Mary Red White Yellow

9 rows selected.

You might also like