Anda di halaman 1dari 47

PL/SQL - Procedures

A subprogram is a program unit/module that performs a


particular task. These subprograms are combined to form larger
programs. This is basically called the 'Modular design'. A
subprogram can be invoked by another subprogram or program
which is called the calling program.
A subprogram can be created:
At schema level
Inside a package
Inside a PL/SQL block
A schema level subprogram is a standalone subprogram. It is
created with the CREATE PROCEDURE or CREATE FUNCTION
statement. It is stored in the database and can be deleted with
the DROP PROCEDURE or DROP FUNCTION statement.
A subprogram created inside a package is a packaged
subprogram. It is stored in the database and can be deleted only
when the package is deleted with the DROP PACKAGE statement.
We will discuss packages in the chapter 'PL/SQL - Packages'.
PL/SQL subprograms are named PL/SQL blocks that can be
invoked with a set of parameters. PL/SQL provides two kinds of
subprograms:
Functions: these subprograms return a single value, mainly
used to compute and return a value.
Procedures: these subprograms do not return a value
directly, mainly used to perform an action.
This chapter is going to cover important aspects of a PL/SQL
procedure and we will cover PL/SQL function in next chapter.
Parts of a PL/SQL Subprogram

Each PL/SQL subprogram has a name, and may have a parameter


list. Like anonymous PL/SQL blocks and, the named blocks a
subprograms will also have following three parts:
S.
N.

Parts & Description

Declarative Part
It is an optional part. However, the declarative part for a
subprogram does not start with the DECLARE keyword. It
contains declarations of types, cursors, constants,
variables, exceptions, and nested subprograms. These
items are local to the subprogram and cease to exist
when the subprogram completes execution.

Executable Part
This is a mandatory part and contains statements that
perform the designated action.

Exception-handling
This is again an optional part. It contains the code that
handles run-time errors.

Creating a Procedure
A procedure is created with the CREATE OR REPLACE PROCEDURE
statement. The simplified syntax for the CREATE OR REPLACE
PROCEDURE statement is as follows:
CREATE [OR REPLACE] PROCEDURE procedure_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])]
{IS | AS}
BEGIN
< procedure_body >

END procedure_name;
Where,
procedure-name specifies the name of the procedure.
[OR REPLACE] option allows modifying an existing procedure.
The optional parameter list contains name, mode and types
of the parameters. IN represents that value will be passed
from outside and OUT represents that this parameter will be
used to return a value outside of the procedure.
procedure-body contains the executable part.
The AS keyword is used instead of the IS keyword for
creating a standalone procedure.
Example:
The following example creates a simple procedure that displays
the string 'Hello World!' on the screen when executed.
CREATE OR REPLACE PROCEDURE greetings
AS
BEGIN
dbms_output.put_line('Hello World!');
END;
/
When above code is executed using SQL prompt, it will produce
the following result:
Procedure created.
Executing a Standalone Procedure
A standalone procedure can be called in two ways:
Using the EXECUTE keyword

Calling the name of the procedure from a PL/SQL block


The above procedure named 'greetings' can be called with the
EXECUTE keyword as:
EXECUTE greetings;
The above call would display:
Hello World
PL/SQL procedure successfully completed.
The procedure can also be called from another PL/SQL block:
BEGIN
greetings;
END;
/
The above call would display:
Hello World
PL/SQL procedure successfully completed.
Deleting a Standalone Procedure
A standalone procedure is deleted with the DROP PROCEDURE
statement. Syntax for deleting a procedure is:
DROP PROCEDURE procedure-name;
So you can drop greetings procedure by using the following
statement:
DROP PROCEDURE greetings;
Parameter Modes in PL/SQL Subprograms
S.

Parameter Mode & Description

N.
1

IN
An IN parameter lets you pass a value to the
subprogram. It is a read-only parameter. Inside the
subprogram, an IN parameter acts like a constant. It
cannot be assigned a value. You can pass a constant,
literal, initialized variable, or expression as an IN
parameter. You can also initialize it to a default value;
however, in that case, it is omitted from the subprogram
call. It is the default mode of parameter passing.
Parameters are passed by reference.

OUT
An OUT parameter returns a value to the calling
program. Inside the subprogram, an OUT parameter acts
like a variable. You can change its value and reference
the value after assigning it. The actual parameter
must be variable and it is passed by value.

IN OUT
An IN OUT parameter passes an initial value to a
subprogram and returns an updated value to the caller. It
can be assigned a value and its value can be read.
The actual parameter corresponding to an IN OUT formal
parameter must be a variable, not a constant or an
expression. Formal parameter must be assigned a
value. Actual parameter is passed by value.

IN & OUT Mode Example 1


This program finds the minimum of two values, here procedure
takes two numbers using IN mode and returns their minimum
using OUT parameters.

DECLARE
a number;
b number;
c number;
PROCEDURE findMin(x IN number, y IN number, z OUT number) IS
BEGIN
IF x < y THEN
z:= x;
ELSE
z:= y;
END IF;
END;
BEGIN
a:= 23;
b:= 45;
findMin(a, b, c);
dbms_output.put_line(' Minimum of (23, 45) : ' || c);
END;
/
When the above code is executed at SQL prompt, it produces the
following result:
Minimum of (23, 45) : 23

PL/SQL procedure successfully completed.


IN & OUT Mode Example 2
This procedure computes the square of value of a passed value.
This example shows how we can use same parameter to accept a
value and then return another result.
DECLARE
a number;
PROCEDURE squareNum(x IN OUT number) IS
BEGIN
x := x * x;
END;
BEGIN
a:= 23;
squareNum(a);
dbms_output.put_line(' Square of (23): ' || a);
END;
/
When the above code is executed at SQL prompt, it produces the
following result:
Square of (23): 529
PL/SQL procedure successfully completed.
Methods for Passing Parameters
Actual parameters could be passed in three ways:
Positional notation
Named notation

Mixed notation
POSITIONAL NOTATION
In positional notation, you can call the procedure as:
findMin(a, b, c, d);
In positional notation, the first actual parameter is substituted for
the first formal parameter; the second actual parameter is
substituted for the second formal parameter, and so on. So, a is
substituted for x, b is substituted for y, c is substituted for z and d
is substituted for m.
NAMED NOTATION
In named notation, the actual parameter is associated with the
formal parameter using the arrow symbol ( => ). So the
procedure call would look like:
findMin(x=>a, y=>b, z=>c, m=>d);
MIXED NOTATION
In mixed notation, you can mix both notations in procedure call;
however, the positional notation should precede the named
notation.
The following call is legal:
findMin(a, b, c, m=>d);
But this is not legal:
findMin(x=>a, b, c, d);
.FUNCTION
..
A PL/SQL function is same as a procedure except that it returns a
value. Therefore, all the discussions of the previous chapter are
true for functions too.
Creating a Function

