Null Values in SQL Group By

·

SQL Having SQL Group By Examples of SQL Group By and SQL Having


It is known that Null <> Null. When two different NULL values are compared, the result is NULL (not TRUE), i.e. the two NULL values are not considered to be equal. Applying the same rule to the GROUP BY clause would force SQL to place each row with a NULL grouping column into a separate group by itself.

But creating a separate group for every row with a NULL in a grouping column is confusing and of no useful value, so designers wrote the SQL standard such that NULL values are considered equal for the purposes of a GROUP BY clause. Therefore, if two rows have NULL values in the same grouping columns and matching values in the remaining non-NULL grouping columns, the DBMS will group the rows together.

Simply put if the grouping column contains more than one null value, the null values are put into a single group.

For example, the grouped query:

SELECT A, B, SUM(amount_purchased) AS 'C'
FROM customers
GROUP BY A, B
ORDER BY A, B

will display a results table similar to

ABC
NULLNULL61438.0000
NULL101196156.0000
AZNULL75815.0000
AZ10336958.0000
CA10178252.0000
LANULL181632.0000


for CUSTOMERS that contain the following rows.

ABamount_purchased
NULLNULL45612.00000
NULLNULL15826.00000
NULL10145852.0000
NULL10174815.0000
NULL10175489.0000
AZNULL75815.0000
AZ10336958.0000
CA10178252.0000
LANULL96385.0000
LANULL85247.0000

Examples of SQL Having & SQL Group By

·

SQL Having SQL Group By Null in SQL Group By


Some of the examples found on the Internet:

Find the average sales price for each beer.

Sells (bar, beer, price)

SELECT beer, AVG (price)
FROM Sells
GROUP BY beer;

Find, for each drinker, the average price of Bud at the bars they frequent.

Sells (bar, beer, price)
Frequents (drinker, bar)


SELECT drinker, AVG (price)
FROM Frequents, Sells
WHERE beer = 'Bud' AND
Frequents.bar = Sells.bar
GROUP BY drinker;

Find the average price of those beers that are either served in at least 3 bars or manufactured by Anheuser-Busch.

Beers (name, manf)
Sells (bar, beer, price)


SELECT beer, AVG (price)
FROM Sells
GROUP BY beer
HAVING
COUNT (*) > = 3 OR
beer IN(
SELECT name
FROM Beers
WHERE manf = 'Anheuser-Busch'
);

SQL Inline Views

·

SQL Modifying View SQL Join View SQL Views


It is a subquery that appears in the From clause of the Select statement. The inline view is a construct in Oracle SQL where you can place a query in the SQL FROM, clause, just as if the query was a table name. This subquery is enclosed in parenthesis and may be given an alias name. The columns selected in the subquery can be referenced in the parent query.

As an example let us suppose that we want to select first 3 employees hired by the company.



When considering using an inline view, ask the following questions:
* What value does the inline view add to the readability and, more importantly, the performance of the containing query?
* How large will the result set generated by the inline view be?
* How often, if ever, will I have need of this particular data set?
In general, using an inline view should enhance the readability and performance of the query, and it should generate a manageable data set that is of no value to other statements or sessions; Most common usage of an Inline View is in “TOP-N” analysis

SQL Join View

·

SQL Modifying View SQL Views SQL Inline View


A join view is a view which is based on more than one base table. Any insert, update or delete statement on a view can update only one of the base tables involved in the view. A table is called a key preserved in a join view, if the primary and unique keys are unique on the views result set.

Sql> create view t1_view as select a.empno, a.ename, a.deptno, b.dname
2 from emp a, dept b
3 where a.deptno = b.deptno;
View created.

Sql>desc t1_view;

NameNull?Type
EMPNONOT NULLNUMBER(4)
ENAME
VARCHAR2(10)
DEPTPNO
NUMBER(2)
DNAME
VARCHAR2(14)


Sql> select * from t1_view;

EMPNOENAMEDEPTNODNAME
7369SMITH20RESEARCH
7499ALLEN30SALES
7521WARD30SALES
7566JONES20RESEARCH
7654MARTIN30SALES

5 rows selected.

In the above view table emp is key preserved because primary key of the emp is also unique in the view. The dept table is not key preserved as it primary key deptno is duplicated many times.
You can update only the key preserved table through the view.

If the view is defined with the WITH CHECK OPTION then you cannot update columns that join the base tables.

Insert statements also cannot refer to any column of the non key preserved table. If a view is created with “WITH CHECK OPTION” , then no insert is permitted on view.

Modifying SQL Views (Insert, Update and Delete on SQL Views)

·

SQL Views SQL Join View SQL Inline View


You can use the “OR Replace” option. If the view exists it will be replaced with the new definition or a new view will be created. We can use Create or Replace option to create views instead of dropping the view and recreating it, as with this option the privileges granted on the view are preserved, but the dependent stored programs and view become invalid.

The view will become invalid whenever the base table is altered. We can recompile a view using the Alter view statement, but oracle automatically recompiles the view once it is accessed. On recompiling the dependent objects become invalid.

ALTER VIEW View-Name COMPILE ;

Use Drop View statement to drop a view.

SQL> drop view emp_info;<>View dropped.

Insert, Delete and Update on Views

When you update a view oracle will update the underlying base table. You can use DML operations on a view if the view does not include Group by, Start with, Connect by, Distinct clauses or any subqueries and set operations(Union, union all, intersect and minus).

Sql> create table t1(name varchar2(10), id number);
Table created.

Sql> select * from t1;
no rows selected

Sql> create view t1_view as select * from t1;
View created.

Sql> insert into t1_view values('a',1);
1 row created.

Sql> select * from t1;

NAMEID
a1


Sql> select * from t1_view;

NAMEID
a1


You can check whether the particular columns in a view are updateable or not:

For the t1_view created above we can check like this

Sql> select * from user_updatable_columns where table_name = 'T1_VIEW';

OWNERTABLE_NAMECOLUMN_NAMEUPDINSDEL
SCOTTT1_VIEWNAMEYESYESYES
SCOTTT1_VIEWIDYESYESYES


Another example of non updatable view

Sql> create view t1_secret as select name, id * 2 "secret id" from t1;
View created.
SQL> desc t1_secret;

NameNull?Type
NAME
VARCHAR2(10)
Secret ID
NUMBER


Sql> select * from user_updatable_columns where table_name = 'T1_SECRET';

OWNERTABLE_NAMECOLUMN_NAMEUPDINSDEL
SCOTTT1_SECRETNAMEYESYESYES
SCOTTT1_SECRETSECRET IDNONONO


WITH CHECK OPTION

Suppose we have a table t1

Sql> select * from t1;

NAMEID
a1
b2
c3
d4
e5


We will create a view t1_view on table t1:

Sql> create view t1_view as select name, id from t1 where id > 3;
View created.
Sql> desc t1_view;

