Showing posts with label oracle. Show all posts
Showing posts with label oracle. Show all posts

29 December, 2015

Oracle | Forward Declaration

Forward Declaration of Elements

There can be cases where the elements have to called in program code before they are coded in the program. But Oracle is very fuzzy about the declaration of program units. It will throw you an error because if the element is not defined, Oracle treats it as wrong semantic.

To resolve cases, where mutual recursion is present, meaning a program element calls another program unit which in turn calls the first program unit, this issue can be resolved using forward declarations.
In forward declaration, the actual element is not coded, but rather a declaration of it is made before calling it in another program unit. This ensures that Oracle knows the code for the declared program unit is somewhere later present in the code.

There are few guidelines for forward declaration as well:
1. A variable or a cursor cannot be forward declared.
2. Only modules like a procedure or a function can be forward declared.
3. The definition of the forward declared element should be present in the declaration part of the same PL/SQL block where the element is declared.

12 October, 2015

Oracle B Tree and Bitmap Index | Internal working

Oracle B-tree indexes
B-tree indexes are ordered lists of values divided into ranges with a key associated with a row or range of rows, thereby providing excellent retrieval performance for queries such as exact match and range searches.
This type of index contains 3 types of blocks - the root block, one or more branch blocks and one or more leaf blocks. The root block holds keys and pointers to the branch blocks which in turn hold pointers to the leaf blocks which contain the key (data) values that have been indexed and the rowids of the rows in the Oracle database table associated with each key value.
Branch blocks hold the minimum key prefix needed to be able to choose the required branch and a pointer to the child block containing the key. The number of keys and pointers is limited by the block size. Index leaf blocks are double linked - each block contains pointers to the next and previous leaf blocks.
B-tree indexes are always balanced because the height of the index (the number of levels in the index) is the same throughout the index. In other words, the number of blocks that have to be read to find the rowid associated with any particular index value is not dependent on that value. For example if you had an index on the last_name column of the employee table in the sample Oracle database the number or blocks that would need to be read to find the rowid associated with "Ernst" would be the same as for "King".
The height of a b-tree index is the number of blocks required to go from the root block to a leaf block. For an index with one level of branch blocks the height is 3 (1 root block + 1 branch block + 1 leaf block).

Oracle bitmap indexes
Bitmap indexes are completely different to b-tree indexes. Whereas b-tree indexes are ideal for storing highly selective/unique values (low cardinality), bitmap indexes are designed to store values of low cardinality where the same value can be found in a large proportion of the table. An example of this might be the part number column in the sales table, or gender in the employee table.
With this type of index, each distinct value of the column is associated with a set of bits representing the rows in the table (one bit for each row in the table). Each bit has a value of 0 or 1. If the bit is set then then the row associated with that bit has that value in the column.
Bitmap indexes are expensive to maintain as the whole bitmap has to be rebuilt after any DML operation (insert/update/delete) on the table.

Oracle Triggers

Triggers are an important part of Oracle. And I know only them to be the objects which are event-driven. 

That means they cannot be executed by the plsql code and rather they depend upon some event to occur. That event can be any DML operation a table or a DDL level operation on the database.

Definition - Triggers are procedures which are event-driven.

Timing points(Events which trigger triggers) - BEFORE | AFTER
ROW LEVEL | STATEMENT LEVEL

So if there are multiple triggers defined on a table, from the above, we can define the order of the trigger execution. 
Before statement >>> Before each row >>> DML >>> After each row >>> After statement.

FOLLOWS - If there are multiple triggers defined at the same timing point for a table, then the order in which they will be executed, is not defined; and is decided by Oracle server.
But, in Oracle 11g, there a new keyword FOOLOWS created. through this keyword, we can define which trigger is to follow which trigger.

COMPOUND TRIGGER - We define a trigger for a particular event, like before the row of after the statement, but Oracle 11g, brought this new way to define a single trigger which can define code blocks to run at different events. This is compound trigger.
Compound trigger have many benefits over normal triggers. And they have many rules as well.