A standalone function is created using the CREATE FUNCTION


statement. The simplified syntax for the CREATE OR REPLACE
PROCEDURE statement is as follows:
CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])]
RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
END [function_name];
Where,
function-name specifies the name of the function.
[OR REPLACE] option allows modifying an existing function.
The optional parameter list contains name, mode and types of the
parameters. IN represents that value will be passed from outside
and OUT represents that this parameter will be used to return a
value outside of the procedure.
The function must contain a return statement.
RETURN clause specifies that data type you are going to return
from the function.

function-body contains the executable part.


The AS keyword is used instead of the IS keyword for creating a
standalone function.
Example:
The following example illustrates creating and calling a
standalone function. This function returns the total number of
CUSTOMERS in the customers table. We will use the CUSTOMERS
table, which we had created in PL/SQL Variables chapter:
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME

| AGE | ADDRESS | SALARY |

+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi
| 3 | kaushik | 23 | Kota
| 4 | Chaitali | 25 | Mumbai
| 5 | Hardik | 27 | Bhopal
| 6 | Komal

| 22 | MP

| 1500.00 |
| 2000.00 |
| 6500.00 |
| 8500.00 |
| 4500.00 |

+----+----------+-----+-----------+----------+
CREATE OR REPLACE FUNCTION totalCustomers
RETURN number IS
total number(2) := 0;

BEGIN
SELECT count(*) into total
FROM customers;
RETURN total;
END;
/
When above code is executed using SQL prompt, it will produce
the following result:
Function created.
Calling a Function
While creating a function, you give a definition of what the
function has to do. To use a function, you will have to call that
function to perform the defined task. When a program calls a
function, program control is transferred to the called function.
A called function performs defined task and when its return
statement is executed or when it last end statement is reached, it
returns program control back to the main program.
To call a function you simply need to pass the required
parameters along with function name and if function returns a
value then you can store returned value. Following program calls
the function totalCustomers from an anonymous block:
DECLARE
c number(2);

BEGIN
c := totalCustomers();
dbms_output.put_line('Total no. of Customers: ' || c);
END;
/
When the above code is executed at SQL prompt, it produces the
following result:
Total no. of Customers: 6
PL/SQL procedure successfully completed.
Example:
The following is one more example which demonstrates Declaring,
Defining, and Invoking a Simple PL/SQL Function that computes
and returns the maximum of two values.
DECLARE
a number;
b number;
c number;
FUNCTION findMax(x IN number, y IN number)
RETURN number
IS
z number;
BEGIN
IF x > y THEN

z:= x;
ELSE
Z:= y;
END IF;
RETURN z;
END;
BEGIN
a:= 23;
b:= 45;
c := findMax(a, b);
dbms_output.put_line(' Maximum of (23,45): ' || c);
END;
/
When the above code is executed at SQL prompt, it produces the
following result:
Maximum of (23,45): 45
PL/SQL procedure successfully completed.
PL/SQL Recursive Functions
We have seen that a program or subprogram may call another
subprogram. When a subprogram calls itself, it is referred to as a
recursive call and the process is known as recursion.

To illustrate the concept, let us calculate the factorial of a number.


Factorial of a number n is defined as:
n! = n*(n-1)!
= n*(n-1)*(n-2)!
...
= n*(n-1)*(n-2)*(n-3)... 1
The following program calculates the factorial of a given number
by calling itself recursively:
DECLARE
num number;
factorial number;
FUNCTION fact(x number)
RETURN number
IS
f number;
BEGIN
IF x=0 THEN
f := 1;
ELSE
f := x * fact(x-1);
END IF;
RETURN f;
END;

BEGIN
num:= 6;
factorial := fact(num);
dbms_output.put_line(' Factorial '|| num || ' is ' || factorial);
END;
/
When the above code is executed at SQL prompt, it produces the
following result:
Factorial 6 is 720 (PL/SQL procedure successfully completed.)

Packages
PL/SQL packages are schema objects that groups logically related PL/SQL
types, variables and subprograms.
A package will have two mandatory parts:

Package specification

Package body or definition

Package Specification
The specification is the interface to the package. It just DECLARES the types,
variables, constants, exceptions, cursors, and subprograms that can be
referenced from outside the package. In other words, it contains all
information about the content of the package, but excludes the code for the
subprograms.
All objects placed in the specification are called public objects. Any
subprogram not in the package specification but coded in the package body
is called aprivate object.
The following code snippet shows a package specification having a single
procedure. You can have many global variables defined and multiple
procedures or functions inside a package.
CREATE PACKAGE cust_sal AS

PROCEDURE find_sal(c_id customers.id%type);


END cust_sal;
/
When the above code is executed at SQL prompt, it produces the following
result:
Package created.
Package Body
The package body has the codes for various methods declared in the
package specification and other private declarations, which are hidden from
code outside the package.
The CREATE PACKAGE BODY Statement is used for creating the package
body. The following code snippet shows the package body declaration for
the cust_salpackage created above. I assumed that we already have
CUSTOMERS table created in our database as mentioned in PL/SQL Variables chapter.
CREATE OR REPLACE PACKAGE BODY cust_sal AS
PROCEDURE find_sal(c_id customers.id%TYPE) IS
c_sal customers.salary%TYPE;
BEGIN
SELECT salary INTO c_sal
FROM customers
WHERE id = c_id;
dbms_output.put_line('Salary: '|| c_sal);
END find_sal;
END cust_sal;
/
When the above code is executed at SQL prompt, it produces the following
result:
Package body created.
Using the Package Elements

The package elements (variables, procedures or functions) are accessed with


the following syntax:
package_name.element_name;
Consider, we already have created above package in our database schema,
the following program uses the find_sal method of the cust_sal package:
DECLARE
code customers.id%type := &cc_id;
BEGIN
cust_sal.find_sal(code);
END;
/
When the above code is executed at SQL prompt, it prompt to enter
customer ID and when you enter an ID, it displays corresponding salary as
follows:
Enter value for cc_id: 1
Salary: 3000