NameNull?Type
NAMENOT NULLVARCHAR2(10)
ID
NUMBER


Sql> select * from t1_view;

NAMEID
d4
e5


Now if we insert any row in the table through view with id less than or equal to 3 it will let us insert that.

Sql> insert into t1_view values('g',0);
1 row created.
Sql> select * from t1;

NAMEID
a1
b2
c3
d4
e5
g
0

6 rows selected.

Now we will use With Check option to create that view again:

Sql> create or replace view t1_view as select name, id from t1 where id > 3 with check option;
View created.

Now we will not be able to insert any row less than or equal to 3, only greater than 3 so as to match the view definition.

Sql> insert into t1_view values('k',1.5);
insert into t1_view values('k',1.5)
*
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation
Sql> insert into t1_view values('k',6);
1 row created

SQL Scalar subquery

·

SQL inline View subquery SQL Correlated subquery SQL Subqueries


A scalar subquery returns a single row and a single column value.

Example 1 of Scalar subquery

SELECT last_name, job_id, salary
FROM employees
WHERE salary > (SELECT avg(salary) FROM employees);

Example 2 of Scalar subquery

Select dname, (select count(*)
from emp
where emp.deptno= dept.deptno) cnt
from dept

SQL Subqueries can be single row, multiple rows, single column and multiple columns.

You can use single-row subqueries with single-row operators and multiple-row subqueries with multiple-row operators.

Example of Single Row Subquery

Find the highest salary :

SELECT last_name, salary
FROM employees
WHERE salary = (Select MAX(salary) FROM employees);

Example of Multiple Row Subquery

SELECT employee_id, last_name, salary
FROM employees
WHERE salary IN (SELECT Min(salary)
FROM employees
GROUP BY department_id);

Example of single column subquery

A query to retrieve the name of highest paid person in the department 30

Please see that ALL is used with comparison operator because subquery is not returning single value, It is returning multiple values.

Select first_name, last_name
from employee
where dept_id =30 and salary >=ALL (Select salary
from employee
where dept_id = 30);

Example of Multiple column subquery

A subquery that compares more than just one column between the parent query and the subquery is called multiple-column subquery.

Extract employees that make the same salaries as other employee with employee_id 420 with the same job

Select employee_ID, last_name, job_id, salary
from employees
where (job_id, salary) in (select job_id, salary
from employees
where employee_id =420);

SQL Correlated Subquery

·

SQL inline View subquery SQL Subqueries SQL Scalar subquery


When you reference a column from the table in the parent query in the subquery, it is known as a correlated subquery. For each row processed in the parent query, the correlated subquery is evaluated once.

While processing Correlated subquery:
  • The first row of the outer query is fetched.
  • The inner query is processed using the outer query’s value or values.
  • The outer query is processed using the inner query’s value or values.
  • This process is continued until the outer query is done.
Example 1 of Correlated subquery

Display all employees who have switched jobs at least twice.

SELECT e.last_name, e.salary, e.job_id
FROM employees e
WHERE 2 <= (SELECT Count(*)
FROM job_history j
WHERE j.employee_id = e.employee_id);

Example 2 of Correlated subquery

SELECT S.Number, S.Name
FROM Salesman S
WHERE S.Number IN(SELECT C.Salesman
FROM Customer C
WHERE C.Name = S.Name);

SQL Inline View Subquery

·

SQL Subqueries SQL Correlated subquery SQL Scalar subquery


When you use SQL Subquery in From clause of the select statement it is called inline view.

A common use for inline views in Oracle SQL is to simplify complex queries by removing join operations and condensing several separate queries into a single query. A subquery which is enclosed in parenthesis in the FROM clause may be given an alias name. The columns selected in the subquery can be referenced in the parent query, just as you would select from any normal table or view.

Example 1 of Inline View

Display the top five earner names and salaries from the EMPLOYEES table:

SELECT ROWNUM as RANK, last_name, salary
FROM (SELECT last_name, salary
FROM employees
ORDER BY salary DESC)
WHERE ROWNUM <= 5;

Example 2 of Inline View

Calculate the number of employees in each department

SELECT d.dept_id, d.name, emp_cnt.tot
FROM department d, (SELECT dept_id, count(*) tot
FROM employee
GROUP BY dept_id) emp_cnt
WHERE d.dept_id = emp_cnt.dept_id;

Examples of Oracle PL/SQL Cursors

·

Examples of Oracle PL/SQL Cursors:

1)
Retrieving the records from the emp table and displaying them one by one using cursors:

CREATE OR REPLACE PROCEDURE my_proc IS
var_empno emp.empno%type;
var_ename emp.ename%type;
var_sal emp.sal%type;

//declaring a cursor//
CURSOR EMP_CURSOR IS
select empno, ename, sal from emp;
BEGIN

//opening a cursor//
open EMP_CURSOR;
LOOP

//fetching records from a cursor//
fetch EMP_CURSOR into var_empno, var_ename, var_sal;

//testing exit conditions//
EXIT when EMP_CURSOR%NOTFOUND;
IF (var_sal > 1000) then
DBMS_OUTPUT.put_line(var_empno || ' ' || var_ename || ' ' || var_sal);
ELSE
DBMS_OUTPUT.put_line(var_ename || ' sal is less then 1000');
END IF;
END LOOP;

//closing the cursor//
close EMP_CURSOR;
DBMS_OUTPUT.put_line('DONE');

END;

2)
Create a PL/SQL block to increase salary of employees in department 17.
a) The salary increase is 20% for the employees making less than $90,000 and 12% for the employees making $90,000 or more.
b) Use a cursor with a FOR UPDATE clause.
c) Update the salary with a WHERE CURRENT OF clause in a cursor FOR loop (cursor FOR loop problem).



PL/SQL procedure successfully completed.

3)

An example of an Implicit cursor




Oracle automatically associates an implicit cursor with the SELECT INTO statement and fetches
the values for the variables var_firstname and var_lastname. After the SELECT INTO statement completes, Oracle closes the implicit cursor.

Oracle PL/SQL WHERE CURRENT OF & FOR UPDATE

·

Implicit Cursors Explicit Cursors Cursor For Loop REF Cursors Cursors with Parameters


The WHERE CURRENT OF clause is used in some UPDATE and DELETE statements.

The WHERE CURRENT OF clause in an UPDATE or DELETE statement states that the most recent row fetched from the table should be updated or deleted. We must declare the cursor with the FOR UPDATE clause to use this feature.

Inside a cursor loop, WHERE CURRENT OF allows the current row to be directly updated.

When the session opens a cursor with the FOR UPDATE clause, all rows in the return set will hold row-level exclusive locks. Other sessions can only query the rows, but they cannot update, delete, or select with FOR UPDATE.