|||||||||||||||||||||||||||||||||||||||||||||||

BEFORE and AFTER triggers are available for tables; INSTEAD OF triggers is available for views only.

Up to 3 triggering events can be connected and specified using the keyword OR. INSERT OR UPDATE OR DELETE

UPDATE can be optionally followed by OF; specifying the columns whose update will run the trigger.

the special columns NEW and OLD are only available if the trigger is row-level.
CREATE TRIGGER trig_tt
AFTER INSERT
REFERENCING NEW AS newrec
OR UPDATE
ON tab_tt
FOR EACH ROW
WHEN(newrec.a1 <= 100)
BEGIN
   INSERT INTO tem VALUES (:newrec.b1, :newrec.c1);
END trig_tt;

As you can see from the above code, the special variable NEW is used without colon(:) in the WHEN clause.

|||||||||||||||||||||||||||||||||||||||||||||||
To check the errors in a trigger, use:
SHOW ERRORS TRIGGER trigger_name
|||||||||||||||||||||||||||||||||||||||||||||||
list all user created triggers -
SELECT trigger_name FROM USER_TRIGGERS;
|||||||||||||||||||||||||||||||||||||||||||||||
 MUTATING TABLE ERRORS
when the trigger queries or tries to modify a table which is mutating already; Oracle will report a mutating trigger error.

To Aviod mutating table errors:
> A row-level trigger must not query or modify a mutating table. NEW and OLD values are still accessible.
> A statement-level trigger must not query or modify a mutating table of the trigger is fired as the result of a CASCADE DELETE.

|||||||||||||||||||||||||||||||||||||||||||||||
FUN FACTS
Oracle puts a size limit of 32 kb to triggers. This size is big enough to write over 4000 characters. But if you still need more code, then the best idea is to create named procedures and call them in the code of triggers.

Oracle fires all triggers of a type together and then triggers of another type.
We can't control which type will be fired when.

25 September, 2015

FOR UPDATE , NO WAIT | Oracle

When a SELECT statement picks the data from any table, the rows are not locked. And while the user performs some operation on the data, there is a chance that some other user may delete or modify the data. 

To resolve this, we can use the FOR UPDATE clause, which locks the rows picked up in the select statement and releases the locks only after the code block is exited. Ex- 

CURSOR cursor_name
IS
   select_statement

   FOR UPDATE [OF column_list] [NOWAIT]

This cursors select statement has put a lock on the selected rows and will be released only after the cursor is closed.

The NOWAIT clause is optional and it means that the control will not wait for the resources to be available. the

Mutating Trigger | Oracle

Found this small reference to the mutating trigger error.

The most likely cause of a mutating table error is the misuse of triggers. Here is a typical example:
  1. you insert a row in table A.
  2. A trigger on table A (for each row) executes a query on table A, for example to compute a summary column.
  3. Oracle throws an ORA-04091: table A is mutating, trigger/function may not see it
This is an expected and normal behaviour, Oracle wants to protect you from yourself since Oracle guarantees:
  • (i) that each statement is atomic (i.e will either fail or succeed completely)
  • (ii) that each statement sees a consistent view of the data
Most likely when you write this kind of trigger you would expect the query (2) to see the row inserted on (1). This would be in contradiction with both points above since the update is not finished yet (there could be more rows to be inserted).
Oracle could return the result consistent with a point in time just before the beginning of the statement but from most of the examples I have seen that try to implement this logic, people see a multi-row statement as a series of successive steps and expect the statement [2] to see the changes made by the previous steps. Oracle can not return the expected result and therefore throws the error.
If as I suspect the cause of the mutating table error is a trigger, one way to avoid the error is to move the logic out of the trigger into procedures.

Oracle MERGE Statement

It was introduced in Oracle 9i, to insert or update the data in a table conditionally. Its also called upsert.