PL/SQL procedure successfully completed.


Example:
The following program provides a more complete package. We will use the
CUSTOMERS table stored in our database with the following records:
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME

| AGE | ADDRESS | SALARY |

+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 3000.00 |
| 2 | Khilan | 25 | Delhi
| 3 | kaushik | 23 | Kota
| 4 | Chaitali | 25 | Mumbai

| 3000.00 |
| 3000.00 |
| 7500.00 |

| 5 | Hardik | 27 | Bhopal
| 6 | Komal

| 22 | MP

| 9500.00 |
| 5500.00 |

+----+----------+-----+-----------+----------+
THE PACKAGE SPECIFICATION:
CREATE OR REPLACE PACKAGE c_package AS
-- Adds a customer
PROCEDURE addCustomer(c_id customers.id%type,
c_name customers.name%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type);

-- Removes a customer
PROCEDURE delCustomer(c_id customers.id%TYPE);
--Lists all customers
PROCEDURE listCustomer;

END c_package;
/
When the above code is executed at SQL prompt, it creates the above
package and displays the following result:
Package created.
CREATING THE PACKAGE BODY:
CREATE OR REPLACE PACKAGE BODY c_package AS
PROCEDURE addCustomer(c_id customers.id%type,
c_name customers.name%type,
c_age customers.age%type,
c_addr customers.address%type,

c_sal customers.salary%type)
IS
BEGIN
INSERT INTO customers (id,name,age,address,salary)
VALUES(c_id, c_name, c_age, c_addr, c_sal);
END addCustomer;

PROCEDURE delCustomer(c_id customers.id%type) IS


BEGIN
DELETE FROM customers
WHERE id = c_id;
END delCustomer;

PROCEDURE listCustomer IS
CURSOR c_customers is
SELECT name FROM customers;
TYPE c_list is TABLE OF customers.name%type;
name_list c_list := c_list();
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line('Customer(' ||counter|| ')'||name_list(counter));
END LOOP;
END listCustomer;
END c_package;

/
Above example makes use of nested table which we will discuss in the next
chapter. When the above code is executed at SQL prompt, it produces the
following result:
Package body created.
USING THE PACKAGE:
The following program uses the methods declared and defined in the
packagec_package.
DECLARE
code customers.id%type:= 8;
BEGIN
c_package.addcustomer(7, 'Rajnish', 25, 'Chennai', 3500);
c_package.addcustomer(8, 'Subham', 32, 'Delhi', 7500);
c_package.listcustomer;
c_package.delcustomer(code);
c_package.listcustomer;
END;
/
When the above code is executed at SQL prompt, it produces the following
result:
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
Customer(8): Subham
Customer(1): Ramesh

Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish

TRIGGER

Triggers are stored programs, which are automatically executed or fired when
some events occur. Triggers are, in fact, written to be executed in response
to any of the following events:

A database manipulation (DML) statement (DELETE, INSERT, or


UPDATE).

A database definition (DDL) statement (CREATE, ALTER, or DROP).

A database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or


SHUTDOWN).

Triggers could be defined on the table, view, schema, or database with which
the event is associated.
Benefits of Triggers
Triggers can be written for the following purposes:

Generating some derived column values automatically

Enforcing referential integrity

Event logging and storing information on table access

Auditing

Synchronous replication of tables

Imposing security authorizations

Preventing invalid transactions

Creating Triggers
The syntax for creating a trigger is:

CREATE [OR REPLACE ] TRIGGER trigger_name


{BEFORE | AFTER | INSTEAD OF }
{INSERT [OR] | UPDATE [OR] | DELETE}
[OF col_name]
ON table_name
[REFERENCING OLD AS o NEW AS n]
[FOR EACH ROW]
WHEN (condition)
DECLARE
Declaration-statements
BEGIN
Executable-statements
EXCEPTION
Exception-handling-statements
END;
Where,

CREATE [OR REPLACE] TRIGGER trigger_name: Creates or replaces an


existing trigger with the trigger_name.

{BEFORE | AFTER | INSTEAD OF} : This specifies when the trigger


would be executed. The INSTEAD OF clause is used for creating trigger
on a view.

{INSERT [OR] | UPDATE [OR] | DELETE}: This specifies the DML


operation.

[OF col_name]: This specifies the column name that would be updated.

[ON table_name]: This specifies the name of the table associated with
the trigger.

[REFERENCING OLD AS o NEW AS n]: This allows you to refer new and
old values for various DML statements, like INSERT, UPDATE, and
DELETE.

[FOR EACH ROW]: This specifies a row level trigger, i.e., the trigger
would be executed for each row being affected. Otherwise the trigger
will execute just once when the SQL statement is executed, which is
called a table level trigger.

WHEN (condition): This provides a condition for rows for which the
trigger would fire. This clause is valid only for row level triggers.

Example:
To start with, we will be using the CUSTOMERS table we had created and
used in the previous chapters:
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME

| AGE | ADDRESS | SALARY |

+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi
| 3 | kaushik | 23 | Kota
| 4 | Chaitali | 25 | Mumbai
| 5 | Hardik | 27 | Bhopal
| 6 | Komal

| 22 | MP

| 1500.00 |
| 2000.00 |
| 6500.00 |
| 8500.00 |
| 4500.00 |

+----+----------+-----+-----------+----------+
The following program creates a row level trigger for the customers table
that would fire for INSERT or UPDATE or DELETE operations performed on the
CUSTOMERS table. This trigger will display the salary difference between the
old values and new values:
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number;

BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
/
When the above code is executed at SQL prompt, it produces the following
result:
Trigger created.
Here following two points are important and should be noted carefully:

OLD and NEW references are not available for table level triggers,
rather you can use them for record level triggers.

If you want to query the table in the same trigger, then you should use
the AFTER keyword, because triggers can query the table or change it
again only after the initial changes are applied and the table is back in
a consistent state.

Above trigger has been written in such a way that it will fire before any
DELETE or INSERT or UPDATE operation on the table, but you can write
your trigger on a single or multiple operations, for example BEFORE
DELETE, which will fire whenever a record will be deleted using DELETE
operation on the table.