Oracle provides the FOR UPDATE clause in SQL syntax to allow the developer to lock a set of Oracle rows for the duration of a transaction.

The syntax of using the WHERE CURRENT OF clause in UPDATE and DELETE statements follows:

WHERE [CURRENT OF cursor_name | search_condition]

The following example opens a cursor for employees and updates the commission, if there is no commission assigned based on the salary level.



The FOR UPDATE clause in the SELECT statement can only be specified in the top level; subqueries cannot have this clause.


Another Example of WHERE CURRENT OF

Go through all Maths students and set all GPA’s under 4.0 to 4.0!


DECLARE
thisStudent Student%ROWTYPE;

CURSOR Maths_Student IS
SELECT * FROM Student WHERE SID IN
(SELECT SID FROM Take WHERE CID = ’CS145’)
FOR UPDATE;

BEGIN
OPEN Maths_Student;
LOOP
FETCH Maths_Student INTO thisStudent;
EXIT WHEN (Maths_Student%NOTFOUND);
IF (thisStudent.GPA < 4.0) THEN
UPDATE Student SET GPA = 4.0
WHERE CURRENT OF Maths_Student;
END IF;
END LOOP;

CLOSE Maths_Student;
END;
.
RUN;

Oracle PL/SQL REF Cursors

·

Implicit Cursors Explicit Cursors Cursor For Loop Cursors with Parameters Where Current of & For Update


A REF CURSOR or cursor variable is just a reference or a handle to a static cursor. It allows a user to pass this “reference to the same cursor” among all the programs that need access to the cursor. Cursor variables give you easy access to centralized data retrieval.


There are two types of cursor variables; one is called Strong REF Cursor and the other is called Weak REF Cursor


What is the difference between Cursor and REF Cursor, and when would you appropriately use each of these?


Technically, under the covers, at the most "basic level", they are the same.


A "normal" plsql cursor is static in defintion.

Ref cursors may be dynamically opened or opened based on logic.



Declare
type rc is ref cursor;
cursor c is select * from dual;
l_cursor rc;
begin
if (to_char(sysdate,'dd') = 30 ) then
open l_cursor for 'select * from emp';
elsif ( to_char(sysdate,'dd') = 29 ) then
open l_cursor for select * from dept;
else
open l_cursor for select * from dual;
end if;
open c;
end;
/

  • Given that block of code - you see perhaps the most "salient" difference - no matter how many times you run that block - cursor C will always be select * from dual. The ref cursor can be anything.

  • Another difference is a ref cursor can be returned to a client. A PL/SQL cursor cannot be returned to a client.

  • Another difference is a cursor can be global - a ref cursor cannot (you cannot define them OUTSIDE of a procedure / function).

  • Another difference is a ref cursor can be passed from subroutine to subroutine - a cursor cannot be.

  • Another difference is that static SQL (not using a ref cursor) is much more efficient then using ref cursors and that use of ref cursors should be limited to.

    • returning result sets to clients

    • when there is NO other efficient/effective means of achieving the goal. That is, you want to use static SQL (with implicit cursors really) first and use a ref cursor only when you absolutely have to.

A ref cursor is a variable, defined as a cursor type, which will point to, or reference a cursor result. The advantage that a ref cursor has over a plain cursor is that is can be passed as a variable to a procedure or a function. The "REF CURSOR" can be assigned to other REF CURSOR variables. This is a powerful capability in that the cursor can be opened, then passed to another block for processing, then returned to the original block to be closed. The cursor variable can also be returned by a function and assigned to another variable. The REF CURSOR variable is not a cursor, but a variable that points to a cursor. Before assigning a cursor variable, a cursor type must be defined.

type author_cursor is ref cursor;

This "REF CURSOR" is a weak typed cursor variable because it does not define the datatype the cursor will return. Below is the same cursor that is strongly typed.

type author_cursor is ref cursor
returning author%rowtype;

By strongly typing the cursor variable, you define what the cursor can return. If a strongly typed cursor returns something other that its return type, a "ROWTYPE_MISMATCH" exception is raised. A strongly typed cursor type is less flexible but less prone to programming errors. The PL/SQL compiler will verify that the "FETCH clause" has the correct variable/record for the cursor return type at compile time.

Once the cursor type is defined, the actual variable can be defined as the cursor type.

c1 author_cursor;

Now c1 is a variable of a cursor type. It is opened using a SQL statement.

open c1 for select * from authors;

Now c1 has all the attributes of the actual cursor. As with any cursor it is important to close the cursor as soon as you have completed processing.

SQL> declare
2 type auth_cursor is ref cursor;
3 c1 auth_cursor;
4 r_c1 author%rowtype;
5 begin
6 open c1 for select * from author;
7 fetch c1 into r_c1;
8 if c1%isopen then
9 dbms_output.put_line('The Cursor is open.');
10 end if;
11 dbms_output.put_line('Row Count is '||c1%rowcount);
12 close c1;
13 if not c1%isopen then
14 dbms_output.put_line('The Cursor is closed.');
15 end if;
16 end;
17 /


The Cursor is open.
Row Count is 1
The Cursor is closed.

Here some of the cursor attributes are used to process the cursor. Notice that the record used to hold a fetched cursor row is defined as an author table "%rowtype". Even though the example cursor variable is defined, the record can not use it because the cursor variable return type is not defined. The example below attempts to create a cursor %rowtype variable for processing.

SQL> declare
2 type auth_cursor is ref cursor;
3 c1 auth_cursor;
4 r_c1 c1%rowtype;
5 begin
6 null;
7 end;
8 /
r_c1 c1%rowtype;
*
ERROR at line 4:
ORA-06550: line 4, column 8:
PLS-00320: the declaration of the type of this
expression is incomplete or malformed
ORA-06550: line 4, column 8:
PL/SQL: Item ignored

However, a strongly typed cursor can use the cursor variable to define the cursor record.

SQL> declare
2 type auth_cursor is ref cursor return author%rowtype;
3 c1 auth_cursor;
4 r_c1 c1%rowtype;
5 begin
6 null;
7 end;
8 /

In this example, the auth_cursor type returns an author%rowtype. Because this is defined in line 2, the record defined in line 4 can now use it.

Cursor variables that are weakly typed can be defined to return any values. In the example below, the cursor variable c1 is defined as three different statements.

SQL> declare
2 type auth_cursor is ref cursor;
3 c1 auth_cursor;
4 r_c1 author%rowtype;
5 r2_c1 book%rowtype;
6 r3_c1 number;
7 begin
8 open c1 for select * from author;
9 fetch c1 into r_c1;
10 close c1;
11 open c1 for select * from book;
12 fetch c1 into r2_c1;
13 close c1;
14 open c1 for select sum(quantity)
15 from store join sales using (store_key)
16 group by store_name;
17 fetch c1 into r3_c1;
18 close c1;
19 end;
20 /

