Using SQL in PL/SQL ITEC 224 Database Programming.

22
Using SQL in PL/SQL Using SQL in PL/SQL ITEC ITEC 224 224 Database Database Programming Programming

Transcript of Using SQL in PL/SQL ITEC 224 Database Programming.

Using SQL in PL/SQLUsing SQL in PL/SQL

ITEC ITEC 224224 Database Database ProgrammingProgramming

Cursors used for SQL Cursors used for SQL statementsstatements

Whenever an SQL command is executed in Whenever an SQL command is executed in a PL/SQL block, a PL/SQL block, Oracle assigns a private Oracle assigns a private work area for that statement. work area for that statement.

This work area contains information about This work area contains information about the SQL statement and the set of data the SQL statement and the set of data returned or affected by that statement. returned or affected by that statement.

There are two types of SQL cursor: There are two types of SQL cursor: implicit cursor. The implicit cursor is used by implicit cursor. The implicit cursor is used by

Oracle server to test and parse the SQL Oracle server to test and parse the SQL statementsstatements

explicit cursor explicit cursor : : the explicit cursors are the explicit cursors are declared by the programmers.declared by the programmers.

Attributes of Implicit CursorsAttributes of Implicit Cursors

Using the implicit cursor, we can test the Using the implicit cursor, we can test the outcome of SQL statements in PL/SQLoutcome of SQL statements in PL/SQL blocks blocks using the following attributes:using the following attributes:

SQL%ROWCOUNTSQL%ROWCOUNT: : return the number of rows affected; return the number of rows affected; SQL%FOUNDSQL%FOUND : : BOOLEAN attribute indicating whether BOOLEAN attribute indicating whether

the recent SQL statement matches to any row; the recent SQL statement matches to any row; SQL%NOTFOUNDSQL%NOTFOUND: : BOOLEAN attribute indicating BOOLEAN attribute indicating

whether the recent SQL statement does not match to whether the recent SQL statement does not match to any row; any row;

SQL%ISOPENSQL%ISOPEN: : a BOOLEAN attribute and always a BOOLEAN attribute and always evaluated as FALSE immediately after the SQL evaluated as FALSE immediately after the SQL statement is executed. statement is executed.

DML CommandsDML Commands

DML commands (insert/delete/update) DML commands (insert/delete/update) are used with no change inside any are used with no change inside any PL/SQL blockPL/SQL block Insert/delete/update commands modify Insert/delete/update commands modify

the contents of the table and they do not the contents of the table and they do not really “return” any data.really “return” any data.

It is possible to check the status of the It is possible to check the status of the statement using the implicit cursor statement using the implicit cursor attributesattributes

DML commandsDML commandsTask: Insert a new row into the following table:

Author(AuthorId, Lname, FName)

BEGIN

INSERT INTO Author(AuthorId, Lname, FName)

VALUES(‘5266’, ‘Armanfar’, ‘Hamed’);

END;

DML commandsDML commandsTask: Append “old_” to the beginning of all last names

BEGIN

UPDATE Author

SET lname = ‘old_’ || lname;

DBMS_OUTPUT.PUT_LINE(SQL%rowcount || ’ names modified’);

END;

Use of DML commandsUse of DML commands

You can use as many DML You can use as many DML commands as you need in one blockcommands as you need in one block

You should plan the DML commands You should plan the DML commands and use the DCL commands commit and use the DCL commands commit or rollback in the appropriate places or rollback in the appropriate places in your PL/SQL block.in your PL/SQL block.

Use of DML and DCL commands Use of DML and DCL commands togethertogether

Employees(employee_id, last_name, salary, department_id)Raises(department_id, number_modified)

DECLAREv_dept_id number(4) :=&did;

v_count number;BEGIN

UPDATE employeesSET salary = salary * 1.1WHERE department_id = v_dept_id;

IF SQL%FOUND THEN v_count := SQL%ROWCOUNT;

INSERT INTO raisesVALUES(v_dept_id, v_count);COMMIT;

ELSEROLLBACK;

END IF;END;

Task:

•Increase salary of all employees in a given department by 10%.

•Read the department id from the keyboard.

•If any rows were updated, insert a new row into the raises table containing the department id of the specified department and the number of rows modified and commit.

•Otherwise undo the update.

•Use the following tables:

Employees.department_id%TYPE

Anchored declaration may be used here. v_dept_id has the same data type as the

