Вы находитесь на странице: 1из 5

All About Oracle Synonym

Synonym : A synonym is an alias for table, stored procedure and other database objects.Main
use of synonym :
Hide Complexity :
If you have to access a object owned by another database user thenYou have to use syntax
Owner.Objectname every time to use that object. Instead of using cumbersome syntax every time
we can
create synonym for thatCreate Synonym Syn_Name for Owner.ObjectnameSuppose you have to
access Table Tab_Y owner by user User_Y .Before creating synonym you have to use
Select * from User_Y.Tab_Y
Now if we create a synonym
Create Synonym Tab_Y for User_Y.Tab_YAfter creating synonym you can use
Select * from Tab_Y
Note : The object does not need to exist at the time of its creation
Hide Owner/Location : In some applications application designers do not want to reveal the
owner and location of object to other user. To achieve this they create synonym
Type of synonym :
There are primarily two type of synonym
1. Private : Only owner of synonym can use private synonym By default synonym created is
private
Create Synonym Tab_Y for User_Y.Tab_Y .
2. Public : Everyone can use public synonym. Syntax for creating public synonym
Create Public Synonym Tab_Y for User_Y.Tab_Y .

Order of precedence for synonym :


There are lot of confusion when both object and synonym exist in database, which one will be
used first. Following is order of precedence
1. Local objects will always be accessed first.
2. If a local object does not exist, the object with a private synonym will be accessed.
3. If a private synonym does not exist or the object does not exist, then the public synonym will
be used.

Flip Side of using synonym :


1. There are security issues related with public synonym
2. If there are lot of synonym in database then database performance will degrade i.e. suppose
user want to query Tab_A in above mentioned example database parser have to go across large
set of synonym and have to put each synonym in library cache along with dependency.
Alternative to using synonyms:
Use logon trigger to set ALTER SESSION SET CURRENT_SCHEMA This will make default
schema for unqualified object
create or replace trigger trg_at_logon on database after logonbegin
if user in ('X','Y') then execute immediate 'alter session set current_schema=DFLT;
end if
end;
now if user X,Y login their default schema for unqualified object will be DFLT
Misc point about synonym :
We cannot use Drop and truncate command with synonym
Removing Synonyms :
We can use following syntax to drop private synonym
Drop synonym syn_name
To drop public synonnynm
Drop Public synonym syn_name
We can also use force command
Drop synonym syn_name force
The force syntax will force Oracle to drop the synonym even if it has dependencies. It is not a
good idea to use the force phrase as it can cause invalidation of Oracle objects.
Query to find Synonym use in database :
Suppose we want to object that reference synonynm test_syn
Select owner, name, type
From dba_dependencies
Where referenced_name ='TEST_SYN'and referenced_type ='SYNONYM'

Common Error with Synonym :


One of the most common error encountered with synonynm is"ORA-00980: synonym translation
is no longer valid"
Main causes for this to happen are
1. One has created a synonym on non-existing object by mistake.
2. You dropped an object but did not drop the synonyms which are referencing the object.

PL/SQL Collections

PL/SQL RECORD:
A record is a group of related data items stored in fields, each with its own name and datatype.
Suppose you have various data about an employee such as name, salary, and hire date. These
items are logically related but dissimilar in type. A record containing a field for each item lets
you treat the data as a logical unit. Thus, records make it easier to organize and represent
information.

The attribute %ROWTYPE lets you declare a record that represents a row in a database table.
However, you cannot specify the datatypes of fields in the record or declare fields of your own.
The datatype RECORD lifts those restrictions and lets you define your own records.
Manipulating Records
The datatype RECORD letxs you collect information about the attributes of something.
The information is easy to manipulate because you can refer to the collection as a whole.

In the following example, you collect accounting figures from database tables assets and
liabilities, then use ratio analysis to compare the performance of two subsidiary companies:

DECLARE
TYPE FiguresRec IS RECORD (cash REAL, notes REAL, ...);
Sub1_figs FiguresRec;
Sub2_figs FiguresRec;

FUNCTION acid_test (figs FiguresRec) RETURN REAL IS...


BEGIN
SELECT cash, notes ... INTO sub1_figs FROM assets, liabilities
WHERE assets.sub = 1 AND liabilities.sub = 1;

SELECT cash, notes ... INTO sub2_figs FROM assets, liabilities