Although the block does not do anything but open and close the cursor variable, it does demonstrate that weakly typed variables can be defined differently each time the variable is opened. But what happens when a cursor variable is defined with a SQL statement but returns unexpected values? Below is an example of defining a cursor variable of one type and the record as another. The cursor variable is returning all columns in the book table, but the receiving variable is defined as a record of columns from the author table.

SQL> declare
2 type auth_cursor is ref cursor;
3 c1 auth_cursor;
4 r_c1 author%rowtype;
5 begin
6 open c1 for select * from book;
7 fetch c1 into r_c1;
8 close c1;
9 end;
10 /
declare
*
ERROR at line 1:
ORA-06504: PL/SQL: Return types of Result Set
variables or query do not match
ORA-06512: at line 7

Notice that the error message is pointing to the DECLARE clause. That is because the block successfully compiled and only threw the error when it was executed. The PL/SQL compiler can not catch the error because the cursor type did not define a return type. By changing the definition of the cursor type to a strongly typed definition, the compiler will catch this error when the code is compiled.


SQL> declare
2 type auth_cursor is ref cursor
3 return book%rowtype;
4 c1 auth_cursor;
5 r_c1 author%rowtype;
6 begin
7 open c1 for select * from book;
8 fetch c1 into r_c1;
9 close c1;
10 end;
11 /

fetch c1 into r_c1;
*
ERROR at line 8:
ORA-06550: line 8, column 5:
PLS-00394: wrong number of values in the INTO
list of a FETCH statement
ORA-06550: line 8, column 5:
PL/SQL: SQL Statement ignored

Now the compiler catches the error. So far the examples have been using the cursor variables as regular cursors. The real advantage of using a cursor variable is the ability to pass it as a parameter. In the example below a local function is used to open a cursor called c1 and return it.
The block body calls the function to assign the cursor to the cursor variable c2. The block body then processes the cursor and closes it.

SQL> declare
2 type auth_cursor is ref cursor
return author%rowtype;
3 c2 auth_cursor;
4 r_c2 c2%rowtype;
5
6 function get_auth return auth_cursor
7 is
8 c1 auth_cursor;
9 begin
10 open c1 for select * from author;
11 return c1;
12 end;
13
14 begin
15 c2 := get_auth;
16 loop
17 fetch c2 into r_c2;
18 exit when c2%notfound;
19 dbms_output.put_line(initcap(r_c2.author_last_name));
20 end loop;
21 close c2;
22 end;
23 /

Jones
Hester
Weaton
Jackie
Withers
Petty
Clark
Mee
Shagger
Smith

Line 2 defines the cursor type. Lines 3 and 4 define the cursor and return record used in the body. Line 6 declares a local function called get_auth that returns an auth_cursor type. Inside this local function, cursor c1 is defined as an auth_cursor type, opened and returned to the calling code. The function is actually executed on line 15 when c2 is assigned the return value of the get_auth function. The cursor c2 is processed and finally closed on line 21. Note that c1 opened the cursor and c2 closed it. This is an important point.

The example contains only ONE cursor. When c2 is assign the value of c1, both variables point to the same cursor. Remember that c1 and c2 are variables that point to or reference the actual cursor.

The same basic example is shown below except, the output is generated by a local procedure. Note that the procedure print_name gets passed the cursor c2 and then processes it. It then passes the cursor backup to be closed by the body of the PL/SQL block.

SQL> declare
2 type auth_cursor is ref cursor
return author%rowtype;
3 c2 auth_cursor;
4 r_c2 c2%rowtype;
5
6 function get_auth return auth_cursor
7 is
8 c1 auth_cursor;
9 begin
10 open c1 for select * from author;
11 return c1;
12 end;
13
14 procedure print_name (c3 in out auth_cursor)
15 as
16 r_c3 author%rowtype;
17 begin
18 loop
19 fetch c3 into r_c3;
20 exit when c3%notfound;
21 dbms_output.put_line(initcap(r_c3.author_last_name));
22 end loop;
23 end;
24
25 begin
26 c2 := get_auth;
27 print_name(c2);
28 close c2;
29 end;
30 /

Jones
Hester
Weaton
Jeckle
Withers
Petty
Clark
Mee
Shagger
Smith

There are three items you should note about this PL/SQL block. First, the body is pretty simple to understand.

Get the authors, print the names, and close the cursor. Second, you can pass cursor variables to procedures and functions, and functions can return the variables. Lastly, it can become confusing about when a cursor variable should be closed.



Source: http://www.fast-track.cc/t_easyoracle_pl_sql_ref_cursors.htm and
http://www.oracle.com/technology/oramag/oracle/04-may/o34asktom.html?_template=/ocom/print

Oracle PL/SQL Cursors With Parameters

·

Implicit Cursors Explicit Cursors Cursor For Loop REF Cursors Where Current of & For Update


We can pass parameters into a cursor and use them in the query.


We can only pass values to the cursor; and cannot pass values out of the cursor through parameters.


Only the datatype of the parameter is defined, not its length.


Optionally, we can also give a default value for the parameter, which will take effect if no value is passed to the cursor.

The following cursor prints department number and name in one line followed by employees working in that department (name and salary) and total salary.



Cursors with parameters

DECLARE
CURSOR cur_dept IS SELECT * FROM dept ORDER BY deptno;
CURSOR cur_emp (par_dept VARCHAR2) IS
SELECT ename, salary
FROM emp
WHERE deptno = par_dept
ORDER BY ename;

r_dept DEPT%ROWTYPE;
var_ename EMP.ENAME%TYPE;
var_salary EMP.SALARY%TYPE;
var_tot_salary NUMBER (10,2);

BEGIN
OPEN cur_dept;
LOOP
FETCH cur_dept INTO r_dept;
EXIT WHEN cur_dept%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('Department : ' || r_dept.deptno || ' - '|| r_dept.dname);
var_tot_salary := 0;
OPEN cur_emp (r_dept.deptno);
LOOP
FETCH cur_emp INTO var_ename, var_salary;
EXIT WHEN cur_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('Name: ' ||var_ename || ' Salary:'||var_salary);
var_tot_salary := var_tot_salary + var_salary;
END LOOP;
CLOSE cur_emp;
DBMS_OUTPUT.PUT_LINE ('Total Salary for Dept: ' || var_tot_salary);
END LOOP;
CLOSE cur_dept;
END;
/

Important points to keep in mind for parameters in cursors are:
  • The mode of the parameters can only be IN.
  • Cursor becomes more reusable with Cursor parameters.
  • Default values can be assigned to Cursor parameters.
  • The scope of the cursor parameters is local to the cursor.

Oracle PL/SQL Cursor For Loops

·

Implicit Cursors Explicit Cursors REF Cursors Cursors with Parameters Where Current of & For Update