department_id column of the employees table

SQL%ROWCOUNT>0

Alternatively, rowcount may be used as part of the conditionIf the update command did not find any rows , t

means rowcount=0.

Use of SELECT in PL/SQL blocksUse of SELECT in PL/SQL blocks

Select statement returns a set of results and Select statement returns a set of results and these results are normally displayed on these results are normally displayed on screenscreen

When used inside a PL/SQL block, the results When used inside a PL/SQL block, the results returned by the SELECT statement must be returned by the SELECT statement must be saved into variables therefore SELECT INTO saved into variables therefore SELECT INTO statement is usedstatement is used

Syntax of Select Into :Syntax of Select Into :SELECT <column list> INTO <variable list>FROM <table list>WHERE <conditions for choosing rows>GROUP BY <columns | expressions to form group>HAVING <conditions for choosing groups>ORDER BY <columns | expressions to order the results>

Example Select IntoExample Select IntoTask: Print on screen the average salary of all employees

DECLAREv_avg_salary employees.salary%TYPE;

BEGINSELECT avg(salary) INTO v_avg_salaryFROM employees;

DBMS_OUTPUT.PUT_LINE( ‘The average salary of all employees is ’ ||v_avg_salary);

END;

The average salary of all employees is 6461.68

Employees(employee_id, last_name, salary, department_id)

Example Select IntoExample Select IntoTask: Print on screen names of employees in the employees table.

DECLAREv_name employees.last_name%TYPE;

BEGINSELECT last_name INTO v_nameFROM employees;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’ ||v_name);END;

DECLARE*ERROR at line 1:ORA-01422: exact fetch returns more than requested number of rowsORA-06512: at line 4

If select into returns more than one row, an exception (error) is raised and the program crashes.

Employees(employee_id, last_name, salary, department_id)

Example Select IntoExample Select IntoTask: Print on screen name of employees in department 99

DECLAREv_name employees.last_name%TYPE;

BEGINSELECT last_name INTO v_nameFROM employees;WHERE department_id = 99;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’||v_name);END;

DECLARE*ERROR at line 1:ORA-01403: no data foundORA-06512: at line 4

If select into returns no rows, an exception (error) is raised and the program crashes.

Handling Select Into Handling Select Into exceptionsexceptions

NO_DATA_FOUNDNO_DATA_FOUND : : A SELECT INTO statement returns A SELECT INTO statement returns no rows, or your program references a deleted no rows, or your program references a deleted element in a nested table or an uninitialized element element in a nested table or an uninitialized element in an index-by table. in an index-by table.

TOO_MANY_ROWSTOO_MANY_ROWS : : A SELECT INTO statement A SELECT INTO statement returns more than one row.VALUE_ERRORAn returns more than one row.VALUE_ERRORAn arithmetic, conversion, truncation, or size-constraint arithmetic, conversion, truncation, or size-constraint error occurs. For example, when your program error occurs. For example, when your program selects a column value into a character variable, if selects a column value into a character variable, if the value is longer than the declared length of the the value is longer than the declared length of the variable, PL/SQL aborts the assignment and raises variable, PL/SQL aborts the assignment and raises

VALUE_ERROR. In procedural statements, VALUE_ERROR. In procedural statements, VALUE_ERROR is raised if the conversion of a VALUE_ERROR is raised if the conversion of a character string into a number fails. character string into a number fails.

DML related Exceptions DML related Exceptions

Oracle Exception Oracle Exception NameName

Oracle Oracle Error Error NumberNumber

DescriptionDescription

NO_DATA_FOUND NO_DATA_FOUND ORA-01403 ORA-01403 SELECT INTO statement returns no SELECT INTO statement returns no rowsrows

TOO_MANY_ROWS TOO_MANY_ROWS ORA-01422 ORA-01422 SELECT INTO statement returns SELECT INTO statement returns more than one row.more than one row.

VALUE_ERROR VALUE_ERROR ORA-06502 ORA-06502 An arithmetic, conversion, An arithmetic, conversion, truncation, or size-constraint error truncation, or size-constraint error occursoccurs

ZERO_DIVIDE ZERO_DIVIDE ORA-01476 ORA-01476 Attempt to Attempt to divide a number by zero. divide a number by zero.