It is faster as it reduces table scans.

Found this example where data from the hr table is merged with the employees table. Here we have MERGE INTO statement, instead of the usual INSERT INTO. And the table from which the new data is to be picked, is specified using USING keyword.

The next step is to specify the merge condition, based on which the data will be checked. 

When the condition will match, an update will be fired to update the employees table, otherwise if not matched, the data will be inserted into employees table.

MERGE INTO employees e
    USING hr h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)

    VALUES (h.emp_id, h.address);


MERGE statement enhancements in 10g
There are few additions done to make merge statement more flexible.
- Now, we can skip one of the MATCHED or NOT MATCHED blocks.
- a WHERE condition can also be added to the insert/update part.
- a DELETE statement can also be added to the insert/update part but only on the MATCHED block.

REF Cursor | Oracle

Using REF CURSORs (or cursor variable)is one of the most powerful, flexible, and scalable ways to return query results.

Its a datatype whose value is the memory address of a SQL query result. So, basically its a pointer to a result-set. It allows a user to pass the reference of this resultset among all the programs that need access to it.

Like a normal cursor, its data is accessible in the forward only direction. And also a REF CURSOR is read-only and its data cannot be updated.

TYPES
- Strong REF cursor
- Weak REF cursor

While declaring, if the return type of ref cursor is defined, it becomes a strong cursor.

TYPE emp_curs IS REF CURSOR
RETURNING emp%ROWTYPE;

And if the returning block, returns a ref cursor of a different type, then the one defined, it will raise a "ROWTYPE_MISMATCH" exception.

Diff between a cursor and REF cursor
At the basic level, they are both same. But a normal cursor is quite static in its definition, and its query cannot be changed. Whereas a REF cursor can be opened and used as per the requirement.

And a REF cursor can be passed across program blocks, but a normal cursor can't.

----------

A REF cursor is a variable , so it can be passed as parameter across program blocks.

TYPE emp_curs IS REF CURSOR
RETURNING emp%ROWTYPE;

se emp_curs;

Here the se is a variable of ref cursor type and it can be used for emp table records.


oracle-plsql-ref-cursors

24 September, 2015

Context Switching | Oracle

Context Switching – There is pl/sql engine for pl/sql code and sql engine for sql queries. Every time the control is passed between any of these two engines, its called context switching.

Context switching takes time and creates a delay in execution of the code. It’s a necessary requirement for the code, but too much switches will make the code work slow.

Ex- SELECT  emp_id,
       Dept_name(emp_id)
FROM emp
WHERE emp_id = v_id;


The above code is part of a procedure(plsql eng). When the code executes the query, the control is passed to (sql eng). While, executing query, the func dept_name is encountered and control is passed to (plsql eng). This function itself has a sql query to generate the department name and hence control goes to (sql eng) again. This is not a good practise and is not recommended. 

Oracle | DATA DICTIONARY

DATA DICTIONARY

-- set of read only tables, provide info about the database
-- contains - definition of all schema objects (tables, views, indexes, sequences, synonyms, functions, procs, packages, clusters etc.)
>> how much space is allocated to and is used by a schema object
>> integrity constraints
>> default values of the columns
>> names of the users, their privileges and roles
>> who accessed and updated which db object
>> other general db related info

data dictionary is structured in tables and views. It is stored in the SYSTEM tablespace of a database.

It consists of : BASE TABLES - which store all the db related info. user access to these tables is not advised, and only Oracle database should access these tables. Most info stored in these tables is in cryptic form.

USER-ACCESSIBLE VIEWS - summarize the info stored in BASE TABLES into userful informative views. Most of the views are intended for every user, but there are few which are for administrators only.
These views are grouped into 3 classes - 
DBA_ - These views have some additional info for database administrators
ALL_ - accessible to all users, contains objects to which the user has privileges
USER_ - accessible to all users, contains objects owned by the user