The following procedure is followed in most of the situations in PL/SQL:
  1. Open a cursor
  2. Start a loop
  3. Fetch the cursor
  4. Check whether rows are returned
  5. Process
  6. Close the loop
  7. Close the cursor

Cursor FOR loop allows us to simplify this procedure by letting PL/SQL do most of the things for us.

You can simplify coding by using a cursor FOR loop instead of the OPEN, FETCH, and CLOSE statements.

A cursor FOR loop implicitly declares its loop index as a record that represents a row fetched from the database.

Next, it opens a cursor, repeatedly fetches rows of values from the result set into fields in the record, and then closes the cursor when all rows have been processed.

Cursor FOR loop example

DECLARE CURSOR c1 IS
SELECT ename, sal, deptno
FROM emp;
...
BEGIN
FOR emp_rec IN c1 LOOP
...
salary_total := salary_total +
emp_rec.sal;
END LOOP;

Another example of Cursor FOR loop



Let us rewrite the example (used in Cursors with Parameters) again using Cursor FOR loop



Oracle PL/SQL Explicit Cursors

·

Implicit Cursors Cursor For Loop REF Cursors Cursors with Parameters Where Current of & For Update


Programmers create explicit cursors, and with these you can do operations on a set of rows, which can be processed one by one. You use explicit cursors when you are sure that the SQL statement will return more than one row. You have to declare an explicit cursor in the declare section at the beginning of the PL/SQL block.

Use explicit cursors to individually process each row returned by a multiple-row SELECT statement.

Explicit cursor functions:
  • Can process beyond the first row returned by the query, row by row

  • Keep track of which row is currently being processed

  • Allow the programmer to manually control explicit cursors in the PL/SQL block

Once you declare your cursor, the explicit cursor will go through these steps:

Declare: This clause initializes the cursor into memory.
Open: The previously declared cursor is now open and memory is allotted.
Fetch: The previously declared and opened cursor can now access data;
Close: The previously declared, opened, and fetched cursor is closed, which also releases memory allocation.

Below is a small example of Explicit cursor:

SQL> set serveroutput on;
SQL> Declare
2 Cursor empcursor(empn in number)
3 Is select * from emp where empno=empn;
4
5 empvar emp%rowtype;
6 Begin
7 Dbms_output.put_line('Getting records for employee no. 7521');
8 Open empcursor(7521);
9 Loop
10 Fetch empcursor into empvar;
11 Exit when empcursor%notfound;
12 Dbms_output.put_line('emp name : ' || empvar.ename);
13 Dbms_output.put_line('emp salary : ' || empvar.sal);
14 End loop;
15 Close empcursor;
16 End;
17 /
Getting records for employee no. 7521
emp name : WARD
emp salary : 1250

PL/SQL procedure successfully completed.


Explicit Cursor Attributes

Here are the main cursor attributes:

%ISOPENIt returns TRUE if cursor is open, and FALSE if it is not.
%FOUNDIt returns TRUE if the previous FETCH returned a row and FALSE if it did not.
%NOTFOUNDIt returns TRUE if the previous FETCH did not return a row and FALSE if it did.
%ROWCOUNTIt gives you the number of rows the cursor fetched so far.


Some more examples of Explicit Cursors:

Example 1 of an Explicit Cursor:

An example to retrieve the first 10 employees one by one.

SET SERVEROUTPUT ON
DECLARE
v_empno employees.employee_id%TYPE;
v_ename employees.last_name%TYPE;
CURSOR emp_cursor IS
SELECT employee_id, last_name
FROM employees;
BEGIN
OPEN emp_cursor;
FOR i IN 1..10 LOOP
FETCH emp_cursor INTO v_empno, v_ename;
DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_empno)
||' '|| v_ename);
END LOOP;
Close emp_cursor
END ;

Example 2 of an Explicit Cursor:

DECLARE

CURSOR csr_ac (p_name VARCHAR2) IS
SELECT empno, name, sal
FROM employee
WHERE name LIKE '%p_name%';

BEGIN

FOR rec_ac IN csr_ac ('LE')
LOOP
DBMS_OUTPUT.PUT_LINE(rec_ac.empno || ' ' ||rec_ac.name || ' '||v_sal);
END LOOP ;

CLOSE csr_ac;

END;

Example 3 of Explicit Cursor:

Another way of writing the above code, is to use the basic loop and the SQL%NOTFOUND cursor, as shown in the following.

DECLARE
CURSOR csr_ac (p_name VARCHAR2) IS
SELECT empno, ename, sal
FROM emp

WHERE ename LIKE '%SMITH%';

v_a emp.empno%TYPE;
v_b emp.ename%TYPE;
v_c emp.sal%TYPE;

BEGIN
OPEN csr_ac('');
LOOP
FETCH csr_ac INTO v_a, v_b, v_c;
EXIT WHEN csr_ac%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(v_a || ' ' || v_b || ' '||v_c);

END LOOP;
CLOSE csr_ac;
END;

Oracle PL/SQL Implicit Cursors

·

Explicit Cursors Cursor For Loop REF Cursors Cursors with Parameters Where Current of & For Update


Implicit cursors are automatically created and used by Oracle every time you issue a Select statement in PL/SQL. If you use an implicit cursor, Oracle will perform the open, fetches, and close for you automatically. Implicit cursors are used in statements that return only one row. If the SQL statement returns more than one row, an error will occur.

The Oracle server implicitly opens a cursor to process each SQL statement not associated with an explicitly declared cursor. PL/SQL allows you to refer to the most recent implicit cursor as the SQL cursor.

For a long time there have been debates over the relative merits of implicit cursors and explicit cursors. The short answer is that implicit cursors are faster and result in much neater code so there are very few cases where you need to resort to explicit cursor.

The process of an implicit cursor is as follows:

  1. Whenever an SQL statement is executed, any given PL/SQL block issues an implicit cursor, as long as an explicit cursor does not exist for that SQL statement.
  2. A cursor is automatically associated with every DML statement (UPDATE, DELETE, and INSERT).
  3. All UPDATE and DELETE statements have cursors those recognize the set of rows that will be affected by the operation.
  4. An INSERT statement requires a place to accept the data that is to be inserted in the database; the implicit cursor fulfills this need.
  5. The most recently opened cursor is called the “SQL%” Cursor.

The implicit cursor is used to process INSERT, UPDATE, DELETE, and SELECT INTO statements. Oracle automatically performs the OPEN, FETCH, and CLOSE operations, during the processing of an implicit cursor.

In the following PL/SQL code block, the select statement makes use of an implicit cursor:

Begin
Update emp Where 1=2;
Dbms_output.put_line (sql%rowcount ||’ ‘|| ‘ rows are affected by the update statement’);
End;
SELECT SUM (sal) INTO TOTAL
FROM emp
WHERE depno = 10;

Another Example