Triggering a Trigger
Let us perform some DML operations on the CUSTOMERS table. Here is one
INSERT statement, which will create a new record in the table:
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (7, 'Kriti', 22, 'HP', 7500.00 );
When a record is created in CUSTOMERS table, above create
triggerdisplay_salary_changes will be fired and it will display the following
result:
Old salary:
New salary: 7500

Salary difference:
Because this is a new record so old salary is not available and above result is
coming as null. Now, let us perform one more DML operation on the
CUSTOMERS table. Here is one UPDATE statement, which will update an
existing record in the table:
UPDATE customers
SET salary = salary + 500
WHERE id = 2;
When a record is updated in CUSTOMERS table, above create
triggerdisplay_salary_changes will be fired and it will display the following
result:
Old salary: 1500
New salary: 2000
Salary difference: 500

.PL/SQL DATABASE

OBJECT
The Role of Abstraction
An abstraction is a high-level description or model of a real-world entity.
Abstractions keep our daily lives manageable by suppressing irrelevant
detail. For example, to drive a car, you need not know how its engine works.
A simple interface consisting of a gearshift, steering wheel, accelerator, and
brake, lets you use the car effectively. The details of what happens under the
hood are not important for day-to-day driving.
Abstractions are central to the discipline of programming. For example, you
use procedural abstraction when you hide the details of a complex
algorithm by writing a procedure and passing it parameters. To try a different
implementation, you simply replace the body of the procedure. Thanks to
abstraction, programs that call the procedure need not be modified.
You use data abstraction when you specify the datatype of a variable. The
datatype represents a set of values and a set of operations appropriate for
those values. For instance, a variable of type POSITIVE can hold only positive
integers, and can only be added, subtracted, multiplied, and so on. To use
the variable, you do not need to know how PL/SQL stores integers or
implements arithmetic operations.

Object types are a generalization of the built-in datatypes found in most


programming languages. PL/SQL provides a variety of built-in scalar and
composite datatypes, each of which is associated with a set of predefined
operations. A scalartype (such as CHAR) has no internal components.
A composite type (such as RECORD) has internal components that can be
manipulated individually. Like the RECORD type, an object type is a
composite type. However, its operations are user-defined, not predefined.
Currently, you cannot define object types within PL/SQL. They must
be CREATEd and stored in an Oracle database, where they can be shared by
many programs. A program that uses object types is called a client
program. It can declare and manipulate an object without knowing how the
object type represents data or implements operations. This lets you write the
program and object type separately, and to change the implementation of
the object type without affecting the program. Thus, object types support
both procedural and data abstraction.
What Is an Object Type?
An object type is a user-defined composite datatype that encapsulates a
data structure along with the functions and procedures needed to
manipulate the data. The variables that form the data structure are
called attributes. The functions and procedures that characterize the
behavior of the object type are called methods.
We usually think of an object (such as a person, car, or bank account) as
having attributes and behaviors. For example, a baby has the attributes
gender, age, and weight, and the behaviors eat, drink, and sleep. Object
types let you maintain this perspective when you sit down to write an
application.
When you define an object type using the CREATE TYPE statement, you
create an abstract template for some real-world object. The template
specifies only those attributes and behaviors the object will need in the
application environment. For example, an employee has many attributes, but
usually only a few are needed to fill the requirements of an application
(see Figure 10-1).
Figure 10-1 Each Application Uses a Subset of Object Attributes

Text description of the illustration pls81020_form_follows_function.gif

Suppose you must write a program to allocate employee bonuses. Not all
employee attributes are needed to solve this problem. So, you design an
abstract employee who has the following problem-specific attributes: name,
ID number, department, job title, salary, and rank. Then, you identify the
operations needed to handle an abstract employee. For example, you need
an operation that lets Management change the rank of an employee.
Next, you define a set of variables (attributes) to represent the data, and a
set of subprograms (methods) to perform the operations. Finally, you
encapsulate the attributes and methods in an object type.
The data structure formed by the set of attributes is public (visible to client
programs). However, well-behaved programs do not manipulate it directly.
Instead, they use the set of methods provided. That way, the employee data
is kept in a proper state.
At run time, when the data structure is filled with values, you have created
an instance of an abstract employee. You can create as many instances
(usually called objects) as you need. Each object has the name, number, job
title, and so on of an actual employee (see Figure 10-2). This data is
accessed or changed only by the methods associated with it. Thus, object
types let you create objects with well-defined attributes and behavior.
Figure 10-2 Object Type and Objects (Instances) of that Type

Text description of the illustration pls81021_object_type_and_objects.gif

Why Use Object Types?


Object types reduce complexity by breaking down a large system into logical
entities. This lets you create software components that are modular,
maintainable, and reusable. It also allows different teams of programmers to
develop software components concurrently.
By encapsulating operations with data, object types let you move datamaintenance code out of SQL scripts and PL/SQL blocks into methods. Object
types minimize side effects by allowing access to data only through
approved operations. Also, object types hide implementation details, so that
you can change the details without affecting client programs.
Object types allow for realistic data modeling. Complex real-world entities
and relationships map directly into object types. Moreover, object types map
directly into classes defined in object-oriented languages such as Java and
C++. Now your programs can better reflect the world they are trying to
simulate.
Structure of an Object Type
Like a package, an object type has two parts: a specification and a body
(refer to Figure 10-3). The specification (or spec for short) is the interface
to your applications; it declares a data structure (set of attributes) along with

the operations (methods) needed to manipulate the data. The body fully
defines the methods, and so implements the spec.
Figure 10-3 Object Type Structure

Text description of the illustration pls81022_object_type_structure.gif

All the information a client program needs to use the methods is in the spec.
Think of the spec as an operational interface and of the body as a black box.
You can debug, enhance, or replace the body without changing the spec--and
without affecting client programs.
In an object type spec, all attributes must be declared before any methods.
Only subprograms have an underlying implementation. So, if an object type
spec declares only attributes, the object type body is unnecessary. You
cannot declare attributes in the body. All declarations in the object type spec
are public (visible outside the object type).
To understand the structure better, study the example below, in which an
object type for complex numbers is defined. For now, it is enough to know
that a complex number has two parts, a real part and an imaginary part, and
that several arithmetic operations are defined for complex numbers.
CREATE TYPE Complex AS OBJECT (
rpart REAL, -- attribute
ipart REAL,
MEMBER FUNCTION plus (x Complex) RETURN Complex, -- method
MEMBER FUNCTION less (x Complex) RETURN Complex,
MEMBER FUNCTION times (x Complex) RETURN Complex,
MEMBER FUNCTION divby (x Complex) RETURN Complex
);