The system supplied view DICTIONARY has names and desc of all the data dictionary views.

******
select OBJECT_NAME from USER_OBJECTS
WHERE object_type = 'TABLE' 

This query will give the list of all the user tables in the schema.
******
select *  from ALL_OBJECTS
WHERE object_type = 'TABLE' 

This query will give all the tables , user created as well as Oracle supplied like DUAL.

Oracle PARTITIONS | Oracle

@@@@ PARTITIONS @@@@

It makes manging large tables & indexes management easy. Its done through a new type of storage structure called PARTIOTION.

A partition is an independent object; it may also have its independent storage characteristics.

However, from an application's perspective, there is just only one schema. No change is required for the DML statements.

IOTs can also be partitioned like a normal table.

BENEFITS - Increased availability, increased query performance for data warehouses, decreased contention for a single resource in OLTP systems, easy administration of schema objects(DDL)

Each partition should have the same logical attributes like column names, constraints; but they can have different logical attributes like tablespace to which it belongs.

PARTITION KEY - one or more columns which determine the partition to which a row of data will go. Ex- In a range partition, the date is the parameter on the basis of which we can partiition a table data.

PARTITIONING STRETEGIES - it defines the conditions based on which the data is partitioned. There are 3 available - RANGE, LIST and HASH.
RANGE - most common type, PARTITION BY RANGE(colname)
**database creates interval partitions for data beyond that transition point. Interval partitions extend range partitioning by instructing the database to create partitions of the specified range or interval automatically when data inserted into the table exceeds all of the range partitions. the SALES_2001 partition contains rows with partitioning key time_id values greater than or equal to 01-JAN-2001.
LIST - partitioning key is based on a set of values and based on those values , the data is partitioned. PARTITION colname VALUES (set of values)
HASH - hash algo is applied on the key to select the partition to which the data will be added. Useful for OLTP systems where high update contention is there. Increases availability. 
PARTITION BY HASH(colname)
you cannot specify to which partition what data should go, and oracle distributes the data evenly across all partitions.

PARTITIONED TABLES - 
partitioned table is different from a non-partitioned table. The normal table has its data allocated to table segment where as in case of partitioned tables, the data is allocated to partition segment. Each partition segment has a portion of data allocated to it.

PARTITIONED INDEXES - 
Like a partitioned table, the partitioned index is decomposed into smaller pieces. 
Global(B-Tree index) indexes are partitioned independent of their table where as local partitioned indexes are automatically linked to its table partition.

How to Load Data into Oracle | Fast Load

There are many ways to load data into Oracle -- Each of these processes varies in speed, simplicity, scalability, recoverability and data availability. There is no single best way to load data into Oracle and it varies with all the criterias mentioned above.

>>SQL*Loader
>>>>Data pump import and export
>>>>>>External tables


>>SQL*Loader >> Used when we have to load huge volumes of data into database from external sources, like a csv file.

It is used to load data from a single or multiple files in the same load session. We can also perform various data manipulations/ validations before loading. Selective load of data is also possible.

>>>>External tables >> They allow you to access tables outside the database, as they are actually present in the database. They are quite similar to how we use sql*loader. Its a convenient way to use sql*loader functionality. When an external table is queried, Oracle parses the flat file and provides data to the  user in such a manner as if the data is stored in the database itself.
The user can define the structure of the flat file and then SQL query is used to generate iska kaam.

>>Data pump import and export >> This utility is used to transport oracle objects between different Oracle databases, regardless of the hardware and software.

LISTAGG Aggregate Function | Oracle

LISTAGG Aggregate function @@@@

The function concatenates the results in a single row. Like if you want to check which covers exist for a transaction in the agreement table. Check out the following query :

select policy_no, trans_id, listagg(product_line_id,'-') within group (order by agr_line_seq_no desc) agg_data
from agreement_line
where 1=1 
and policy_no = 12345678  
group by policy_no, trans_id;