The following single-row query calculates and returns the total salary for a department. PL/SQL creates an implicit cursor for this statement:

SELECT SUM (salary) INTO department_total
FROM employee
WHERE department_number = 10;

PL/SQL provides some attributes, which allow you to evaluate what happened when the implicit cursor was last used. You can use these attributes in PL/SQL statements like functions but you cannot use then within SQL statements.

%ROWCOUNTThe number of rows processed by a SQL statement.
%FOUNDTRUE if at least one row was processed.
%NOTFOUNDTRUE if no rows were processed.
%ISOPENTRUE if cursor is open or FALSE if cursor has not been opened or has been closed. Only used with explicit cursors.


An Example:

DECLARE
rows_deleted NUMBER;
BEGIN
DELETE * FROM emp;
rows_deleted := SQL%ROWCOUNT;
END;


The implicit cursor has the following drawbacks:
  • It is less efficient than an explicit cursor.
  • It is more vulnerable to data errors.
  • It gives you less programmatic control.

Please see this link to know if Implicit cursors are fast or Explicit cursors.

PL/SQL Programmer Defined Records

·

These are records in which you, the programmer, define a record type.

Example 1 of Programmer Defined Records

Type my_first_record is record (

Name varchar2(20);
Age number;
Salary number;);

Var_of_myfirstrecord my_first_record;

Example 2 of Programmer Defined Records


DECLARE

TYPE employee_rectype IS RECORD (
emp_id NUMBER(10) NOT NULL
,dept_no dept.deptno%TYPE
,nаme empnаme_rectype
,hire_dаte DATE := SYSDATE);

new_emp_rec employee_rectype;

BEGIN

PL/SQL Cursor Based Records

·

Cursor-Based record has fields that match in name, datatype, and order to the final list of columns in the cursor’s SELECT statement.

Example 1 of Cursor Based Records

Cursor emp_cur is
Select ename, eno. , hiredate
From emp;

emp_rec emp_cur%ROWTYPE

Example 2 of Cursor Based Records

CURSOR c IS
SELECT beer, price
FROM Sells
WHERE bar = 'Joe''s bar';

Bp1 c%ROWTYPE;

PL/SQL Table Based Records

·

You define and declare records either in the declaration section of a PL/SQL block, or globally, via a package specification. A table-based record is one whose structure is drawn from the list of columns in the table. A table-based record is drawn from a particular table structure.

%TYPE and %ROWTYPE

%TYPE is used to declare a variable that is of the same type as a specified table’s column.

Emp_number emp.empno%type;

%ROWTYPE is used to declare a record i.e. a variable that represents the entire row of a table.

Emp_record emp%rowtype

Another example of Table Based Record

Declare table-based record for employee table.

emp_rec employee%ROWTYPE

Oracle PL/SQL Nested Tables

·

PL/SQL Records PL/SQL TablesPL/SQL Varrays

Nested tables are similar to index by table but these can be stored in database columns but index by tables cannot be stored in database columns.

A nested table can be considered as a single-column table that can either be in memory, or as a column in a database table. A nested table is quite similar to a VARRAY with the exception that the order of the elements is not static. Elements can be deleted or added anywhere in the nested table where as a VARRAY can only add or delete elements from the end of the array. Nested Table is known as a sparse collection because a nested table can contain empty elements.

Nested tables are a superior choice when:
  • You need to delete or update some elements, but not all the elements at once.
  • The index values are not consecutive.
  • We don’t have any predefined upper bound for index values.
Example 1 of Pl/SQL Nested Table

DECLARE
TYPE n_tab_T IS TABLE OF NUMBER;
nt n_tab_T := n_tab_T();

BEGIN
FOR i IN 1..10 LOOP
nt.EXTEND;
nt(i) := i;
END LOOP;
END;

Example 2 of Pl/SQL Nested Table

Suppose we have a more complex beer type:

create type BeerBrand as object (
name char(20),
kind char(10),
color char(10) );

We may create a type that is a nested table of objects of this type by

create type BeerTableBrand as table of BeerBrand;

Define a relation of manufacturers that will nest their beers inside.

create table manfs (
name char(30),
addr AddrType,
beers BeerTableBrand)
nested table beers store as BeerTable;

The last line in the create table statement indicates that the nested table is not stored “in-line” with the rest of the table
(Oracle maintains pointers between tables); you cannot refer to BeerTable in any query!

Inserting into nested table

insert into manfs values
(’Budweiser’,
AddrType(’LoopRoad’,’Boga’,’CA’,56789),
BeerTableBrand(
BeerBrand(’sweet’,’ale’,’yellow’),
BeerBrand(’sour’,’lager’,’pale’)
)
);

Querying the nested table

Example: List the beers made by Budweiser:

select beers from manfs
where name = ’Budweiser’;

This query gives you a single value that looks like this:

BeerTableBrand(
BeerBrand(’sweet’,’ale’,’yellow’),
BeerBrand(’sour’,’lager’,’pale’))



Oracle PL/SQL Varrays

·

PL/SQL Records PL/SQL TablesPL/SQL Nested Tables

Varray stands for variable-size array. Varrays can be stored in the columns of your tables. When you create varrays you must provide the maximum size for them. They retain their ordering and subscripts when stored in and retrieved from a database table. They are similar to PL/SQL table, and each element in a varray is assigned a subscript/index starting with 1.These are dense and Not sparse, which means there is no way to delete individual elements of a varrays.

Example 1 of PL/SQL Varray

Once the VARRAY is defined, elements can easily be inserted into the VARRAY. We can initialize our PLSQL varrays either in the declaration or separately. If the varray is only partially initialized we have to use the EXTEND method to define extra cells.

SQL> declare
2 type auth_var is varray(10) of
3 author.author_last_name%type;
4 x_auth auth_var := auth_var();
5 begin
6 x_auth.extend;
7 x_auth(1) := 'Hello';
8 x_auth.extend;
9 x_auth(2) := 'World';
10 dbms_output.put_line(
x_auth(1) ||' & '|| x_auth(2));
11 end; /

Hello & World

In the lines 2 and 3 we define the VARRAY type with a maximum of 10 elements. In line 4 we define the variable x_auth of auth_var type and it also initializes the array. A VARRAY can not be used until it is initialized. In line 4 the auth_var() function actually does the initialization.

Once the array is initialized you can extend it and add elements, which is done in lines 6 through 9. We access each element using the VARRAY variable and the index number. When the PL/SQL block ends (or the array variable goes out of scope), the memory used by the array is recovered automatically by the PL/SQL engine. Unlike a cursor, you do not close a collection.

Example 2 of PL/SQL Varray



Example 3 of PL/SQL Varray




PL/SQL procedure successfully completed.

Let us take a look what the line varray.EXTEND(2, 4);does in the above code. It appends two copies on the fourth element to the collection. As a result, the seventh and eighth elements both contain a value of 4.