CREATE TYPE BODY Complex AS


MEMBER FUNCTION plus (x Complex) RETURN Complex IS
BEGIN
RETURN Complex(rpart + x.rpart, ipart + x.ipart);
END plus;

MEMBER FUNCTION less (x Complex) RETURN Complex IS


BEGIN
RETURN Complex(rpart - x.rpart, ipart - x.ipart);
END less;

MEMBER FUNCTION times (x Complex) RETURN Complex IS


BEGIN
RETURN Complex(rpart * x.rpart - ipart * x.ipart,
rpart * x.ipart + ipart * x.rpart);
END times;

MEMBER FUNCTION divby (x Complex) RETURN Complex IS


z REAL := x.rpart**2 + x.ipart**2;
BEGIN
RETURN Complex((rpart * x.rpart + ipart * x.ipart) / z,
(ipart * x.rpart - rpart * x.ipart) / z);
END divby;
END;
Components of an Object Type
An object type encapsulates data and operations. You can declare attributes
and methods in an object type spec, but not constants, exceptions, cursors,
or types. You must declare at least one attribute (the maximum is 1000).
Methods are optional.

Attributes
Like a variable, an attribute is declared with a name and datatype. The name
must be unique within the object type (but can be reused in other object
types). The datatype can be any Oracle type except:

LONG and LONG RAW

ROWID and UROWID

The PL/SQL-specific types BINARY_INTEGER (and its


subtypes), BOOLEAN, PLS_INTEGER, RECORD, REF CURSOR, %TYPE,
and %ROWTYPE

Types defined inside a PL/SQL package

You cannot initialize an attribute in its declaration using the assignment


operator or DEFAULT clause. Also, you cannot impose
the NOT NULL constraint on an attribute. However, objects can be stored in
database tables on which you can impose constraints.
The kind of data structure formed by a set of attributes depends on the realworld object being modeled. For example, to represent a rational number,
which has a numerator and a denominator, you need only
two INTEGER variables. On the other hand, to represent a college student,
you need several VARCHAR2 variables to hold a name, address, phone
number, status, and so on, plus a VARRAY variable to hold courses and
grades.
The data structure can be very complex. For example, the datatype of an
attribute can be another object type (called a nested object type). That lets
you build a complex object type from simpler object types. Some object
types such as queues, lists, and trees are dynamic, meaning that they can
grow as they are used. Recursive object types, which contain direct or
indirect references to themselves, allow for highly sophisticated data models.
Methods
In general, a method is a subprogram declared in an object type spec using
the keyword MEMBER or STATIC. The method cannot have the same name as
the object type or any of its attributes. MEMBER methods are invoked on
instances, as in
instance_expression.method()

However, STATIC methods are invoked on the object type, not its instances,
as in
object_type_name.method()

Like packaged subprograms, methods have two parts: a specification and a