The data is grouped on the basis of policy and transaction number. The aggregate function will show the result as a concatenated string:

POLICY_NO TRANS_ID AGG_DATA
12345678 28310344 CAGUU-CAGIS-CAGIP-CAGIJ-CAGII-CAGIA-CAGFA-CAGPP
12345678 29437966 CAGUU-CAGIS-CAGIP-CAGIJ-CAGII-CAGIA-CAGFA-CAGPP
12345678 29456666 CAGUU-CAGIS-CAGIP-CAGIJ-CAGII-CAGIA-CAGFA-CAGPP


Order of execution of Triggers

Order of execution of Triggers

If 2 or more triggers are defined on the same statement of a table, then the order of execution of them is –

1. All before statement triggers
2. All before row triggers
3. All after row triggers
4. All after statement triggers

But, along with this, if we have 2 or more triggers defined at the same level, then we can also order their execution. Oracle has provided the FOLLOWS keyword for this.

22 September, 2015

Oracle Pseudocolumns | Oracle

Named pseudocolumns as they are not actually part of the table, so not actually stored in the table.

Data of these columns can only be selected, but cannot be inserted, updated or deleted.

Some of the pseudocolumns available in Oracle are:


  • Hierarchical Query Pseudocolumns
  • Sequence Pseudocolumns
  • Version Query Pseudocolumns
  • COLUMN_VALUE Pseudocolumn
  • OBJECT_ID Pseudocolumn
  • OBJECT_VALUE Pseudocolumn
  • ROWID Pseudocolumn
  • ROWNUM Pseudocolumn

1. Hierarchical Query Pseudocolumn :
                Used only in hierarchical queries. Examples - 
CONNECT_BY_ISCYCLE - returns 1 if the parent row is also the child row of the current row, otherwise it returns 0. This is used specifically for checking the following error

ERROR:
ORA-01436: CONNECT BY loop in user data



But it can only be used in the case when the CONNECT BY clause has used the NOCYCLE parameter.

Example reference for the cycle


CONNECT_BY_ISLEAF - returns 1 if the current row is the leaf of the tree defined in the CONNECT BY condition. Otherwise it returns 0.

LEVEL - returns data based on the level of the current row in the inverted tree. 1 for the root row, 2 for its child, 3 for the next child in the tree and so on.

2. Sequence Pseudocolumns :
            Sequence is a schema object which can generate unique sequential values. These values can be used for primary key of the table.
The CURRVAL and NEXTVAL are the pseudocolumns that are used for the sequence.

3. Version Query Pseudocolumns :
            Applicable only in the flashback queries, specifically flashback version queries. The pseudocolumns are:
  • VERSIONS_STARTTIME: Returns the timestamp of the first version of the rows returned by the query.
  • VERSIONS_STARTSCN: Returns the SCN of the first version of the rows returned by the query.
  • VERSIONS_ENDTIME: Returns the timestamp of the last version of the rows returned by the query.
  • VERSIONS_ENDSCN: Returns the SCN of the last version of the rows returned by the query.
  • VERSIONS_XID: For each version of each row, returns the transaction ID (a RAW number) of the transaction that created that row version.
  • VERSIONS_OPERATION: For each version of each row, returns a single character representing the operation that caused that row version. The values returned are I (for an insert operation), U (for an update operation) or D (for a delete operation).
4. COLUMN_VALUE pseudocolumn :
            Used when a virtual table is created using the TABLE function.

5. OBJECT_ID pseudocolumn :
            returns the object identifier of the column in object table or view. Used mostly when INSTEAD OF trigger is used for any view.

6. OBJECT_VALUE pseudocolumn :
           returns the system generated names of the columns used in object table.

7. ROWID pseudocolumn :
          contains the address of each row of the table. It is the fastest way to access a row in the database.

Usually each row in the database has a unique rowid value. However, the rows of different tables stored together in the same cluster can have same rowids.