WHERE assets.sub = 2 AND liabilities.sub = 2;

IF acid_test (sub1_figs) > acid_test (sub2_figs) THEN...


...
END;

Notice how easy it is to pass the collected figures to the function acid_test, which computes a
financial ratio.
----------------------------------------------------------------------------------------------
In the example below, you fetch rows from database table flights into record flight_info. That
way, you can treat all the information about a flight, including its passenger list, as a logical unit.

DECLARE
TYPE FlightRec IS RECORD (
flight_no NUMBER(3), gate CHAR(5), departure CHAR(15), arrival CHAR(15),
passengers PassengerList);

flight_info FlightRec;
CURSOR c1 IS SELECT * FROM flights;
seat_not_available EXCEPTION;

BEGIN
OPEN c1;
LOOP
FETCH c1 INTO flight_info;
EXIT WHEN c1%NOTFOUND;
FOR i IN 1...FLIGHT_info.passengers.LAST LOOP
IF flight_INFO.PASSENGERS (i).seat = NA THEN
dbms_output.put_LINE (flight_INFO.PASSENGERS (i).name);
RAISE seat_not_available;
END IF;
...
END LOOP;
END LOOP;
CLOSE c1;
EXCEPTION
WHEN seat_not_available THEN
...
END;

PL/SQL TABLE:
In the example below, with each iteration of the loop, the FETCH statement fetches ten rows (or
less) into index-by table empnos. The previous values are overwritten.

DECLARE
TYPE NumTab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
CURSOR c1 IS SELECT empno FROM emp;
empnos NumTab;
rows NATURAL := 10;
BEGIN
OPEN c1;
LOOP
/* The following statement fetches 10 rows (or less). */
FETCH c1 BULK COLLECT INTO empnos LIMIT rows;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;
CLOSE c1;
END;

BULK COLLECT / FORALL / DYNAMIC SQL:

CREATE OR REPLACE PROCEDURE bulkcollect_9i_demo (whr_in IN VARCHAR2 :=


NULL)
IS
TYPE numlist_t IS TABLE OF NUMBER;
TYPE namelist_t IS TABLE OF VARCHAR2 (100);
-- New Oracle9i pre-defined REF CURSOR type. This is equivalent to:
-- TYPE sys_refcursor IS REF CURSOR
emp_cv sys_refcursor;
empnos numlist_t;
enames namelist_t;
enames_updated namelist_t;
ename_filter namelist_t := namelist_t ('S%', 'E%', 'M%');
sals numlist_t;
l_count PLS_INTEGER;

bulk_errors EXCEPTION;
PRAGMA EXCEPTION_INIT ( bulk_errors, -24381 );
BEGIN
-- Bulk fetch with cursor variable
OPEN emp_cv FOR 'SELECT empno, ename FROM emp WHERE ' NVL (whr_in, '1=1');
FETCH emp_cv BULK COLLECT INTO empnos, enames;
CLOSE emp_cv;

-- Bulk fetch with "implicit cursor"


EXECUTE IMMEDIATE 'SELECT sal FROM emp WHERE ' NVL (whr_in, '1=1')
BULK COLLECT INTO sals;
Dbms_Output.put_line (sals.COUNT);

-- Bulk, dynamic UPDATE


FORALL indx IN empnos.FIRST .. empnos.LAST
EXECUTE IMMEDIATE
'UPDATE emp SET sal = sal * 1.1 WHERE empno = :employee_key '
'RETURNING ename INTO :names_updated'
USING empnos(indx) -- Must specify individual row with FORALL index
RETURNING BULK COLLECT INTO enames_updated; -- Specify collection as whole

-- Using SQL%BULK_ROWCOUNT: how many rows modified by each statement?


FORALL indx IN ename_filter.FIRST .. ename_filter.LAST
EXECUTE IMMEDIATE
'UPDATE emp SET sal = sal * 1.1
WHERE ename LIKE :employee_filter'
USING ename_filter(indx);

FOR indx IN ename_filter.FIRST .. ename_filter.LAST


LOOP
DBMS_OUTPUT.PUT_LINE (
'Number of employees with names like "'
ename_filter(indx)
'" given a raise: ' SQL%BULK_ROWCOUNT(indx));
END LOOP;
END;
/

Вам также может понравиться