body. The specification (spec for short) consists of a method name, an
optional parameter list, and, for functions, a return type. The body is the
code that executes to perform a specific task.
For each method spec in an object type spec, there must either be a
corresponding method body in the object type body, or the method must be
declared NOT INSTANTIABLE to indicate that the body is only present in
subtypes of this type. To match method specs and bodies, the PL/SQL
compiler does a token-by-token comparison of their headers. The headers
must match exactly.
Like an attribute, a formal parameter is declared with a name and datatype.
However, the datatype of a parameter cannot be size-constrained. The
datatype can be any Oracle type except those disallowed for attributes.
(See "Attributes".) The same restrictions apply to return types.
Allowed Languages for Methods
Oracle lets you implement object methods in PL/SQL, Java or C. You can
implement type methods in Java or C by providing a call specification in your
type. A call spec publishes a Java method or external C function in the Oracle
data dictionary. It publishes the routine by mapping its name, parameter
types, and return type to their SQL counterparts. To learn how to write Java
call specs, see Oracle9i Java Stored Procedures Developer's Guide. To learn
how to write C call specs, see Oracle9i Application Developer's Guide Fundamentals.
Parameter SELF
MEMBER methods accept a built-in parameter named SELF, which is an
instance of the object type. Whether declared implicitly or explicitly, it is
always the first parameter passed to a MEMBER method.
However, STATIC methods cannot accept or reference SELF.
In the method body, SELF denotes the object whose method was invoked. For
example, method transform declares SELF as an IN OUT parameter:
CREATE TYPE Complex AS OBJECT (
MEMBER FUNCTION transform (SELF IN OUT Complex) ...

You cannot specify a different datatype for SELF. In MEMBER functions,


if SELF is not declared, its parameter mode defaults to IN. However,
in MEMBER procedures, if SELF is not declared, its parameter mode defaults
to IN OUT. You cannot specify theOUT parameter mode for SELF.
As the following example shows, methods can reference the attributes
of SELF without a qualifier:
CREATE FUNCTION gcd (x INTEGER, y INTEGER) RETURN INTEGER AS
-- find greatest common divisor of x and y
ans INTEGER;
BEGIN
IF (y <= x) AND (x MOD y = 0) THEN ans := y;
ELSIF x < y THEN ans := gcd(y, x);
ELSE ans := gcd(y, x MOD y);
END IF;
RETURN ans;
END;

CREATE TYPE Rational AS OBJECT (


num INTEGER,
den INTEGER,
MEMBER PROCEDURE normalize,
...
);

CREATE TYPE BODY Rational AS


MEMBER PROCEDURE normalize IS
g INTEGER;
BEGIN

g := gcd(SELF.num, SELF.den);
g := gcd(num, den); -- equivalent to previous statement
num := num / g;
den := den / g;
END normalize;
...
END;

From a SQL statement, if you call a MEMBER method on a null instance (that
is, SELF is null), the method is not invoked and a null is returned. From a
procedural statement, if you call a MEMBER method on a null instance,
PL/SQL raises the predefined exception SELF_IS_NULL before the method is
invoked.
Overloading
Like packaged subprograms, methods of the same kind (functions or
procedures) can be overloaded. That is, you can use the same name for
different methods if their formal parameters differ in number, order, or
datatype family. When you call one of the methods, PL/SQL finds it by
comparing the list of actual parameters with each list of formal parameters.
A subtype can also overload methods it inherits from its supertype. In this
case, the methods can have exactly the same formal parameters.
You cannot overload two methods if their formal parameters differ only in
parameter mode. Also, you cannot overload two member functions that differ
only in return type. For more information, see "Overloading Subprogram
Names".
MAP and ORDER Methods
The values of a scalar datatype such as CHAR or REAL have a predefined
order, which allows them to be compared. But instances of an object type
have no predefined order. To put them in order for comparison or sorting
purposes, PL/SQL calls aMAP method supplied by you. In the following
example, the keyword MAP indicates that
method convert() orders Rational objects by mapping them to REAL values:
CREATE TYPE Rational AS OBJECT (
num INTEGER,

den INTEGER,
MAP MEMBER FUNCTION convert RETURN REAL,
...
);

CREATE TYPE BODY Rational AS


MAP MEMBER FUNCTION convert RETURN REAL IS
BEGIN
RETURN num / den;
END convert;
...
END;

PL/SQL uses the ordering to evaluate Boolean expressions such as x > y, and
to do comparisons implied by the DISTINCT, GROUP BY,
and ORDER BY clauses. MAP method convert() returns the relative position of
an object in the ordering of allRational objects.
An object type can contain only one MAP method. It accepts the built-in
parameter SELF and returns one of the following scalar
types: DATE, NUMBER, VARCHAR2, or an ANSI SQL type such
as CHARACTER or REAL.
Alternatively, you can supply PL/SQL with an ORDER method. An object
type can contain only one ORDER method, which must be a function that
returns a numeric result. In the following example, the
keyword ORDER indicates that methodmatch() compares two objects:
CREATE TYPE Customer AS OBJECT (
id NUMBER,
name VARCHAR2(20),
addr VARCHAR2(30),
ORDER MEMBER FUNCTION match (c Customer) RETURN INTEGER
);

CREATE TYPE BODY Customer AS


ORDER MEMBER FUNCTION match (c Customer) RETURN INTEGER IS
BEGIN
IF id < c.id THEN
RETURN -1; -- any negative number will do
ELSIF id > c.id THEN
RETURN 1; -- any positive number will do
ELSE
RETURN 0;
END IF;
END;
END;

Every ORDER method takes just two parameters: the built-in


parameter SELF and another object of the same type.
If c1 and c2 are Customer objects, a comparison such as c1 > c2 calls
method match automatically. The method returns a negative number, zero,
or a positive number signifying that SELF is respectively less than, equal to,
or greater than the other parameter. If either parameter passed to
an ORDER method is null, the method returns a null.
Guidelines
A MAP method, acting like a hash function, maps object values into scalar
values, which are then compared using operators such as <, =, and so on.
An ORDER method simply compares one object value to another.
You can declare a MAP method or an ORDER method but not both. If you
declare either method, you can compare objects in SQL and procedural
statements. However, if you declare neither method, you can compare
objects only in SQL statements and only for equality or inequality. (Two
objects of the same type are equal only if the values of their corresponding
attributes are equal.)
When sorting or merging a large number of objects, use a MAP method. One
call maps all the objects into scalars, then sorts the scalars.

An ORDER method is less efficient because it must be called repeatedly (it


can compare only two objects at a time). You must use a MAP method for
hash joins because PL/SQL hashes on the object value.
Constructor Methods
Every object type has a constructor method (constructor for short),
which is a function with the same name as the object type that initializes and
returns a new instance of that object type.
Oracle generates a default constructor for every object type, with formal
parameters that match the attributes of the object type. That is, the
parameters and attributes are declared in the same order and have the same
names and datatypes.
You can define your own constructor methods, either overriding a systemdefined constructor, or defining a new function with a different signature.
PL/SQL never calls a constructor implicitly, so you must call it explicitly.
For more information, see "Defining Constructors".
Changing Attributes and Methods of an Existing Object Type (Type
Evolution)
You can use the ALTER TYPE statement to add, modify, or drop attributes,
and add or drop methods of an existing object type:
CREATE TYPE Person_typ AS OBJECT
( name CHAR(20),
ssn CHAR(12),
address VARCHAR2(100));
CREATE TYPE Person_nt IS TABLE OF Person_typ;
CREATE TYPE dept_typ AS OBJECT
( mgr Person_typ,
emps Person_nt);
CREATE TABLE dept OF dept_typ;

-- Add new attributes to Person_typ and propagate the change


-- to Person_nt and dept_typ

ALTER TYPE Person_typ ADD ATTRIBUTE (picture BLOB, dob DATE)


CASCADE NOT INCLUDING TABLE DATA;

CREATE TYPE mytype AS OBJECT (attr1 NUMBER, attr2 NUMBER);


ALTER TYPE mytype ADD ATTRIBUTE (attr3 NUMBER),
DROP ATTRIBUTE attr2,
ADD ATTRIBUTE attr4 NUMBER CASCADE;

When a procedure is compiled, it always uses the current version of any


object types it references. Existing procedures on the server that reference
an object type are invalidated when the type is altered, and are
automatically recompiled the next time the procedure is called. You must
manually recompile any procedures on the client side that reference types
that are altered.
If you drop a method from a supertype, you might have to make changes to
subtypes that override that method. You can find if any subtypes are affected
by using the CASCADE option of ALTER TYPE; the statement is rolled back if
any subtypes override the method. To successfully drop the method from the
supertype, you can:

Drop the method permanently from the subtype first.

Drop the method in the subtype, then add it back later using ALTER
TYPE without the OVERRIDING keyword.

For more information about the ALTER TYPE statement, see Oracle9i SQL
Reference. For guidelines about using type evolution in your applications,
and options for changing other types and data that rely on see Oracle9i
Application Developer's Guide - Object-Relational Features.
Defining Object Types
An object type can represent any real-world entity. For example, an object
type can represent a student, bank account, computer screen, rational
number, or data structure such as a queue, stack, or list. This section gives
several complete examples, which teach you a lot about the design of object
types and prepare you to start writing your own.

Currently, you cannot define object types in a PL/SQL block, subprogram, or


package. However, you can define them interactively in SQL*Plus using the
following syntax:
CREATE [OR REPLACE] TYPE type_name
[AUTHID {CURRENT_USER | DEFINER}]
{ {IS | AS} OBJECT | UNDER supertype_name }
(
attribute_name datatype[, attribute_name datatype]...
[{MAP | ORDER} MEMBER function_spec,]
[{FINAL| NOT FINAL} MEMBER function_spec,]
[{INSTANTIABLE| NOT INSTANTIABLE} MEMBER function_spec,]
[{MEMBER | STATIC} {subprogram_spec | call_spec}
[, {MEMBER | STATIC} {subprogram_spec | call_spec}]...]
) [{FINAL| NOT FINAL}] [ {INSTANTIABLE| NOT INSTANTIABLE}];

[CREATE [OR REPLACE] TYPE BODY type_name {IS | AS}


{ {MAP | ORDER} MEMBER function_body;
| {MEMBER | STATIC} {subprogram_body | call_spec};}
[{MEMBER | STATIC} {subprogram_body | call_spec};]...
END;]

Definition - What does Embedded SQL mean?


Embedded SQL statements SQL statements are embedded directly into the
program source code and mixed with the host language statements. This approach
allows users to write programs that access the database directly. A special
precompiler modifies the source code to replace SQL statements with calls to DBMS
routines. The source code can then be compiled and linked in the normal way. The
ISO standard specifies embedded support for Ada, C, COBOL, Fortran, MUMPS,
Pascal, and PL/1 programming languages. n Application Programming Interface (API)
An alternative technique is to provide the programmer with a standard set of
functions that can be invoked from the software. An API can provide the same
functionality as embedded statements and removes the need for any
precompilation. It may be argued that this approach provides a cleaner interface

and generates more manageable code. The best-known API is the Open Database
Connectivity (ODBC) standard. DS4_Web1.qxd 23/04/2004 18:39 Page 1 .. 2 |
Appendix E z Programmatic SQL .. E.1 Most DBMSs provide some form of embedded
SQL, including Oracle, INGRES, Informix, and DB2; Oracle also provides an API;
Access provides only an API (called ADO ActiveX Data Objects a layer on top of
ODBC). Structure of this Appendix There are two types of embedded SQL: static
embedded SQL, where the entire SQL statement is known when the program is
written, and dynamic embedded SQL, which allows all or part of the SQL statement
to be specified at runtime. Dynamic SQL provides increased flexibility and helps
produce more general-purpose software. We examine static embedded SQL in
Section E.1 and dynamic embedded SQL in Section E.2. In Section E.3 we discuss
the Open Database Connectivity (ODBC) standard,
Embedded SQL is a method of inserting inline SQL statements or queries into the
code of a programming language, which is known as a host language. Because the
host language cannot parse SQL, the inserted SQL is parsed by an embedded SQL
preprocessor.

Embedded SQL is a robust and convenient method of combining the computing


power of a programming language with SQL's specialized data management and
manipulation capabilities.
[WEBINAR] Edge Analytics: The IoT Economy at Last

Techopedia explains Embedded SQL

Embedded SQL is not supported by all relational database management systems


(RDBMS). Oracle DB and PostgreSQL provide embedded SQL support. MySQL,
Sybase and SQL Server 2008 do not, although support was provided by earlier
versions of SQL Server (2000 and 2005).

The C programming language is commonly used for embedded SQL


implementation. For example, a commercial bank's information system (IS) has a
front-end user interface created in the C language, and the IS interfaces with a
back-end Oracle DB database. One of the front-end interface modules allows quick
viewing and commission calculation for sales agents during specified periods. An
inefficient approach to handling this process would be to store each commission
value in a database table. However, a more effective solution is to calculate and
return commission values based on unique user requests on specified dates. The
application accomplishes this by embedding a SQL query within the C code, as
follows:

SELECT 0.2*SALE_AMOUNT FROM TOTAL_SALES WHERE SALE_DATE='MM/DD'YYYY'


AND AGENT_NO=xx

In this example, the SQL statement calculates and returns 20 percent of the sale
amount from a TOTAL_SALES table, while the user is expected to input the
SALE_DATE and AGENT_NO values. This SQL query is then inserted inline into the C
code of the front-end module. The C code and SQL query work together to deliver
seamless user results.

.
What Is ODBC?
Open Database Connectivity (ODBC) is a standard that allows programs to read
from almost all of the databases currently available.
This means that Batch can read database formats like Microsoft Access, Paradox,
dBase and FoxPro; spreadsheets like Microsoft Excel; and connect to external
database servers such as Oracle, Informix or Microsoft SQL Server.
Or For A Technical Definition
Open Database Connectivity (ODBC) technology provides a common interface for
accessing heterogeneous SQL databases. ODBC is based on Structured Query
Language (SQL) as a standard for accessing data. This interface provides maximum
interoperability: a single application can access different SQL Database
Management Systems (DBMS) through a common set of code. This enables a
developer to build and distribute a client/server application without targeting a
specific DBMS. Database drivers are then added to link the application to the user's
choice of DBMS.
How Does It Work?
Rather than having to know about each type of database, an application just talks to
an ODBC driver that understands that format.
This means that, once the ODBC driver for a particular type of database is provided,
any program can read databases in that format. If a new database format needs to
be worked with, then all that is required is to install the relevant driver.

The figure above shows how ODBC fits in between an application and the database
it is accessing.
Who Provides ODBC Drivers?
When installing Batch, if the Database Connectivity option is left checked, then
ODBC drivers will be installed for the following database formats: Microsoft Access,
dBase, Excel, FoxPro, Oracle, SQL Server and Paradox.
If you need drivers that are not included then they should be available from the
supplier or manufacturer of the database: check on their web site, as they are often
available free-of-charge.
Tech Note: Batch will not display the new database types unless it has additional
information about the driver, stored in qaworld.ini. However, it is still possible to use
the new driver by using it to establish a Registered ODBC Source.
Batch does not need ODBC to operate, but does require DAO. The System
Components installation option installs all the basics Batch needs; it must be run
on every machine you want to run Batch from.
What Is A Registered ODBC Source?
A Registered ODBC Source is a way of storing all the information needed to make an
ODBC connection: it can then be referred to by a single name the data source
name (DSN).
The application can then establish a connection without needing to know where or
what type of database it is connecting to, making it easy for administrators to move
or update the source.

You would use a Registered ODBC Source when you need to connect to an external
database server it is the only way of doing so or if you frequently connect to a
particular database.

To examine ODBC settings on your machine, go to the Control Panel and open the
ODBC icon. The figure above shows what it looks like on various platforms.
The ODBC Data Source Administrator that starts up displays all the drivers installed
on your machine (under the Drivers tab) along with their version, connections for all
who use your machine (under the System DSN tab) and connections set up solely
for you (under the User DSN tab).

To create a new DSN click on the Add button and use the wizard that appears to set
up all the settings required. Click on Configure to modify an existing DSN.
Can We Batch Data That Is On A Unix/AS400/Mainframe Box?
Yes. All you need is the appropriate ODBC driver (such as the SQL Server driver
provided with QAS Batch) and to set up your server as a Registered ODBC Source.
You might need to provide a username and password in order to make the
connection.
What Happens When You Clean A Database?
The following section explains what database reading and writing goes on during a
Batch run, and what affect this has on Batch cleaning.

The figure above shows a simplified picture of how the cleaning process work.

What Happens During Automatic Cleaning?


If you set up a session by selecting a database and driver then Batch automatically
makes an ODBC connection to the database on your behalf, using those settings.
If, instead, you use a Registered ODBC Source then the connection information has
already been set up on your machine, so Batch just needs to open the link.
Tech Note: Text files (.csv, .dat, .txt) are not accessed using ODBC, as QAS have a
more comprehensive system for working with them. This, by the way, is why input
file filtering is not available for text files, as only ODBC provides it.
Records are read from the database, one at a time, cleaned and then written to the
intermediate database.
Therefore, the user performing the automatic run requires write access to the
session file and intermediate database, and read access to the source database.
Why Can't Batch Open All Tables?
Batch reads databases through ODBC, which does not support as rich a set of
allowed table and field names as does, say, Microsoft Access. It is recommended
that spaces, commas, quotes and other difficult characters should be excluded from
the names of any tables or fields you wish to process.
Resuming An Automatic Run.
The Batch session goes into a suspended state if the user chooses to suspend or if
there is a system crash. Normally the run can be resumed at the last record read,
but this is only possible if the database has a unique record identifier.
What Is A Unique Record Identifier?
A unique record identifier (UID), or row identifier, allows individual records in a
database to be directly referenced. Without it there is no random access to records,
no way to refer to a particular record. This also means that Batch cannot update
data in place when it comes to the Commit stage.
When such a database is selected a warning is given in the Setup Wizard, the
Suspend button is renamed Stop, and Commit will only write out the cleaned
addresses to a text file.
What Is The Intermediate Database?
The intermediate database (IDB) is where the original input fields, reference fields
and cleaned (output) address fields are kept. It is updated during Automatic and
Interactive cleaning and Commit operations.
Where Is The Intermediate Database Stored?
Initially, all intermediate databases are stored in the same place as the session files.

The location of a session's IDB and all future IDB's can be changed when configuring
a session: it is shown at the bottom of the "Enter Filename" page of the wizard:
modify it by clicking on the Change button.
How Big Is The Intermediate Database?
As the IDB holds original and cleaned address fields as well as the reference fields,
it can be as large as twice the size of the source database. However, it will
frequently be smaller as it does not include any fields or tables that are not part of
the Batch run.
How Can We Delete It?
The IDB is automatically deleted when a session is deleted. It is also deleted when a
fresh Batch run is started on an existing session, or when a fully cleaned session is
Reconfigured and then saved.
The last one is a useful way of reusing a session file say, if the same file is cleaned
periodically without the intermediate database hanging around.
Why Do We Use An Intermediate Database Instead Of Updating As We Go?
Writing data back to the user's database it is a one-way process: it cannot be
undone or rolled back. As Batch frequently deals with customer and contact
databases of immense value to the user, integrity and security are very important.
We wish to support the following functionality:
a. Allow the user to view the cleaned records before they are written.
b. Inform the user of what has been done to the record (match codes).
c. Provide the ability to Interactively clean the addresses.
d. Allow cleaned records to be selectively written back to the original database.
In order to provide all this, it is therefore necessary to hold the original and cleaned
addresses in an intermediate database.
What Is DAO And Why Do We Use It?
It was decided to store the IDB as an Access database rather than plain text as it
allows random access reads, updates, writes, record filtering and multi-user access.
Data Access Objects (DAO) is way of connecting to databases, designed primarily
for Microsoft Access files. It was chosen because it offers superior performance to
ODBC for our purposes.
What Happens During Interactive Cleaning?
Interactive displays the original and cleaned address fields to the user, along with
the match code (what Batch has done and how much confidence it has in the
cleaned record), all of which is read from the intermediate database.

If the user corrects the address or updates it's status then changes will be written
back to the IDB.
Note, therefore, that every Interactive user must have full write access to the
intermediate database, as well as the session file, in order to work successfully.
What Happens When You Commit?
The act of writing the cleaned address records back to the source database is called
a Commit (taken from database terminology). It is a one-way updating procedure.
As mentioned in paragraph 0, Resuming An Automatic Run, the source database can
only be updated in place if it has a unique field identifier. If it does not then the
cleaned address records can be written out to a text file instead.
Once a Commit filter has been chosen, the cleaned records that match it will be
written back to the source database. When Batch writes data back, it simply
overwrites the contents of each output field, then marks the record as committed in
the IDB.
As time has passed between when the source was originally read and the commit,
the following situations can arise:
a. Modification: if changes are made to fields in the source database after the
record is read by Batch, then they will be lost if Batch writes to that field as it
commits.
b. Deletion: if a record has been deleted then Batch will be unable to write the
address back: it will keep track of write failures, which will be displayed in the
commit summary.
c. Write failure: if the record cannot be updated for any other reason then this is
classed as a serious error, which will be reported individually in the summary along
with the reason. Fifty of these errors can occur before the Commit process
terminates.
Write failure could occur because the record is locked if somebody is editing it in
the source database or if the field is read-only to the user running Batch, or if the
database is offline or down.
Note that once a record successfully commits, it no longer appears in any of the
filters. This also means that problem records can easily be traced by running the
Viewer with the filter that was just used to Commit.
Why Did Commit Say "There Are No Records Matching The Specified
Filter"?
As mentioned above, when you Commit, each record that is successfully updated is
then marked as committed and is excluded from all the filters. This means that if
you immediately reapply the same Commit filter then there should no longer be any
record that matches it.

If some further Automatic or Interactive processing is performed then records may


once again match the selected filter.
What Happens When A Commit Fails?
If over fifty serious commit failures occur, or if Batch cannot proceed, then Batch
will unmark all the previously committed records in the IDB, so the whole Commit
operation can be restarted when the issues are resolved.

Anda mungkin juga menyukai