Oracle PL/SQL Tables

·

PL/SQL Records PL/SQL VarraysPL/SQL Nested Tables

PL/SQL has two composite datatypes: TABLE and RECORD.

Objects of type TABLE are known as PL/SQL tables.

PL/SQL tables use a primary key to give you array-like access to rows. The number of rows in a PL/SQL table can increase dynamically. The PL/SQL table grows as new rows are added. PL/SQL tables can have one column and a primary key, neither of which can be named. The column can belong to any scalar type, but the primary key must belong to type BINARY_INTEGER.

A PL/SQL table can consist of one simple datatype or be defined as a type of record and is sometimes referred to as an Index by table.

Rows in a PL/SQL table do not have to be contiguous.

Tables with simple datatypes can be populated as:

<variable>(<integer>) := <value>;

Tables with complex datatypes will need the columns populated individually as:

<variable>(<integer>).<column_name> := <value>;

Or from a cursor:

fetch <cursor_name> into <variable>(<integer>);

Example 1 of PL/SQL Table

Type my_first_table is table of varchar2(10)
Index by binary_integer;
Var_of_table my_first_table;
Var_of_table(1) := ‘hello world’;
Var_of_table(2) := ‘bye’;

Example 2 of PL/SQL Table

Type my_emp_table is table of emp%rowtype
Index by binary_integer:
Var_of_emp my_emp_table;
Var1_of_emp my_emp_table;
Var_of_emp(1).ename := ‘sachin’;
Var_of_emp(1).empno := 20;
Var_of_emp(1).sal := 3000;

To delete individual records from PL/SQL tables:

Var_of_emp .delete(1);

To remove all entries from a PL/SQL table:

Var_of_emp.delete;

Or

Var_of_emp := var1_of_emp

Where var1_of_emp does not contain any value, it is empty.

COUNT method can be used to return number of records in a PL/SQL Table.

Var_of_table.count

First, Next and Last methods of PL/SQL Tables.

First is for first index in the PL/SQL Tables.

Last is for last index in the PL/SQL Tables.

Next is for next index in the PL/SQL Tables.

Example showing First and Next method of PL/SQL tables

SQL> set serveroutput on

SQL> Declare
2
3 Type my_dept_table is table of varchar2(20)
4 Index by binary_integer;
5
6 Var_of_dept my_dept_table;
7 Index_value number;
8
9 Begin
10
11 For dept_rec in (select * from dept) loop
12 Var_of_dept(dept_rec.deptno) := dept_rec.dname;
13 End loop;
14
15 Index_value := var_of_dept.first;
16 Loop
17 Exit when index_value is null;
18 Dbms_output.put_line (index_value || ' ' ||var_of_dept(index_value));
19 Index_value := var_of_dept.next(index_value);
20 End loop;
21 End;
22 /

10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS

PL/SQL procedure successfully completed.

Oracle PL/SQL Records

·

PL/SQL Tables PL/SQL VarraysPL/SQL Nested Tables


A PL/SQL record is a collection of basic types of data and can be accessed as a single unit.

PL/SQL records are similar in structure to a row in a database table.

A record consists of components of any scalar, PL/SQL record, or PL/SQL table type.
It makes your life easier by transferring the entire row into a record, rather than transferring each column into a variable separately.

PL/SQL supports three kinds of records:


Important points on records

1.
Individual fields are referenced via dot notation:

record_name.field_name

Example:

Emp_rec.first_name

2.
Individual fields within a record can be read from or written to. They can appear on either the left or right side of the assignment operator:

BEGIN
policy_start_date:= new_emp_rec.hire_date + 30;
new_emp_rec.present:= FALSE;

3.
An entire record can be assigned to another record of the same type.

However the assignment can fail, if you do not conform to these rules:
  • Both cursor-based records in a collective assignment must be based on the same cursor.
  • Both table-based records in a collective assignment must be based on the same table.
  • Both programmer-defined records in a collective assignment must be based on the same TYPE...RECORD statement.
4.
Records cannot be compared, rather their field can be.

SQL PL/SQL Interview Questions

·

These questions will be updated and new questions will be added on regular basis, so stay tuned and subscribe to RSS Feed.

What special operators does Oracle provide for dealing with NULLs?

NVL - Converts a NULL to another specified value, as in:

my_var := NVL (your_var, 'Hello');

IS NULL
and IS NOT NULL

You can use this syntax to check specificaly to see if a variable's value is NULL or NOT NULL.


Explain three different rules that apply to NULLs when doing comparisons?

1. For all operators except for concatenation (||), if a value in an expression is a NULL, that expression evaluates to NULL

2. NULL is never equal or not equal to another value

3. NULL is never TRUE or FALSE

What command would you use to encrypt a PL/SQL application?

WRAP


Explain the difference between a FUNCTION, PROCEDURE and PACKAGE.

A function has a return type in its specification and must return a value specified in that type. A procedure does not have a return type in its specification and should not return any value, but it can have a return statement that simply stops its execution and returns to the caller.


What steps are included in the compilation process of a PL/SQL block?

The compilation process includes syntax checking, binding, and p-code generation. Syntax checking involves checking PL/SQL code for compilation errors. After syntax errors have been corrected, a storage address is assigned to the variables that are used to hold data for Oracle. This process is called binding. Next, p-code is generated for the PL/SQL block. P-code is a list of instructions to the PL/SQL engine. For named blocks, p-code is stored in the database, and it is used the next time the program is executed.

How does a syntax error differ from a runtime error?

A syntax error can be detected by the PL/SQL compiler. A runtime error occurs while the program is running and cannot be detected by the PL/SQL compiler.

A misspelled keyword is an example of a syntax error. For example, this script:

BEIN
DBMS_OUTPUT.PUT_LINE ('This is a test');
END;

contains a syntax error. Try to find it.

A SELECT INTO statement returning no rows is an example of a runtime error. This error can be handled with the help of the exception-handling section of the PL/SQL block.

SQL PL/SQL Interview QuestionsDefine Commit, Rollback and Savepoint.

When a COMMIT statement is issued to the database, the transaction has ended, and the following results are true:

. All work done by the transaction becomes permanent.

. Other users can see changes in data made by the transaction.

. Any locks acquired by the transaction are released.

When a ROLLBACK statement is issued to the database, the transaction has ended, and the following results are true:

. All work done by the transaction is undone, as if it hadn’t been issued.

. Any locks acquired by the transaction are released.

The ROLLBACK statement undoes all the work done by the user in a specific transaction. With the SAVEPOINT command, however, only part of the transaction can be undone.

SQL PL/SQL Interview QuestionsExplain Implicit and Explicit cursors

Oracle automatically declares an implicit cursor every time a SQL statement is executed. The user is unaware of this and cannot control or process the information in an implicit cursor.