DUP_VAL_ON_INDEXDUP_VAL_ON_INDEX ORA-00001ORA-00001 Uniqueness of a column is violated Uniqueness of a column is violated by INSERT or UPDATEby INSERT or UPDATE

Every error that can be detected by Oracle has a unique number. Some exceptions have pre-defined names associated with them.

Handling exceptions of Select Handling exceptions of Select IntoInto

DECLAREv_name employees.last_name%TYPE; v_deptid employees.department_id%TYPE := &dept_id

BEGINSELECT last_name INTO v_nameFROM employees;WHERE department_id = v_deptid;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’||v_name);

EXCEPTIONWHEN TOO_MANY_ROWS THEN

DBMS_OUTPUT.PUT_LINE(‘ More than one row’);WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE(‘ No data’);END;

Enter value for dept_id: 99old 3: v_deptid employees.department_id%TYPE := &dept_idnew 3: v_deptid employees.department_id%TYPE := 99No data

PL/SQL procedure successfully completed.

There are no employees in department 99

Exception handling section

Handling exceptions of Select Handling exceptions of Select IntoInto

DECLAREv_name employees.last_name%TYPE; v_deptid employees.department_id%TYPE := &dept_id

BEGINSELECT last_name INTO v_nameFROM employees;WHERE department_id = v_deptid;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’||v_name);

EXCEPTIONWHEN TOO_MANY_ROWS THEN

DBMS_OUTPUT.PUT_LINE(‘ More than one row’);WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE(‘ No data’);END;

Enter value for dept_id: 20old 3: v_deptid employees.department_id%TYPE := &dept_idnew 3: v_deptid employees.department_id%TYPE := 20More than one row

PL/SQL procedure successfully completed.

There are two employees in department 20

Exception handling section

Handling exceptions of Select Handling exceptions of Select IntoInto

DECLAREv_name number; v_deptid employees.department_id%TYPE := &dept_id

BEGINSELECT last_name INTO v_nameFROM employees;WHERE department_id = v_deptid;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’||v_name);

EXCEPTIONWHEN VALUE_ERROR THEN

DBMS_OUTPUT.PUT_LINE(‘Data type conversion problem’);WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(‘error’);END;

Enter value for dept_id: 10old 3: v_deptid employees.department_id%TYPE := &dept_idnew 3: v_deptid employees.department_id%TYPE := 10Data type conversion problem

PL/SQL procedure successfully completed.

There is only one employee in department

10

OTHERS is a catch-all phrase for exceptions

SELECT INTO CAN HANDLE ONLY A SINGLE

ROW

Handling exceptions of Select Handling exceptions of Select IntoInto

DECLAREv_name varchar2(2); v_deptid employees.department_id%TYPE := &dept_id

BEGINSELECT last_name INTO v_nameFROM employees;WHERE department_id = v_deptid;

DBMS_OUTPUT.PUT_LINE( ‘Employee name is ’||v_name);

EXCEPTIONWHEN VALUE_ERROR THEN

DBMS_OUTPUT.PUT_LINE(‘Data type conversion problem’);WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(‘error’);END;

Enter value for dept_id: 10old 3: v_deptid employees.department_id%TYPE := &dept_idnew 3: v_deptid employees.department_id%TYPE := 10Data type conversion problem

PL/SQL procedure successfully completed.

There is only one employee in department 10 and his last

name is Whalen

OTHERS is a catch-all phrase for exceptions

Handling exceptions of DML Handling exceptions of DML statementsstatements

BEGININSERT INTO regions

(region_id, region_name)VALUES(1, ‘SCT’);

EXCEPTIONWHEN DUP_VAL_ON_INDEX THEN

DBMS_OUTPUT.PUT_LINE(‘Region_id must be unique’);WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(‘Error’);END;

Region_id must be unique

PL/SQL procedure successfully completed.

Region_id is the Primary key of regions table and therefore must be unique. Region_id=1 already exists in the table

You should anticipate all

possible problems and handle them in

the exception handling section

SummarySummary

This week we coveredThis week we covered CursorsCursors Cursor AttributesCursor Attributes How to use DML commands in PL/SQL blocksHow to use DML commands in PL/SQL blocks How to use select INTO in PL/SQL blocksHow to use select INTO in PL/SQL blocks Handling exceptions related to SELECT INTO Handling exceptions related to SELECT INTO

and DMLcommandsand DMLcommands

Next Week we will learn about the explicit Next Week we will learn about the explicit cursorscursors