It contains the following information required to locate a row:
a> data object number of the object
b> the datafile of the tablsespace in which the row resides
c> datablock in the datafile where the row is stored
d> inside that datablock, the position of the row. The first row is termed as position 0.

8. ROWNUM pseudocolumn : 
         ROW_NUMBER build-in SQL function provides a unique way to order the resultset. The ROWNUM column is used to order the resultset of a query. Each row is assigned a unique number in the order(1,2,3,4,5...)

If order by clause is used in the same query where rownum is used, the order by will force the results to be reordered. But if the order by is used in a sub-query and rownum is used in the top level query, the rownum will be used on the ordered data.


References:

Main Article

List of Topics | Oracle

List of topics :

The post contains the list of  all the common topics that should be covered while preparing for Oracle interiews.

The page will be updated constantly as new topics and subtopics will be added.

# Pseudocolumns

23 August, 2015

Oracle | Keywords | GROUP BY, ROLLUP and CUBE

This article is for knowing how some of the keywords in Oracle work:

1. GROUP BY - Group by clause allows us to group the data based on a column or a combination of columns. The main benefit of using this keyword is when we have to get the aggregated data.
Ex - We have to find the total number of employees working in different departments. The following query can be used for this.
SELECT dept_id, COUNT(emp_id) 
FROM department d, employee e 
WHERE e.dept_id = d.dept_id 
GROUP BY dept_id 
The same way we can use group by to get the sum or average of the salaries of different departments.
 

25 July, 2015

Oracle PL SQL | Pending Questions

1. The validity of a package depends upon the validity of the other database objects it references to; So if we try to create 2 packages which have dependency on each other, then how will that contention be resolved?

24 July, 2015

Oracle pointers - Part 001

Composite Index

In a composite index, the selected columns should be chosen wisely as this impacts the index performance. The more the columns of a composite index are used in the WHERE clause , the faster would be the execution. The rule is most commonly used column should do first in the composite index.

---------

Cardinality

This is the measure of distinct values of a set. And in terms of database, cardinality is defined as the number of distinct rows returned by a query.

-----------

HINTS -

ALL_ROWS- It instructs the optimizer to fetch the last row of the result-set as fast as possible. non-interactive, batch mode type of application would benefit from this.

FIRST_ROWS - It instructs the optimizer to fetch the first row to the client as fast as possible. An interactive, typical end-user application would benefit from it.

08 July, 2015

Oracle Collections : Introduction

A collection is an ordered group of elements which have the same data type and we use subscripts to actually access those elements.

There are three types of collections provided by Oracle:

  1. Index-by Tables / Associative Arrays
  2. Nested Table
  3. Variable size array / Varray

Index by Table / Associative Array
Each stored data unit is in the form of KEY-VALUE pair. The keys are unique and it can be either a string or an integer.

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY sucscript_type;

table_name type_name;

Below is an example showing how to use associatibe array:

TYPE salary IS TABLE OF NUMBER INDEX BY varchar2(20);
salary_list salary;

--Adding elements to this ass. array

salary_list('ram') = 15000;
salary_list('lakshman') = 7050;
salary_list('bharat') = 35000;
salary_list('shatrugan') = 5000;

--Now using the collection elements

name := salary_list.FIRST;
WHILE name IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE ('Salary of '||name||' is '||TO_CHAR(salary_list(name));

name := salary_list.NEXT(name);


END LOOP;

END;
/

Elements of a index-by table can be %ROWTYPE data of a database table; or it could be %TYPE of a single column of the table.


NESTED TABLES

Its like a one-dimensional array where the elements are stored with their subscript. 
But its not conventional type of array as the no. of elements in the nested table is unbound compared to normal array. And its also not as dense as arrays are because the elements keep on changing making it sparse.

The syntax of nested tables is similar to that of the index-by collection except the fact that nested tables do not use INDEX BY clause.

Nested tables can be stored in the database tables where as index-by doesn't.