The program defines an explicit cursor for any query that returns more than one row of data. This means that the programmer has declared the cursor within the PL/SQL code block. This declaration allows the application to sequentially process each row of data as the cursor returns it.

SQL PL/SQL Interview QuestionsHow an Implicit cursor works?

  1. Any given PL/SQL block issues an implicit cursor whenever a SQL statement is executed, as long as an explicit cursor does not exist for that SQL statement.
  2. A cursor is automatically associated with every DML (data manipulation) statement (UPDATE, DELETE, INSERT).
  3. All UPDATE and DELETE statements have cursors that identify the set of rows that will be affected by the operation.
  4. An INSERT statement needs a place to receive the data that is to be inserted into the database; the implicit cursor fulfills this need.
  5. The most recently opened cursor is called the SQL cursor.


SQL PL/SQL Interview QuestionsHow an Explicit cursor works?

The process of working with an explicit cursor consists of the following steps:

1. Declaring the cursor. This initializes the cursor into memory.

2. Opening the cursor. The declared cursor is opened, and memory is allotted.

3. Fetching the cursor. The declared and opened cursor can now retrieve data.

4. Closing the cursor. The declared, opened, and fetched cursor must be closed to release the memory allocation.

SQL PL/SQL Interview QuestionsWhat are Explicit Cursor attributes


%NOTFOUNDcursor_name%NOTFOUNDA Boolean attribute that returns TRUE if the previous FETCH did not return a row and FALSE if it did.
%FOUNDcursor_name%FOUNDA Boolean attribute that returns TRUE if the previous FETCH returned a row and FALSE if it did not.
%ROWCOUNT cursor_name%ROWCOUNTThe number of records fetched from a cursor at that point in time.
%ISOPEN cursor_name%ISOPENA Boolean attribute that returns TRUE if the cursor is open and FALSE if it is not.


SQL PL/SQL Interview QuestionsAnswer any three PL/SQL Exceptions?

Too_many_rows,
No_Data_Found,
Value_Error,
Zero_Error,
Others

SQL PL/SQL Interview QuestionsWhat are PL/SQL Cursor Exceptions?

Cursor_Already_Open, Invalid_Cursor

SQL PL/SQL Interview QuestionsWhat is the maximum number of triggers, can apply to a single table?

12 triggers.

SQL PL/SQL Interview QuestionsWhat is a mutating table error and how can you get around it?

This happens with triggers. It occurs because the trigger is trying to update a row it is currently using. The usual fix involves either use of views or temporary tables so the database is selecting from one while updating the other.

SQL PL/SQL Interview QuestionsWhat packages (if any) has Oracle provided for use by developers?

Oracle provides the DBMS_ series of packages. There are many which developers should be aware of such as DBMS_SQL, DBMS_PIPE, DBMS_TRANSACTION, DBMS_LOCK, DBMS_ALERT, DBMS_OUTPUT, DBMS_JOB, DBMS_UTILITY, DBMS_DDL, UTL_FILE. If they can mention a few of these and describe how they used them, even better. If they include the SQL routines provided by Oracle, great, but not really what was asked.

SQL PL/SQL Interview QuestionsDescribe the use of PL/SQL tables

PL/SQL tables are scalar arrays that can be referenced by a binary integer. They can be used to hold values for use in later queries or calculations. In Oracle 8 they will be able to be of the %ROWTYPE designation, or RECORD.

SQL PL/SQL Interview QuestionsWhen is a declare statement needed?

The DECLARE statement is used in PL/SQL anonymous blocks such as with stand alone, non-stored PL/SQL procedures. It must come first in a PL/SQL stand alone file if it is used.

SQL PL/SQL Interview QuestionsIn what order should a open/fetch/loop set of commands in a PL/SQL block be implemented if you use the %NOTFOUND cursor variable in the exit when statement? Why?

OPEN then FETCH then LOOP followed by the exit when. If not specified in this order will result in the final return being done twice because of the way the %NOTFOUND is handled by PL/SQL.

SQL PL/SQL Interview QuestionsWhat are SQLCODE and SQLERRM and why are they important for PL/SQL developers?

SQLCODE returns the value of the error number for the last error encountered. The SQLERRM returns the actual error message for the last error encountered. They can be used in exception handling to report, or, store in an error log table, the error that occurred in the code. These are especially useful for the WHEN OTHERS exception.

SQL PL/SQL Interview QuestionsHow can you find within a PL/SQL block, if a cursor is open?

Use the %ISOPEN cursor status variable.

SQL PL/SQL Interview QuestionsHow can you generate debugging output from PL/SQL?

Use the DBMS_OUTPUT package. Another possible method is to just use the SHOW ERROR command, but this only shows errors. The DBMS_OUTPUT package can be used to show intermediate results from loops and the status of variables as the procedure is executed. The new package UTL_FILE can also be used.

SQL PL/SQL Interview QuestionsWhat are the types of triggers?

There are 12 types of triggers in PL/SQL that consist of combinations of the BEFORE, AFTER, ROW, TABLE, INSERT, UPDATE, DELETE and ALL key words:
BEFORE ALL ROW INSERT
AFTER ALL ROW INSERT
BEFORE INSERT
AFTER INSERT etc.

SQL PL/SQL Interview QuestionsHow can I define a two-dimensional array of numbers in PL/SQL?

Although PL/SQL does not natively support the declaration and manipulation of multidimensional arrays, you can emulate these structures using nested collection definitions, which were first supported in Oracle9i Database Release 1.

Here is a brief example to get you started and introduce you to some of the challenges you may encounter as you use collections in this way.

First, create a collection of associative arrays.

CREATE OR REPLACE PACKAGE twodim_aa
IS
TYPE data_t IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;

TYPE array_t IS TABLE OF data_t
INDEX BY PLS_INTEGER;
END twodim_aa;
/

The first, inner collection—data_t—contains the data for each cell in the two-dimensional array. Each row in the outer collection—array_t—contains a collection of the first type.

Now declare a variable based on that outer collection type —array_t—, which will serve as a two-dimensional array. In the following script, I declare such a collection—

DECLARE
l_2d_grid twodim_aa.array_t;

—and then assign values to three cells: (1,1), (1,2), and (200,206). Notice that the syntax is different from that used in traditional array cell specification, namely: (1)(1), (1)(2), and (200)(206). Also, since I am using associative arrays to define my two-dimensional array, I do not have to specify a size for this two-dimensional array.


DECLARE
l_2d_grid twodim_aa.array_t;
BEGIN
l_2d_grid (1) (1) := 100;
l_2d_grid (1) (2) := 120;
l_2d_grid (200) (206) := 200;

IF l_2d_grid (1)(2)

source of above question: http://www.oracle.com/technology/oramag/oracle/06-jan/o16plsql.html

Live Traffic Feed

About this blog

Site Sponsors