Documente Academic
Documente Profesional
Documente Cultură
By
CONTENT
TOPIC 1. PAGE
INTRODUCTION TO DBMS3
2. INTRODUCTION TO SQL12
3. SQL CONSTRAINT.33
5. SECURITY MANAGEMENT65
6.INTRODUCTION TO PL/SQL69
7. ORACLE TRANSACTIONS.100
CHAPTER-1INTODUCTION TO DBMS
1.1 What is Data ?
Data is stored facts. Data may be numerical data which may be integers or floating point numbers, and nonnumerical data such as characters, date and etc., Eg :
98 89 87 92
The above numbers may be anything: It may be distance in kms or amount in rupees or no of days or marks in each subject etc.,
98 89 87 92
Database is a collection of information organized in such a way that a computer program can quickly select desired pieces of data.
76 87 79 88
A collection of programs that enables you to store, modify, and extract information from a database. The general purpose of a DBMS is to provide for the definition, storage, and management of data in a centralized area that can be shared by many users. ORACLE's database management system is patterned on the relational model described by Dr. E. F. Code
Eg: EMPNO column is primary key in EMP table DEPTNO column is primary key in DEPT table Referential Integrity The referential integrity rule states that if a relational table has a foreign key, then every value of the foreign key must either be null or match the values in the relational table in which that foreign key is a primary key. Referential integrity ensures that we can correctly navigate between related entities Eg : DEPTNO column in EMP is FOREIGN KEY with reference to DEPTNO column in DEPT which is a PRIMARY KEY
Foreign key.
A foreign key creates a hierarchical relationship between two associated entities. The entity containing the foreign key is the child, or dependent, and the table containing the primary key from which the foreign key values are obtained is the parent. In order to maintain referential integrity between the parent and child as data is inserted or deleted from the database certain insert and delete rules are to be considered. If FK and PK are in same table it is self referential
1.6NORMALIZATION
Normalization is the process of decomposing and arranging the attributes in a schema, which results in a set of tables with very simple structures.
The purpose of normalization is to make tables as simple as possible. There are different types of normal forms i.e., First normal form, Second normal form, Third normal form, Forth normal form, Boyce/Codd Normal Form etc., Example Relation (Table) S# S1 S1 S1 S1 S1 S1 S2 S2 S3 S4 S4 S4 City London London London London London London Paris Paris Paris London London London Status 20 20 20 20 20 20 10 10 10 20 20 20 P# P1 P2 P3 P4 P5 P6 P1 P2 P2 P2 P4 P5 Qty 300 200 400 200 100 100 300 400 200 200 300 400
S# - Supplier No City Supplier City Status City Status P# - Part No Qty Quantity
UPDATE: If supplier S1 moves from London to New York, all S1 records need to be updated! Redundant! *part # is part of Primary Key! These anomalies indicate that 1NF in our case is not ideal. How do we solve this? Break the relation into two!! Proposed Solutions 2nd NF New Relations!: Second Normal Form (2NF) S# City Status S1 London 20 S2 Paris 10 S3 Paris 10 S4 London 20 S5 Athens 30 S# P# Qty S1 S1 S1 S1 S1 S1 S2 S2 S3 S4 S4 S4 P1 P2 P3 P4 P5 P6 P1 P2 P2 P2 P4 P5 300 200 400 200 100 100 300 400 200 200 300 400
INSERT: We can not create a new tuple giving a specific Status to a City unless we have a Supplier from the City* DELETE: If we delete the only tuple for a particular city, we destroy supplier information as well as city status information! UPDATE: If we wanted to change status for a city, we need to modify all the tuples for the city! Redundant! *Supplier # is the primary key!
attributes are mutually independent. Now, all our relations are in the 3NF. From a single relation (SUPP) in 1NF, we have developed three relations, (SUPP1.1, SUPP1.2, & SUPP2) all in 3NF. If we join these three relations we WILL get SUPP! (Nonloss decomposition). Again, update Problems Overcome The new structure overcomes update problems of SUPP1 INSERT: We can add a city and assign a status without adding a supplier DELETE: If we delete a tuple in SUPP1.1 we lose only Supplier information. Status information for the City is still available in SUPP1.2 UPDATE: Updating status for a city involves only one tuple in SUPP1.2. Similarly, if a supplier moved to a different city only one tuple needs to be modified in SUPP1.1 DATABASE ADMINSTRATOR(DBA)
A database administrator (DBA) is a person responsible for the design, implementation, maintenance and repair of an organization's database They are also known by the titles Database Coordinator or Database Programmer, and is closely related to the Database Analyst, Database Modeler, Programmer Analyst, and Systems Manager. The role includes the development and design of database strategies, monitoring and improving database performance and capacity, and planning for future expansion requirements. They may also plan, co-ordinate and implement security measures to safeguard the database. Employing organizations may require that a database administrator have a certification or degree for database systems (for example, the Microsoft Certified Database Administrator Database administrator's activities can be listed as below: 1. Maintaining database and ensuring its availability to users 2. Controlling privileges and permissions to database users 3. Monitoring database performance 4. Database backup and recovery 5. Database security
RELATIONAL DATABASE
10
Definition A relational database is a collection of data items organized as a set of formally-described tables from which data can be accessed or reassembled in many different ways without having to reorganize the database tables. The relational database was invented by E. F. Codd at IBM in 1970. The standard user and application program interface to a relational database is the structured query language (SQL).SQL statements are used both for interactive queries for information from a relational database and for gathering data for reports. In addition to being relatively easy to create and access, a relational database has the important advantage of being easy to extend. After the original database creation, a new data category can be added without requiring that all existing applications be modified. A relational database is a set of tables containing data fitted into predefined categories. Each table (which is sometimes called a relation) contains one or more data categories in columns. Each row contains a unique instance of data for the categories defined by the columns. For example, a typical business order entry database would include a table that described a customer with columns for name, address, phone number, and so forth. Another table would describe an order: product, customer, date, sales price, and so forth. A user of the database could obtain a view of the database that fitted the user's needs. For example, a branch office manager might like a view or report on all customers that had bought products after a certain date. A financial services manager in the same company could, from the same tables, obtain a report on accounts that needed to be paid. When creating a relational database, you can define the domain of possible values in a data column and further constraints that may apply to that data value. For example, a domain of possible customers could allow up to ten possible customer names but be constrained in one table to allowing only three of these customer names to be specifiable. The definition of a relational database results in a table of metadata or formal descriptions of the tables, columns, domains, and constraints. Dr. Codd defined thirteen standards which must be met before a database can be considered to be a relational database: 0. A relational DBMS must be able to manage databases entirely through its relational capabilities. 1. Information rule-- All information in a relational database (including table and column names) is represented explicitly as values in tables. 2. Guaranteed access--Every value in a relational database is guaranteed to be accessible by using a combination of the table name, primary key value, and column name.
11
3. Systematic null value support--The DBMS provides systematic support for the treatment of null values (unknown or inapplicable data), distinct from default values, and independent of any domain. 4. Active, online relational catalog--The description of the database and its contents is represented at the logical level as tables and can therefore be queried using the database language. 5. Comprehensive data sublanguage--At least one supported language must have a welldefined syntax and be comprehensive. It must support data definition, manipulation, integrity rules, authorization, and transactions. 6. View updating rule--All views that are theoretically updatable can be updated through the system. 7. Set-level insertion, update, and deletion -- The DBMS supports not only setlevel retrievals but also set-level inserts, updates, and deletes. 8. Physical data independence--Application programs and ad hoc programs are logically unaffected when physical access methods or storage structures are altered. 9. Logical data independence--Application programs and ad hoc programs are logically unaffected, to the extent possible, when changes are made to the table structures. 10. Integrity independence--The database language must be capable of defining integrity rules. They must be stored in the online catalog, and they cannot be bypassed. 11. Distribution independence--Application programs and ad hoc requests are logically unaffected when data is first distributed or when it is redistributed. 12. Nonsubversion--It must not be possible to bypass the integrity rules defined through the database language by using lower-level languages. Alternatives to the relational database model include the heirarchical model, the network model, and the object model. ADVANTAGES OF RELATIONAL APPROACH The popularity of the relational database approach has been apart from access of availability of a large variety of products also because it has certain inherent advantages. 1. Ease of use: The revision of any information as tables consisting 0f rows and columns is quite natural and therefore even first time users find it attractive.
12
2. Flexibility: Different tables from which information has to be linked and extracted can be easily manipulated by operators such as Projectand join to give information in the form in which it is desired. 3. Precision: The usage of relational algebra and relational calculus in the manipulation of he relations between the tables ensures that there is no ambiguity, which may otherwise arise in establishing the linkages in a complicated network type database. 4. Security: Security control and authorization can also be implemented more easily by moving sensitive attributes in a given table into a separate relation with its own authorization controls. If authorization requirement permits, a particular attribute could be joined back with others to enable full information retrieval 5. Data Independence: Data independence is achieved more easily with normalization structure used in a relational database than in the more complicated tree or Network structure. 6. Data Manipulation Language: The possibility of responding to ad-hoc query by means of a language based on relational algebra and relational calculus is easy in the relational database approach. For data organized in other structure the query language either becomes complex or extremely limited in its capabilities.
ENTITY-RELATIONSHIP(E-R)
13
Definition: An entity-relationship (ER) diagram is a specialized graphic that illustrates the interrelationships between entities in a database. ER diagrams often use symbols to represent three different types of information. Boxes are commonly used to represent entities. Diamonds are normally used to represent relationships and ovals are used to represent attributes. Also Known As: ER Diagram, E-R Diagram, entity-relationship model
Examples: Consider the example of a database that contains information on the residents of a city. The ER digram shown in the image above contains two entities -- people and cities. There is a single "Lives In" relationship. In our example, due to space constraints, there is only one attribute associated with each entity. People have names and cities have populations. In a real-world example, each one of these would likely have many different attributes.
Two-Tier Architecture:
The two-tier architecture is like client server application. The direct communication takes place between client and server. There is no intermediate between client and server.
The above figure shows the architecture of two-tier. Here the communication is one to one. Let us see the concept of two tier with real time application. For example now we have a need to save the employee details in database. The two tiers of two-tier architecture is 1. 2. Database (Data tier) Client Application (Client tier)
So, in client application the client writes the program for saving the record in SQL Server and thereby saving the data in the database. Advantages:
14
1.
Three-Tier Architecture:
Three tier architecture having three layers. They are 1. 2. 3. Client layer Business layer Data layer
Client layer: Here we design the form using textbox, label etc. Business layer: It is the intermediate layer which has the functions for client layer and it is used to make communication faster between client and data layer. It provides the business processes logic and the data access. Data layer: it has the database.
Advantages 1. 2. Easy to modify with out affecting other modules Fast communication
15
SOLVED QUESTIONS
Q.1 What is Database Management System (DBMS) ? Sol. A collection of programs that enables you to store, modify, and extract information
from a database. The general purpose of a DBMS is to provide for the definition, storage, and management of data in a centralized area that can be shared by many users. \
Q.2Differentiate between DBMS and RDBMS. Sol. DBMS DDD 1. DBMS a data base management
System. . 2. RDBMS is two table joining Relation. 3. DBMS does not support client/ Server Architecture 4. The speed of operation is very Poor. 5. It uses the concept of file. 6.The DBMS normally use a 3GL.
RDBMS
1.RDBMS is a relation data base Management system 2.DBMS is not join the table. 3.RDBMS supports client/server Architecture 4.The speed of operation is very Fast. 4. It use the concept of table. 5. The RDBMS normally use a 4GL.
7. Only one user can access the database 7. RDBMS allows simultaneous access of users to the database access of users to the database
8. Data Base Management System 8. The database which is is a process of managing used by relations(tables) data for efficient retrieval & to acquire information Storage of database retrieval are known as RDBMS. Ex: Sybase , FoxPro EX: SQL, ORACLE,MY-SQLSERVER
16
Q;3.Explain two tier and three tier computing models. Sol. Two-Tier Architecture:
The two-tier architecture is like client server application. The direct communication takes place between client and server. There is no intermediate between client and server.
The above figure shows the architecture of two-tier. Here the communication is one to one. Let us see the concept of two tier with real time application. For example now we have a need to save the employee details in database. The two tiers of two-tier architecture is 1. 2. Database (Data tier) Client Application (Client tier)
So, in client application the client writes the program for saving the record in SQL Server and thereby saving the data in the database. Advantages: 1. Understanding and maintenances is easier.
Three-Tier Architecture: Three tier architecture having three layers. They are 1. 2. 3. Client layer Business layer Data layer
Client layer: Here we design the form using textbox, label etc. Business layer: It is the intermediate layer which has the functions for client layer and it is used to make communication faster between client and data layer. It provides the business processes logic and the data access.
17
Advantages 1. 2. 3. Easy to modify with out affecting other modules Fast communication Performance will be good in three tier architectur
Q:5 Describe the three levels of data abstraction? Sol. External or user views: the view of the data that each person has for their functional
area. Logical Data Model or Conceptual Model: the entire collection of user views for each functional area. In other words, it is the enterprise's overall view of the database. Physical or Internal view: the structure used to physically implement the logical data model on a physical medium. Q:6 Define the "integrity rules" SOL. Data integrity Data integrity means that the data values in the database are correct and consistent. Data integrity means, in part, that you can correctly and consistently navigate and manipulate the tables in the database. Data integrity is enforced in the relational model by entity and referential integrity rules. Entity Integrity The entity integrity rule states that for every instance of an entity, the value of the primary key must exist, be unique, and cannot be null.
18
Without entity integrity, the primary key could not fulfill its role of uniquely identifying each instance of an entity.
Eg: EMPNO column is primary key in EMP table DEPTNO column is primary key in DEPT table Referential Integrity The referential integrity rule states that if a relational table has a foreign key, then every value of the foreign key must either be null or match the values in the relational table in which that foreign key is a primary key. Referential integrity ensures that we can correctly navigate between related entities Eg : DEPTNO column in EMP is FOREIGN KEY with reference to DEPTNO column in DEPT which is a PRIMARY KEY
Q:7. What is Data Model? SOL. A collection of conceptual tools for describing data, data relationships data
semantics and constraints.
Q;8. What is E-R model?\ Sol. This data model is based on real world that consists of basic objects called entities
and of relationship among these objects. Entities are described in a database by a set of attributes.
Q:10.Define RDBMS Sol. A relational database is a collection of data items organized as a set of formallydescribed tables from which data can be accessed or reassembled in many different ways without having to reorganize the database tables
Q:11.What is DBA?Define Sol. A database administrator (DBA) is a person responsible for the design,
implementation, maintenance and repair of an organization's database They are also known by the titles Database Coordinator or Database Programmer
Q:12. What is an Entity? Sol. t is a thing in the real world with an independent existence
19
Q: 13. What is an Entity type? Sol. It is a collection (set) of entities that have same attributes Q: 14. What is an Entity set? Sol. It is a collection of all entities of particular entity type in the database Q: 15. What is an attribute? Sol. It is a particular property, which describes the entity. Q: 16.Define Primary Key. Sol. The PRIMARY KEY constraint uniquely identifies each record in a database table.
Primary keys must contain unique values. A primary key column cannot contain NULL values. Each table should have a primary key, and each table can have only ONE primary key
Q: 17.Define Foreign Key. Sol. A FOREIGN KEY in one table points to a PRIMARY KEY in another table.
20
CHAPTER -2 SQL
INTRODUCTION TO SQL
SQL is a standard language for accessing and manipulating databases.
SQL stands for Structured Query Language SQL lets you access and manipulate databases SQL is an ANSI (American National Standards Institute) standard
SQL can execute queries against a database SQL can retrieve data from a database SQL can insert records in a database 21
SQL can update records in a database SQL can delete records from a database SQL can create new databases SQL can create new tables in a database SQL can create stored procedures in a database SQL can create views in a database SQL can set permissions on tables, procedures, and views
An RDBMS database program (i.e. MS Access, SQL Server, MySQL) A server-side scripting language, like PHP or ASP SQL HTML / CSS
2.5RDBMS RDBMS stands for Relational Database Management System. RDBMS is the basis for SQL, and for all modern database systems like MS SQL Server, IBM DB2, Oracle, MySQL, and Microsoft Access. The data in RDBMS is stored in database objects called tables. A table is a collections of related data entries and it consists of columns and rows 2.6 SQL
data types
Data types and ranges for Microsoft Access, MySQL and SQL Server.
Description Storage Use for text or combinations of text and numbers. 255 characters maximum Memo Memo is used for larger amounts of text. Stores up to 65,536 characters. Note: You cannot sort a memo field. However, they are searchable Byte Allows whole numbers from 0 to 255 1 byte Integer Allows whole numbers between -32,768 and 32,767 2 bytes Long Allows whole numbers between -2,147,483,648 and 4 bytes 2,147,483,647 Single Single precision floating-point. Will handle most decimals 4 bytes Double Double precision floating-point. Will handle most decimals 8 bytes Currency Use for currency. Holds up to 15 digits of whole dollars, plus 48 bytes decimal places. Tip: You can choose which country's currency to use AutoNumber AutoNumber fields automatically give each record its own 4 bytes number, usually starting at 1 Date/Time Use for dates and times 8 bytes Yes/No A logical field can be displayed as Yes/No, True/False, or 1 bit On/Off. In code, use the constants True and False (equivalent to -1 and 0). Note: Null values are not allowed in Yes/No fields Ole Object Can store pictures, audio, video, or other BLOBs (Binary up to Large OBjects) 1GB Hyperlink Contain links to other files, including web pages Lookup Wizard Let you type a list of options, which can then be chosen from a 4 bytes drop-down list
23
converted to a TEXT type TINYTEXT Holds a string with a maximum length of 255 characters TEXT Holds a string with a maximum length of 65,535 characters BLOB For BLOBs (Binary Large OBjects). Holds up to 65,535 bytes of data MEDIUMTEXT Holds a string with a maximum length of 16,777,215 characters MEDIUMBLOB For BLOBs (Binary Large OBjects). Holds up to 16,777,215 bytes of data LONGTEXT Holds a string with a maximum length of 4,294,967,295 characters LONGBLOB For BLOBs (Binary Large OBjects). Holds up to 4,294,967,295 bytes of data ENUM(x,y,z,etc.) Let you enter a list of possible values. You can list up to 65535 values in an ENUM list. If a value is inserted that is not in the list, a blank value will be inserted. Note: The values are sorted in the order you enter them. You enter the possible values in this format: ENUM('X','Y','Z') Similar to ENUM except that SET may contain up to 64 list items and can store more than one choice
SET
Number types:
Data type TINYINT(size) Description -128 to 127 normal. 0 to 255 UNSIGNED*. The maximum number of digits may be specified in parenthesis SMALLINT(size) -32768 to 32767 normal. 0 to 65535 UNSIGNED*. The maximum number of digits may be specified in parenthesis MEDIUMINT(size) -8388608 to 8388607 normal. 0 to 16777215 UNSIGNED*. The maximum number of digits may be specified in parenthesis INT(size) -2147483648 to 2147483647 normal. 0 to 4294967295 UNSIGNED*. The maximum number of digits may be specified in parenthesis BIGINT(size) -9223372036854775808 to 9223372036854775807 normal. 0 to 18446744073709551615 UNSIGNED*. The maximum number of digits may be specified in parenthesis FLOAT(size,d) A small number with a floating decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter DOUBLE(size,d) A large number with a floating decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter
24
DECIMAL(size,d) A DOUBLE stored as a string , allowing for a fixed decimal point. The maximum number of digits may be specified in the size parameter. The maximum number of digits to the right of the decimal point is specified in the d parameter *The integer types have an extra option called UNSIGNED. Normally, the integer goes from an negative to positive value. Adding the UNSIGNED attribute will move that range up so it starts at zero instead of a negative number.
Date types:
Data type DATE() Description A date. Format: YYYY-MM-DD Note: The supported range is from '1000-01-01' to '9999-12-31' *A date and time combination. Format: YYYY-MM-DD HH:MM:SS
DATETIME()
Note: The supported range is from '1000-01-01 00:00:00' to '9999-12-31 23:59:59' TIMESTAMP() *A timestamp. TIMESTAMP values are stored as the number of seconds since the Unix epoch ('1970-01-01 00:00:00' UTC). Format: YYYY-MM-DD HH:MM:SS Note: The supported range is from '1970-01-01 00:00:01' UTC to '203801-09 03:14:07' UTC A time. Format: HH:MM:SS Note: The supported range is from '-838:59:59' to '838:59:59' A year in two-digit or four-digit format. Note: Values allowed in four-digit format: 1901 to 2155. Values allowed in two-digit format: 70 to 69, representing years from 1970 to 2069 *Even if DATETIME and TIMESTAMP return the same format, they work very differently. In an INSERT or UPDATE query, the TIMESTAMP automatically set itself to the current date and time. TIMESTAMP also accepts various formats, like YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD, or YYMMDD.
TIME()
YEAR()
25
char(n) varchar(n) varchar(max) text Unicode strings: Data type nchar(n) nvarchar(n) nvarchar(max) ntext
Fixed-length character string. Maximum 8,000 characters Variable-length character string. Maximum 8,000 characters Variable-length character string. Maximum 1,073,741,824 characters Variable-length character string. Maximum 2GB of text data
Description Fixed-length Unicode data. Maximum 4,000 characters Variable-length Unicode data. Maximum 4,000 characters Variable-length Unicode data. Maximum 536,870,912 characters Variable-length Unicode data. Maximum 2GB of text data
Storage
Binary types:
Data type Bit binary(n) varbinary(n) varbinary(max) Image Description Allows 0, 1, or NULL Fixed-length binary data. Maximum 8,000 bytes Variable-length binary data. Maximum 8,000 bytes Variable-length binary data. Maximum 2GB Variable-length binary data. Maximum 2GB Storage
2.7SQL SYNTAX
26
Database Tables
A database most often contains one or more tables. Each table is identified by a name (e.g. "Customers" or "Orders"). Tables contain records (rows) with data. Below is an example of a table called "Persons": P_Id 1 2 3 LastName Hansen Svendson Pettersen FirstName Ola Tove Kari Address Timoteivn 10 Borgvn 23 Storgt 20 City Sandnes Sandnes Stavanger
The table above contains three records (one for each person) and five columns (P_Id, LastName, FirstName, Address, and City).
SQL Statements
Most of the actions you need to perform on a database are done with SQL statements. The following SQL statement will select all the records in the "Persons" table: SELECT * FROM Persons In this tutorial we will teach you all about the different SQL statements.
The query and update commands form the DML part of SQL:
SELECT - extracts data from a database UPDATE - updates data in a database DELETE - deletes data from a database INSERT INTO - inserts new data into a database
The DDL part of SQL permits database tables to be created or deleted. It also define indexes (keys), specify links between tables, and impose constraints between tables. The most important DDL statements in SQL are:
CREATE DATABASE - creates a new database ALTER DATABASE - modifies a database CREATE TABLE - creates a new table ALTER TABLE - modifies a table DROP TABLE - deletes a table CREATE INDEX - creates an index (search key) DROP INDEX - deletes an index
FirstName varchar(255), Address varchar(255), City varchar(255) ) The P_Id column is of type int and will hold a number. The LastName, FirstName, Address, and City columns are of type varchar with a maximum length of 255 characters. The empty "Persons" table will now look like this: P_Id LastName FirstName Address City
The empty table can be filled with data with the INSERT INTO statement. The INSERT INTO statement is used to insert new records in a table.
29
Pettersen
Kari
Storgt 20
Stavanger
Now we want to insert a new row in the "Persons" table. We use the following SQL statement: INSERT INTO Persons VALUES (4,'Nilsen', 'Johan', 'Bakken 2', 'Stavanger') The "Persons" table will now look like this: P_Id 1 2 3 4 LastName Hansen Svendson Pettersen Nilsen FirstName Ola Tove Kari Johan Address Timoteivn 10 Borgvn 23 Storgt 20 Bakken 2 City Sandnes Sandnes Stavanger Stavanger
INSERT INTO Persons (P_Id, LastName, FirstName) VALUES (5, 'Tjessem', 'Jakob')
The "Persons" table will now look like this: P_Id 1 2 3 4 5 LastName Hansen Svendson Pettersen Nilsen Tjessem FirstName Ola Tove Kari Johan Jakob Address Timoteivn 10 Borgvn 23 Storgt 20 Bakken 2 City Sandnes Sandnes Stavanger Stavanger
30
Now we want to select the content of the columns named "LastName" and "FirstName" from the table above.
We use the following SELECT statement: SELECT LastName,FirstName FROM Persons The result-set will look like this: LastName Hansen Svendson Pettersen FirstName Ola Tove Kari
SELECT * Example
31
Now we want to select all the columns from the "Persons" table. We use the following SELECT statement: SELECT * FROM Persons Tip: The asterisk (*) is a quick way of selecting all columns! The result-set will look like this: P_Id 1 2 3 LastName Hansen Svendson Pettersen FirstName Ola Tove Kari Address Timoteivn 10 Borgvn 23 Storgt 20 City Sandnes Sandnes Stavanger
32
Now we want to select only the distinct values from the column named "City" from the table above. We use the following SELECT statement: SELECT DISTINCT City FROM Persons The result-set will look like this: City Sandnes Stavanger
33
4 5
Nilsen Tjessem
Johan Jakob
Bakken 2
Stavanger
Now we want to update the person "Tjessem, Jakob" in the "Persons" table. We use the following SQL statement: UPDATE Persons SET Address='Nissestien 67', City='Sandnes' WHERE LastName='Tjessem' AND FirstName='Jakob' The "Persons" table will now look like this: P_Id 1 2 3 4 5 LastName Hansen Svendson Pettersen Nilsen Tjessem FirstName Ola Tove Kari Johan Jakob Address Timoteivn 10 Borgvn 23 Storgt 20 Bakken 2 Nissestien 67 City Sandnes Sandnes Stavanger Stavanger Sandnes
34
Now we want to delete the person "Tjessem, Jakob" in the "Persons" table. We use the following SQL statement: DELETE FROM Persons WHERE LastName='Tjessem' AND FirstName='Jakob' The "Persons" table will now look like this: P_Id 1 2 3 4 LastName Hansen Svendson Pettersen Nilsen FirstName Ola Tove Kari Johan Address Timoteivn 10 Borgvn 23 Storgt 20 Bakken 2 City Sandnes Sandnes Stavanger Stavanger
35
Now we want to select only the persons living in the city "Sandnes" from the table above. We use the following SELECT statement: SELECT * FROM Persons WHERE City='Sandnes'
P_Id
LastName
FirstName 36
Address
City
1 2
Hansen Svendson
Ola Tove
Timoteivn 10 Borgvn 23
Sandnes Sandnes
37
= Equal <> Not equal > Greater than < Less than >= Greater than or equal <= Less than or equal BETWEEN Between an inclusive range LIKE Search for a pattern IN If you know the exact value you want to return for at least one of the columns Note: In some versions of SQL the <> operator may be written as !=
38
Now we want to add a column named "DateOfBirth" in the "Persons" table. We use the following SQL statement: ALTER TABLE Persons ADD DateOfBirth date Notice that the new column, "DateOfBirth", is of type date and is going to hold a date. The data type specifies what type of data the column can hold. For a complete reference of all the data types available in MS Access, MySQL, and SQL Server, go to our complete Data Types refrence. The "Persons" table will now like this: P_Id 1 2 3 LastName Hansen Svendson Pettersen FirstName Ola Tove Kari Address Timoteivn 10 Borgvn 23 Storgt 20 City Sandnes Sandnes Stavanger DateOfBirth
39
Notice that the "DateOfBirth" column is now of type year and is going to hold a year in a two-digit or four-digit format.
The "Persons" table will now like this: P_Id 1 2 3 LastName Hansen Svendson Pettersen FirstName Ola Tove Kari Address Timoteivn 10 Borgvn 23 Storgt 20 City Sandnes Sandnes Stavanger
View is a virtual table. This chapter shows how to create, update, and delete a view.
40
FROM table_name WHERE condition Note: A view always shows up-to-date data! The database engine recreates the data, using the view's SQL statement, every time a user queries a view.
41
SELECT * FROM [Category Sales For 1997] We can also add a condition to the query. Now we want to see the total sale only for the category "Beverages": SELECT * FROM [Category Sales For 1997] WHERE CategoryName='Beverages'
3.1SQL Constraints
Constraints are used to limit the type of data that can go into a table. Constraints can be specified when a table is created (with the CREATE TABLE statement) or after the table is created (with the ALTER TABLE statement). We will focus on the following constraints:
43
The UNIQUE constraint uniquely identifies each record in a database table. The UNIQUE and PRIMARY KEY constraints both provide a guarantee for uniqueness for a column or set of columns. A PRIMARY KEY constraint automatically has a UNIQUE constraint defined on it. Note that you can have many UNIQUE constraints per table, but only one PRIMARY KEY constraint per table.
44
CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName) )
45
LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName) )
47
The "Orders" table: O_Id 1 2 3 4 OrderNo 77895 44678 22456 24562 P_Id 3 3 2 1
Note that the "P_Id" column in the "Orders" table points to the "P_Id" column in the "Persons" table. The "P_Id" column in the "Persons" table is the PRIMARY KEY in the "Persons" table. The "P_Id" column in the "Orders" table is a FOREIGN KEY in the "Orders" table. The FOREIGN KEY constraint is used to prevent actions that would destroy links between tables. The FOREIGN KEY constraint also prevents that invalid data form being inserted into the foreign key column, because it has to be one of the values contained in the table it points to.
48
MySQL: CREATE TABLE Orders ( O_Id int NOT NULL, OrderNo int NOT NULL, P_Id int, PRIMARY KEY (O_Id), FOREIGN KEY (P_Id) REFERENCES Persons(P_Id) ) SQL Server / Oracle / MS Access: CREATE TABLE Orders ( O_Id int NOT NULL PRIMARY KEY, OrderNo int NOT NULL, P_Id int FOREIGN KEY REFERENCES Persons(P_Id) ) To allow naming of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax: MySQL / SQL Server / Oracle / MS Access: CREATE TABLE Orders ( O_Id int NOT NULL, OrderNo int NOT NULL, P_Id int, PRIMARY KEY (O_Id), CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id) REFERENCES Persons(P_Id) )
49
To allow naming of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax: MySQL / SQL Server / Oracle / MS Access: ALTER TABLE Orders ADD CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
50
My SQL: CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CHECK (P_Id>0) ) SQL Server / Oracle / MS Access: CREATE TABLE Persons ( P_Id int NOT NULL CHECK (P_Id>0), LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255) ) To allow naming of a CHECK constraint, and for defining a CHECK constraint on multiple columns, use the following SQL syntax: MySQL / SQL Server / Oracle / MS Access: CREATE TABLE Persons ( P_Id int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes') )
51
MySQL / SQL Server / Oracle / MS Access: ALTER TABLE Persons ADD CHECK (P_Id>0) To allow naming of a CHECK constraint, and for defining a CHECK constraint on multiple columns, use the following SQL syntax: MySQL / SQL Server / Oracle / MS Access: ALTER TABLE Persons ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
52
The DEFAULT constraint can also be used to insert system values, by using functions like GETDATE(): CREATE TABLE Orders ( O_Id int NOT NULL, OrderNo int NOT NULL, P_Id int, OrderDate date DEFAULT GETDATE() )
53
Now we want to find the total sum (total order) of each customer. We will have to use the GROUP BY statement to group the customers. We use the following SQL statement: SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer The result-set will look like this: Customer Hansen Nilsen Jensen SUM(OrderPrice) 2000 1700 2000
Let's see what happens if we omit the GROUP BY statement: SELECT Customer,SUM(OrderPrice) FROM Orders The result-set will look like this: Customer Hansen Nilsen Hansen Hansen Jensen Nilsen SUM(OrderPrice) 5700 5700 5700 5700 5700 5700
The result-set above is not what we wanted. Explanation of why the above SELECT statement cannot be used: The SELECT statement above has two columns specified (Customer and SUM(OrderPrice). The "SUM(OrderPrice)" returns a single value (that is the total sum of the "OrderPrice" column), while "Customer" returns 6 values (one value for each row in the "Orders" table). This will therefore not give us the correct result. However, you have seen that the GROUP BY statement solves this problem.
55
Now we want to find if any of the customers have a total order of less than 2000. We use the following SQL statement: SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer HAVING SUM(OrderPrice)<2000 The result-set will look like this: Customer Nilsen SUM(OrderPrice) 1700
Now we want to find if the customers "Hansen" or "Jensen" have a total order of more than 1500. We add an ordinary WHERE clause to the SQL statement: SELECT Customer,SUM(OrderPrice) FROM Orders WHERE Customer='Hansen' OR Customer='Jensen' GROUP BY Customer HAVING SUM(OrderPrice)>1500 The result-set will look like this: Customer Hansen Jensen SUM(OrderPrice) 2000 2000
56
SQL joins are used to query data from two or more tables, based on a relationship between certain columns in these tables.
3.4SQL JOIN
The JOIN keyword is used in an SQL statement to query data from two or more tables, based on a relationship between certain columns in these tables. Tables in a database are often related to each other with keys. A primary key is a column (or a combination of columns) with a unique value for each row. Each primary key value must be unique within the table. The purpose is to bind data together, across tables, without repeating all of the data in every table. Look at the "Persons" table: P_Id 1 2 3 LastName Hansen Svendson Pettersen FirstName Ola Tove Kari Address Timoteivn 10 Borgvn 23 Storgt 20 City Sandnes Sandnes Stavanger
Note that the "P_Id" column is the primary key in the "Persons" table. This means that no two rows can have the same P_Id. The P_Id distinguishes two persons even if they have the same name. Next, we have the "Orders" table: O_Id 1 2 3 4 5 OrderNo 77895 44678 22456 24562 34764 P_Id 3 3 1 1 15
Note that the "O_Id" column is the primary key in the "Orders" table and that the "P_Id" column refers to the persons in the "Persons" table without using their names. Notice that the relationship between the two tables above is the "P_Id" columns
57
JOIN: Return rows when there is at least one match in both tables LEFT JOIN: Return all rows from the left table, even if there are no matches in the right table RIGHT JOIN: Return all rows from the right table, even if there are no matches in the left table FULL JOIN: Return rows when there is a match in one of the tables
58
4 5
24562 34764
1 15
Now we want to list all the persons with any orders. We use the following SELECT statement: SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons INNER JOIN Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName The result-set will look like this: LastName Hansen Hansen Pettersen Pettersen FirstName Ola Ola Kari Kari OrderNo 22456 24562 77895 44678
The INNER JOIN keyword return rows when there is at least one match in both tables. If there are rows in "Persons" that do not have matches in "Orders", those rows will NOT be listed.
59
The "Orders" table: O_Id 1 2 3 4 5 OrderNo 77895 44678 22456 24562 34764 P_Id 3 3 1 1 15
Now we want to list all the persons and their orders - if any, from the tables above. We use the following SELECT statement: SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons LEFT JOIN Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName The result-set will look like this: LastName Hansen Hansen Pettersen Pettersen Svendson FirstName Ola Ola Kari Kari Tove OrderNo 22456 24562 77895 44678
60
The LEFT JOIN keyword returns all the rows from the left table (Persons), even if there are no matches in the right table (Orders).
The "Orders" table: O_Id 1 2 3 4 5 OrderNo 77895 44678 22456 24562 34764 P_Id 3 3 1 1 15
Now we want to list all the orders with containing persons - if any, from the tables above. We use the following SELECT statement:
61
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons RIGHT JOIN Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName
The result-set will look like this: LastName Hansen Hansen Pettersen Pettersen FirstName Ola Ola Kari Kari OrderNo 22456 24562 77895 44678 34764
The RIGHT JOIN keyword returns all the rows from the right table (Orders), even if there are no matches in the left table (Persons).
62
O_Id 1 2 3 4 5
P_Id 3 3 1 1 15
Now we want to list all the persons and their orders, and all the orders with their persons. We use the following SELECT statement: SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons FULL JOIN Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName The result-set will look like this: LastName Hansen Hansen Pettersen Pettersen Svendson FirstName Ola Ola Kari Kari Tove OrderNo 22456 24562 77895 44678 34764 The FULL JOIN keyword returns all the rows from the left table (Persons), and all the rows from the right table (Orders). If there are rows in "Persons" that do not have matches in "Orders", or if there are rows in "Orders" that do not have matches in "Persons", those rows will be listed as well.
UNION SELECT column_name(s) FROM table_name2 Note: The UNION operator selects only distinct values by default. To allow duplicate values, use UNION ALL.
Now we want to list all the different employees in Norway and USA. We use the following SELECT statement: SELECT E_Name FROM Employees_Norway UNION SELECT E_Name FROM Employees_USA The result-set will look like this:
64
E_Name Hansen, Ola Svendson, Tove Svendson, Stephen Pettersen, Kari Turner, Sally Kent, Clark Scott, Stephen Note: This command cannot be used to list all employees in Norway and USA. In the example above we have two employees with equal names, and only one of them will be listed. The UNION command selects only distinct values.
65
4.1Indexes
An index can be created in a table to find data more quickly and efficiently. The users cannot see the indexes, they are just used to speed up searches/queries. Note: Updating a table with indexes takes more time than updating a table without (because the indexes also need an update). So you should only create indexes on columns (and tables) that will be frequently searched against.
CREATE INDEX Example The SQL statement below creates an index named "PIndex" on the "LastName" column in the "Persons" table: CREATE INDEX PIndex ON Persons (LastName) If you want to create an index on a combination of columns, you can list the column names within the parentheses, separated by commas: CREATE INDEX PIndex ON Persons (LastName, FirstName)
4.5CREATE SEQUENCE
Purpose
Use the CREATE SEQUENCE statement to create a sequence, which is a database object from which multiple users may generate unique integers. You can use sequences to automatically generate primary key values. When a sequence number is generated, the sequence is incremented, independent of the transaction committing or rolling back. If two users concurrently increment the same sequence, the sequence numbers each user acquires may have gaps because sequence numbers are being generated by the other user. One user can never acquire the sequence 67
number generated by another user. Once a sequence value is generated by one user, that user can continue to access that value regardless of whether the sequence is incremented by another user. Sequence numbers are generated independently of tables, so the same sequence can be used for one or for multiple tables. It is possible that individual sequence numbers will appear to be skipped, because they were generated and used in a transaction that ultimately rolled back. Additionally, a single user may not realize that other users are drawing from the same sequence. Once a sequence is created, you can access its values in SQL statements with the CURRVAL pseudocolumn (which returns the current value of the sequence) or the NEXTVAL pseudocolumn (which increments the sequence and returns the new value). Prerequisites To create a sequence in your own schema, you must have the CREATE SEQUENCE system privilege. To create a sequence in another user's schema, you must have the CREATE ANY SEQUENCE system privilege. Syntax create_sequence::=
Semantics
schema
Specify the schema to contain the sequence. If you omit schema, then Oracle Database creates the sequence in your own schema.
sequence
Specify the name of the sequence to be created. If you specify none of the following clauses, then you create an ascending sequence that starts with 1 and increases by 1 with no upper limit. Specifying only INCREMENT BY -1 creates a descending sequence that starts with -1 and decreases with no lower limit.
To create a sequence that increments without bound, for ascending sequences, omit the MAXVALUE parameter or specify NOMAXVALUE. For descending sequences, omit the MINVALUE parameter or specify the NOMINVALUE. To create a sequence that stops at a predefined limit, for an ascending sequence, specify a value for the MAXVALUE parameter. For a descending sequence, specify a value for the MINVALUE parameter. Also specify NOCYCLE. Any attempt to generate a sequence number once the sequence has reached its limit results in an error. To create a sequence that restarts after reaching a predefined limit, specify values for both the MAXVALUE and MINVALUE parameters. Also specify CYCLE. If you do not specify MINVALUE, then it defaults to NOMINVALUE, which is the value 1.
INCREMENT BY Specify the interval between sequence numbers. This integer value can be any positive or negative integer, but it cannot be 0. This value can have 28 or fewer digits. The absolute of this value must be less than the difference of MAXVALUE and MINVALUE. If this value is negative, then the sequence descends. If the value is positive, then the sequence ascends. If you omit this clause, then the interval defaults to 1. START WITH
69
Specify the first sequence number to be generated. Use this clause to start an ascending sequence at a value greater than its minimum or to start a descending sequence at a value less than its maximum. For ascending sequences, the default value is the minimum value of the sequence. For descending sequences, the default value is the maximum value of the sequence. This integer value can have 28 or fewer digits.
Note: This value is not necessarily the value to which an ascending cycling sequence cycles after reaching its maximum or minimum value.
MAXVALUE Specify the maximum value the sequence can generate. This integer value can have 28 or fewer digits. MAXVALUE must be equal to or greater than START WITH and must be greater than MINVALUE. NOMAXVALUE Specify NOMAXVALUE to indicate a maximum value of 1027 for an ascending sequence or -1 for a descending sequence. This is the default. MINVALUE Specify the minimum value of the sequence. This integer value can have 28 or fewer digits. MINVALUE must be less than or equal to START WITH and must be less than MAXVALUE. NOMINVALUE Specify NOMINVALUE to indicate a minimum value of 1 for an ascending sequence or -1026 for a descending sequence. This is the default. CYCLE Specify CYCLE to indicate that the sequence continues to generate values after reaching either its maximum or minimum value. After an ascending sequence reaches its maximum value, it generates its minimum value. After a descending sequence reaches its minimum, it generates its maximum value.
70
NOCYCLE Specify NOCYCLE to indicate that the sequence cannot generate more values after reaching its maximum or minimum value. This is the default. CACHE Specify how many values of the sequence the database preallocates and keeps in memory for faster access. This integer value can have 28 or fewer digits. The minimum value for this parameter is 2. For sequences that cycle, this value must be less than the number of values in the cycle. You cannot cache more values than will fit in a given cycle of sequence numbers. Therefore, the maximum value allowed for CACHE must be less than the value determined by the following formula:
(CEIL (MAXVALUE - MINVALUE)) / ABS (INCREMENT)
If a system failure occurs, all cached sequence values that have not been used in committed DML statements are lost. The potential number of lost values is equal to the value of the CACHE parameter.
Note: Oracle recommends using the CACHE setting to enhance performance if you are using sequences in a Real Application Clusters environment.
NOCACHE Specify NOCACHE to indicate that values of the sequence are not preallocated. If you omit both CACHE and NOCACHE, the database caches 20 sequence numbers by default. ORDER Specify ORDER to guarantee that sequence numbers are generated in order of request. This clause is useful if you are using the sequence numbers as timestamps. Guaranteeing order is usually not important for sequences used to generate primary keys. is necessary only to guarantee ordered generation if you are using Oracle Database with Real Application Clusters. If you are using exclusive mode, sequence numbers are always generated in order.
ORDER
71
NOORDER Specify NOORDER if you do not want to guarantee sequence numbers are generated in order of request. This is the default. Example Creating a Sequence: Example The following statement creates the sequence customers_seq in the sample schema oe. This sequence could be used to provide customer ID numbers when rows are added to the customers table.
CREATE SEQUENCE customers_seq START WITH 1000 INCREMENT BY 1 NOCACHE NOCYCLE;
4.6ALTER SEQUENCE
Purpose
Use the ALTER SEQUENCE statement to change the increment, minimum and maximum values, cached numbers, and behavior of an existing sequence. This statement affects only future sequence numbers. See Also: CREATE SEQUENCE for additional information on sequences
Prerequisites
The sequence must be in your own schema, or you must have the ALTER object privilege on the sequence, or you must have the ALTER ANY SEQUENCE system privilegeSyntax
alter_sequence::=
72
To restart the sequence at a different number, you must drop and re-create it. If you change the INCREMENT BY value before the first invocation of NEXTVAL, some sequence numbers will be skipped. Therefore, if you want to retain the original START WITH value, you must drop the sequence and re-create it with the original START WITH value and the new INCREMENT BY value. Oracle performs some validations. For example, a new MAXVALUE cannot be imposed that is less than the current sequence number.
This statement turns on CYCLE and CACHE for the customers_seq sequence:
4.7DROP SEQUENCE
73
Purpose
Use the DROP SEQUENCE statement to remove a sequence from the database. You can also use this statement to restart a sequence by dropping and then re-creating it. For example, if you have a sequence with a current value of 150 and you would like to restart the sequence with a value of 27, then you can drop the sequence and then re-create it with the same name and a START WITH value of 27.
Prerequisites
The sequence must be in your own schema or you must have the DROP ANY SEQUENCE system privilege.
Syntax
drop_sequence::=
schema
Specify the schema containing the sequence. If you omit schema, then Oracle assumes the sequence is in your own schema.
sequence_name
Specify the name of the sequence to be dropped.
74
5.1Security Management
Because you have just one system to administer, you do not have to replicate basic security tasks such as these:
Creating user accounts Creating and administering rules for password protection Securing network connections Detecting and eliminating security vulnerabilities Safeguarding the system from intruders
The cornerstone of data security is the administration of user accounts and roles. Users open a connection with Oracle Database with a user name and password, and they have access to both dimensional and relational objects in the same session.
5.1(a)Types of Security
Users by default have no access rights to an analytic workspace or any other data type in another user's schema. The owner or an administrator must grant them, or a role to which they belong, any access privileges. Oracle OLAP provides two types of security: Object security and data security.
Object security provides access to dimensional objects. You must set object security before other users can access them. Object security is implemented using SQL GRANT and REVOKE. Data security provides fine-grained control of the data on a cellular level. This type of security is optional. You only need to define data security policies when you want to restrict access to specific areas of a cube. Data security is implemented using the XML DB security of Oracle Database.
75
You can administer both data security and object security in Analytic Workspace Manager. For object security, you also have the option of using SQL GRANT and REVOKE.
Alter: Change the definition of a cube or dimension. Users need this privilege to create and modify a dimensional model. Delete: Remove old dimension members. Users need this privilege to refresh a dimension. Insert: Add new dimension members. Users need this privilege to refresh a dimension. Select: Query the cube or dimension. Users need this privilege to query a view of the cube or dimension or to use the CUBE_TABLE function. CUBE_TABLE is a SQL function that returns the values of a dimensional object. Update: Change the data values of a cube or the name of a dimension member. Users need this privilege to refresh a dimension or cube.
Users exercise these privileges either using Analytic Workspace Manager to create and administer dimensional objects, or by using SQL to query them. They do not issue commands such as SQL INSERT and UPDATE directly on the cubes and dimensions
5.3Layered Security
For dimensional objects, you can manage security at these levels:
The privileges are layered so that, for example, a user with SELECT data security on Software products must also have SELECT object security on the PRODUCT dimension and the Global analytic workspace. Users also need SELECT privileges on the views of the dimensional objects.
76
77
78
Block Structures: PL SQL consists of blocks of code, which can be nested within each other. Each block forms a unit of a task or a logical module. PL/SQL Blocks can be stored in the database and reused. Procedural Language Capability: PL SQL consists of procedural language constructs such as conditional statements (if else statements) and loops like (FOR loops). Better Performance: PL SQL engine processes multiple SQL statements simultaneously as a single block, thereby reducing network traffic. Error Handling: PL/SQL handles errors or exceptions effectively during the execution of a PL/SQL program. Once an exception is caught, specific actions can be taken depending upon the type of the exception or it can be displayed to the user with a message.
6.2Character Set
You write a PL/SQL program as lines of text using a specific set of characters. The PL/SQL character set includes the upper- and lower-case letters A .. Z and a .. z the numerals 0 .. 9 the symbols ( ) + - * / < > = ! ~ ^ ; : . ' @ % , " # $ & _ | { } ? [ ] tabs, spaces, and carriage returns PL/SQL is not case sensitive, so lower-case letters are equivalent to corresponding uppercase letters except within string and character literals.
6.3Lexical Units
A line of PL/SQL text contains groups of characters known as lexical units, which can be classified as follows: delimiters (simple and compound symbols) identifiers, which include reserved words literals comments
79
To improve readability, you can separate lexical units by spaces. In fact, you must separate adjacent identifiers by a space or punctuation. The following line is not allowed because the reserved words END and IF are joined:
IF x > y THEN high := x; ENDIF; -- not allowed
However, you cannot embed spaces in lexical units except for string literals and comments. For example, the following line is not allowed because the compound symbol for assignment (:=) is split:
count : = count + 1; -- not allowed
To show structure, you can divide lines using carriage returns and indent lines using spaces or tabs. Compare these IF statements for readability:
IF x>y THEN max:=x;ELSE max:=y;END IF; | | | | | IF x > y THEN max := x; ELSE max := y; END IF;
6.4Delimiters
A delimiter is a simple or compound symbol that has a special meaning to PL/SQL. For example, you use delimiters to represent arithmetic operations such as addition and subtraction. Simple symbols consist of one character. A list follows: Symbol
+ % ' . / ( ) : , * "
Meaning addition operator attribute indicator character string delimiter component selector division operator expression or list delimiter expression or list delimiter host variable indicator item separator multiplication operator quoted identifier delimiter
80
Symbol
= < > @ ; -
Meaning relational operator relational operator relational operator remote access indicator statement terminator subtraction/negation operator
Meaning assignment operator association operator concatenation operator exponentiation operator label delimiter (begin) label delimiter (end) multi-line comment delimiter (begin) multi-line comment delimiter (end) range operator relational operator relational operator relational operator relational operator relational operator relational operator single-line comment indicator
6.5Identifiers
You use identifiers to name PL/SQL program items and units, which include constants, variables, exceptions, cursors, cursor variables, subprograms, and packages. Some examples of identifiers follow:
81
An identifier consists of a letter optionally followed by more letters, numerals, dollar signs, underscores, and number signs. Other characters such as hyphens, slashes, and spaces are not allowed, as the following examples show:
mine&yours debit-amount on/off user id ----not not not not allowed allowed allowed allowed because because because because of of of of ampersand hyphen slash space
The next examples show that adjoining and trailing dollar signs, underscores, and number signs are allowed:
money$$$tree SN## try_again_
You can use upper, lower, or mixed case to write identifiers. PL/SQL is not case sensitive except within string and character literals. So, if the only difference between identifiers is the case of corresponding letters, PL/SQL considers the identifiers to be the same, as the following example shows:
lastname LastName LASTNAME -- same as lastname -- same as lastname and LastName
The size of an identifier cannot exceed 30 characters. But, every character, including dollar signs, underscores, and number signs, is significant. For example, PL/SQL considers the following identifiers to be different:
lastname last_name
Identifiers should be descriptive. So, avoid obscure names such as cpm. Instead, use meaningful names such as cost_per_thousand.
82
6.6Reserved Words
Some identifiers, called reserved words, have a special syntactic meaning to PL/SQL and so should not be redefined. For example, the words BEGIN and END, which bracket the executable part of a block or subprogram, are reserved. As the next example shows, if you try to redefine a reserved word, you get a compilation error:
DECLARE end BOOLEAN; -- not allowed; causes compilation error
However, you can embed reserved words in an identifier, as the following example shows:
DECLARE end_of_game BOOLEAN; -- allowed
Often, reserved words are written in upper case to promote readability. However, like other PL/SQL identifiers, reserved words can be written in lower or mixed case. For a list of reserved words, see appendixf
6.7redefined Identifiers
Identifiers globally declared in package STANDARD, such as the exception INVALID_NUMBER, can be redeclared. However, redeclaring predefined identifiers is error prone because your local declaration overrides the global declaration.
Quoted Identifiers
For flexibility, PL/SQL lets you enclose identifiers within double quotes. Quoted identifiers are seldom needed, but occasionally they can be useful. They can contain any sequence of printable characters including spaces but excluding double quotes. Thus, the following identifiers are valid:
"X+Y" "last name" "on/off switch" "employee(s)" "*** header info ***"
The maximum size of a quoted identifier is 30 characters not counting the double quotes. Though allowed, using PL/SQL reserved words as quoted identifiers is a poor programming practice. Some PL/SQL reserved words are not reserved by SQL. For example, you can use the PL/SQL reserved word TYPE in a CREATE TABLE statement to name a database column. 83
But, if a SQL statement in your program refers to that column, you get a compilation error, as the following example shows:
SELECT acct, type, bal INTO ... -- causes compilation error
To prevent the error, enclose the uppercase column name in double quotes, as follows:
SELECT acct, "TYPE", bal INTO ...
The column name cannot appear in lower or mixed case (unless it was defined that way in the CREATE TABLE statement). For example, the following statement is invalid:
SELECT acct, "type", bal INTO ... -- causes compilation error
Alternatively, you can create a view that renames the troublesome column, then use the view instead of the base table in SQL statements.
6.8Literals
A literal is an explicit numeric, character, string, or Boolean value not represented by an identifier. The numeric literal 147 and the Boolean literal FALSE are examples.
Numeric Literals
Two kinds of numeric literals can be used in arithmetic expressions: integers and reals. An integer literal is an optionally signed whole number without a decimal point. Some examples follow:
030 6 -14 0 +32767
A real literal is an optionally signed whole or fractional number with a decimal point. Several examples follow:
6.6667 0.0 -12.0 3.14159 +8300.00 .5 25.
PL/SQL considers numbers such as 12.0 and 25. to be reals even though they have integral values. Numeric literals cannot contain dollar signs or commas, but can be written using scientific notation. Simply suffix the number with an E (or e) followed by an optionally signed integer. A few examples follow:
2E5 1.0E-7 3.14159e0 -1E38 -9.5e-3
84
stands for "times ten to the power of." As the next example shows, the number after E is the power of ten by which the number before E must be multiplied (the double asterisk (**) is the exponentiation operator):
E 5E3 = 5 * 10**3 = 5 * 1000 = 5000
The number after E also corresponds to the number of places the decimal point shifts. In the last example, the implicit decimal point shifted three places to the right. In this example, it shifts three places to the left:
5E-3 = 5 * 10**-3 = 5 * 0.001 = 0.005
As the following example shows, if the value of a numeric literal falls outside the range 1E-130 .. 10E125, you get a compilation error:
DECLARE n NUMBER; BEGIN n := 10E127;
Character Literals
A character literal is an individual character enclosed by single quotes (apostrophes). Character literals include all the printable characters in the PL/SQL character set: letters, numerals, spaces, and special symbols. Some examples follow:
'Z' '%' '7' ' ' 'z' '('
PL/SQL is case sensitive within character literals. For example, PL/SQL considers the literals 'Z' and 'z' to be different. Also, the character literals '0'..'9' are not equivalent to integer literals but can be used in arithmetic expressions because they are implicitly convertible to integers.
String Literals
A character value can be represented by an identifier or explicitly written as a string literal, which is a sequence of zero or more characters enclosed by single quotes. Several examples follow:
'Hello, world!' 'XYZ Corporation' '10-NOV-91' 'He said "Life is like licking honey from a thorn."' '$1,000,000'
85
All string literals except the null string ('') have datatype CHAR. Given that apostrophes (single quotes) delimit string literals, how do you represent an apostrophe within a string? As the next example shows, you write two single quotes, which is not the same as writing a double quote:
'Don''t leave without saving your work.'
PL/SQL is case sensitive within string literals. For example, PL/SQL considers the following literals to be different:
'baker' 'Baker'
Boolean Literals
Boolean literals are the predefined values TRUE, FALSE, and NULL (which stands for a missing, unknown, or inapplicable value). Remember, Boolean literals are values, not strings. For example, TRUE is no less a value than the number 25.
Datetime Literals
Datetime literals have various formats depending on the datatype. For example:
DECLARE d1 DATE := DATE '1998-12-25'; t1 TIMESTAMP := TIMESTAMP '1997-10-22 13:01:01'; t2 TIMESTAMP WITH TIME ZONE := TIMESTAMP '1997-01-31 09:26:56.66 +02:00'; -- Three years and two months -- (For greater precision, we would use the day-to-second interval) i1 INTERVAL YEAR TO MONTH := INTERVAL '3-2' YEAR TO MONTH; -- Five days, four hours, three minutes, two and 1/100 seconds i2 INTERVAL DAY TO SECOND := INTERVAL '5 04:03:02.01' DAY TO SECOND; ...
You can also specify whether a given interval value is YEAR TO MONTH or DAY TO SECOND. For example, current_timestamp - current_timestamp produces a value of type INTERVAL DAY TO SECOND by default. You can specify the type of the interval using the formats:
(interval_expression) DAY TO SECOND (interval_expression) YEAR TO MONTH
86
The PL/SQL compiler ignores comments, but you should not. Adding comments to your program promotes readability and aids understanding. Generally, you use comments to describe the purpose and use of each code segment. PL/SQL supports two comment styles: single-line and multi-line.
6.9Single-Line Comments
Single-line comments begin with a double hyphen (--) anywhere on a line and extend to the end of the line. A few examples follow:
-- begin processing SELECT sal INTO salary FROM emp -- get current salary WHERE empno = emp_id; bonus := salary * 0.15; -- compute bonus amount
Notice that comments can appear within a statement at the end of a line. While testing or debugging a program, you might want to disable a line of code. The following example shows how you can "comment-out" the line:
-- DELETE FROM emp WHERE comm IS NULL;
Multi-line Comments
Multi-line comments begin with a slash-asterisk (/*), end with an asterisk-slash (*/), and can span multiple lines. Some examples follow:
BEGIN ... /* Compute a 15% bonus for top-rated employees. */ IF rating > 90 THEN bonus := salary * 0.15 /* bonus is based on salary */ ELSE bonus := 0; END IF; ... /* The following line computes the area of a circle using pi, which is the ratio between the circumference and diameter. */ area := pi * radius**2; END;
You can use multi-line comment delimiters to comment-out whole sections of code, as the following example shows:
/* LOOP FETCH c1 INTO emp_rec;
87
Restrictions on Comments
You cannot nest comments. Also, you cannot use single-line comments in a PL/SQL block that will be processed dynamically by an Oracle Precompiler program because endof-line characters are ignored. As a result, single-line comments extend to the end of the block, not just to the end of a line. So, use multi-line comments instead.
6.10Declarations
Your program stores values in variables and constants. As the program executes, the values of variables can change, but the values of constants cannot. You can declare variables and constants in the declarative part of any PL/SQL block, subprogram, or package. Declarations allocate storage space for a value, specify its datatype, and name the storage location so that you can reference it. A couple of examples follow:
birthday DATE; emp_count SMALLINT := 0;
The first declaration names a variable of type DATE. The second declaration names a variable of type SMALLINT and uses the assignment operator to assign an initial value of zero to the variable. The next examples show that the expression following the assignment operator can be arbitrarily complex and can refer to previously initialized variables:
pi REAL := 3.14159; radius REAL := 1; area REAL := pi * radius**2;
By default, variables are initialized to NULL. So, these declarations are equivalent:
birthday DATE; birthday DATE := NULL;
In the declaration of a constant, the keyword CONSTANT must precede the type specifier, as the following example shows:
88
This declaration names a constant of type REAL and assigns an initial (also final) value of 5000 to the constant. A constant must be initialized in its declaration. Otherwise, you get a compilation error when the declaration is elaborated. (The processing of a declaration by the PL/SQL compiler is called elaboration.)
Using DEFAULT
You can use the keyword DEFAULT instead of the assignment operator to initialize variables. For example, the declaration
blood_type CHAR := 'O';
Use DEFAULT for variables that have a typical value. Use the assignment operator for variables (such as counters and accumulators) that have no typical value. A couple of examples follow:
hours_worked INTEGER DEFAULT 40; employee_count INTEGER := 0;
You can also use DEFAULT to initialize subprogram parameters, cursor parameters, and fields in a user-defined record
You cannot assign nulls to a variable defined as NOT NULL. If you try, PL/SQL raises the predefined exception VALUE_ERROR. The NOT NULL constraint must be followed by an initialization clause. For example, the following declaration is not allowed:
acct_id INTEGER(5) NOT NULL; -- not allowed; not initialized
89
PL/SQL provide subtypes NATURALN and POSITIVEN that are predefined as NOT NULL. For instance, the following declarations are equivalent:
emp_count NATURAL NOT NULL := 0; emp_count NATURALN := 0;
In NATURALN and POSITIVEN declarations, the type specifier must be followed by an initialization clause. Otherwise, you get a compilation error. For example, the following declaration is not allowed:
line_items POSITIVEN; -- not allowed; not initialized
Using %TYPE
The %TYPE attribute provides the datatype of a variable or database column. In the following example, %TYPE provides the datatype of a variable:
credit REAL(7,2); debit credit%TYPE;
Variables declared using %TYPE are treated like those declared using a datatype specifier. For example, given the previous declarations, PL/SQL treats debit like a REAL(7,2) variable. The next example shows that a %TYPE declaration can include an initialization clause:
balance NUMBER(7,2); minimum_balance balance%TYPE := 10.00;
The %TYPE attribute is particularly useful when declaring variables that refer to database columns. You can reference a table and column, or you can reference an owner, table, and column, as in
my_dname scott.dept.dname%TYPE;
Using %TYPE to declare my_dname has two advantages. First, you need not know the exact datatype of dname. Second, if the database definition of dname changes, the datatype of my_dname changes accordingly at run time. However, %TYPE variables do not inherit the NOT NULL column constraint. In the next example, even though the database column empno is defined as NOT NULL, you can assign a null to the variable my_empno:
DECLARE my_empno emp.empno%TYPE; ...
90
-- this works
Using %ROWTYPE
The %ROWTYPE attribute provides a record type that represents a row in a table (or view). The record can store an entire row of data selected from the table or fetched from a cursor or strongly typed cursor variable. In the example below, you declare two records. The first record stores a row selected from the emp table. The second record stores a row fetched from cursor c1.
DECLARE emp_rec emp%ROWTYPE; CURSOR c1 IS SELECT deptno, dname, loc FROM dept; dept_rec c1%ROWTYPE;
Columns in a row and corresponding fields in a record have the same names and datatypes. However, fields in a %ROWTYPE record do not inherit the NOT NULL column constraint. In the following example, you select column values into record emp_rec:
BEGIN SELECT * INTO emp_rec FROM emp WHERE ...
The column values returned by the SELECT statement are stored in fields. To reference a field, you use dot notation. For example, you might reference the deptno field as follows:
IF emp_rec.deptno = 20 THEN ...
Also, you can assign the value of an expression to a specific field, as the following examples show:
emp_rec.ename := 'JOHNSON'; emp_rec.sal := emp_rec.sal * 1.15;
CREATE PACKAGE BODY emp_actions AS CURSOR c1 RETURN emp%ROWTYPE IS -- define cursor body SELECT * FROM emp WHERE sal > 3000;
91
In the first case, you simply use the procedure name. In the second case, you must qualify the name using dot notation because the procedure is stored in a package called emp_actions. In the third case, using the remote access indicator (@), you reference the database link newyork because the procedure is stored in a remote database. In the fourth case, you qualify the procedure name and reference a database link.
Synonyms
You can create synonyms to provide location transparency for remote schema objects such as tables, sequences, views, standalone subprograms, packages, and object types. However, you cannot create synonyms for items declared within subprograms or packages. That includes constants, variables, cursors, cursor variables, exceptions, and packaged subprograms.
Scoping
Within the same scope, all declared identifiers must be unique. So, even if their datatypes differ, variables and parameters cannot share the same name. In the following example, the second declaration is not allowed:
DECLARE valid_id BOOLEAN; valid_id VARCHAR2(5);
For the scoping rules that apply to identifiers, see "Scope and Visibility of PL/SQL Identifiers"
92
Case Sensitivity
Like all identifiers, the names of constants, variables, and parameters are not case sensitive. For instance, PL/SQL considers the following names to be the same:
DECLARE zip_code INTEGER; Zip_Code INTEGER;
-- same as zip_code
Name Resolution
In potentially ambiguous SQL statements, the names of database columns take precedence over the names of local variables and formal parameters. For example, the following DELETE statement removes all employees from the emp table, not just 'KING', because Oracle assumes that both enames in the WHERE clause refer to the database column:
DECLARE ename VARCHAR2(10) := 'KING'; BEGIN DELETE FROM emp WHERE ename = ename; ...
In such cases, to avoid ambiguity, prefix the names of local variables and formal parameters with my_, as follows:
DECLARE my_ename VARCHAR2(10);
The next example shows that you can use a subprogram name to qualify references to local variables and formal parameters:
FUNCTION bonus (deptno IN NUMBER, ...) RETURN REAL IS job CHAR(10); BEGIN SELECT ... WHERE deptno = bonus.deptno AND job = bonus.job; ...
93
The example below illustrates the scope rules. Notice that the identifiers declared in one sub-block cannot be referenced in the other sub-block. That is because a block cannot reference identifiers declared in other blocks nested at the same level.
DECLARE a CHAR; b REAL; BEGIN -- identifiers available here: a (CHAR), b DECLARE a INTEGER; c REAL; BEGIN -- identifiers available here: a (INTEGER), b, c END; DECLARE d REAL; BEGIN -- identifiers available here: a (CHAR), b, d END; -- identifiers available here: a (CHAR), b END;
Recall that global identifiers can be redeclared in a sub-block, in which case the local declaration prevails and the sub-block cannot reference the global identifier unless you use a qualified name. The qualifier can be the label of an enclosing block, as the following example shows:
<<outer>> DECLARE birthdate DATE; BEGIN DECLARE birthdate DATE; BEGIN ... IF birthdate = outer.birthdate THEN ... END; ... END;
As the next example shows, the qualifier can also be the name of an enclosing subprogram:
PROCEDURE check_credit (...) IS rating NUMBER; FUNCTION valid (...) RETURN BOOLEAN IS rating NUMBER; BEGIN ... IF check_credit.rating < 3 THEN ...
95
However, within the same scope, a label and a subprogram cannot have the same name.
Variable Assignment
Variables and constants are initialized every time a block or subprogram is entered. By default, variables are initialized to NULL. Unless you expressly initialize a variable, its value is undefined:
DECLARE count INTEGER; BEGIN -- COUNT began with a value of NULL. -- Thus the expression 'COUNT + 1' is also null. -- So after this assignment, COUNT is still NULL. count := count + 1;
To avoid unexpected results, never reference a variable before you assign it a value. You can use assignment statements to assign values to a variable. For example, the following statement assigns a new value to the variable bonus, overwriting its old value:
bonus := salary * 0.15;
The expression following the assignment operator can be arbitrarily complex, but it must yield a datatype that is the same as or convertible to the datatype of the variable.
96
When applied to an expression, the relational operators return a Boolean value. So, the following assignment is allowed:
done := (count > 500);
Unary operators such as the negation operator (-) operate on one operand; binary operators such as the division operator (/) operate on two operands. PL/SQL has no ternary operators. The simplest expressions consist of a single variable, which yields a value directly. PL/SQL evaluates (finds the current value of) an expression by combining the values of the operands in ways specified by the operators. This always yields a single value and datatype. PL/SQL determines the datatype by examining the expression and the context in which it appears.
97
Operator Precedence
The operations within an expression are done in a particular order depending on their precedence (priority). Table 2-1 shows the default order of operations from first to last (top to bottom).
Operation exponentiation identity, negation multiplication, division addition, subtraction, concatenation comparison logical negation conjunction inclusion
Operators with higher precedence are applied first. In the example below, both expressions yield 8 because division has a higher precedence than addition. Operators with the same precedence are applied in no particular order.
5 + 12 / 4 12 / 4 + 5
You can use parentheses to control the order of evaluation. For example, the following expression yields 7, not 11, because parentheses override the default operator precedence:
(8 + 6) / 2
In the next example, the subtraction is done before the division because the most deeply nested subexpression is always evaluated first:
100 + (20 / 5 + (7 - 3))
The following example shows that you can always use parentheses to improve readability, even when they are not needed:
98
Logical Operators
The logical operators AND, OR, and NOT follow the tri-state logic shown in Table 2-2 AND and OR are binary operators; NOT is a unary operator.
y
TRUE FALSE NULL TRUE FALSE NULL TRUE FALSE NULL
x AND y
TRUE FALSE NULL FALSE FALSE FALSE NULL FALSE NULL
x OR y
TRUE TRUE TRUE TRUE FALSE NULL TRUE NULL NULL
NOT x
FALSE FALSE FALSE TRUE TRUE TRUE NULL NULL NULL
As the truth table shows, AND returns TRUE only if both its operands are true. On the other hand, OR returns TRUE if either of its operands is true. NOT returns the opposite value (logical negation) of its operand. For example, NOT TRUE returns FALSE.
NOT NULL returns NULL because nulls are indeterminate. It follows NOT operator to a null, the result is also indeterminate. Be careful.
that if you apply the Nulls can cause unexpected results; see "Handling Null Values in Comparisons and Conditional Statements"
Order of Evaluation
When you do not use parentheses to specify the order of evaluation, operator precedence determines the order. Compare the following expressions:
NOT (valid AND done) | NOT valid AND done
If the Boolean variables valid and done have the value FALSE, the first expression yields TRUE. However, the second expression yields FALSE because NOT has a higher precedence than AND. Therefore, the second expression is equivalent to:
(NOT valid) AND done
99
In the following example, notice that when valid has the value FALSE, the whole expression yields FALSE regardless of the value of done:
valid AND done
Likewise, in the next example, when valid has the value TRUE, the whole expression yields TRUE regardless of the value of done:
valid OR done
Short-Circuit Evaluation
When evaluating a logical expression, PL/SQL uses short-circuit evaluation. That is, PL/SQL stops evaluating the expression as soon as the result can be determined. This lets you write expressions that might otherwise cause an error. Consider the following OR expression:
DECLARE ... on_hand INTEGER; on_order INTEGER; BEGIN .. IF (on_hand = 0) OR ((on_order / on_hand) < 5) THEN ... END IF; END;
When the value of on_hand is zero, the left operand yields TRUE, so PL/SQL need not evaluate the right operand. If PL/SQL were to evaluate both operands before applying the OR operator, the right operand would cause a division by zero error. In any case, it is a poor programming practice to rely on short-circuit evaluation.
Comparison Operators
Comparison operators compare one expression to another. The result is always true, false, or null. Typically, you use comparison operators in conditional control statements and in the WHERE clause of SQL data manipulation statements. Here are a couple of examples:
IF quantity_on_hand > 0 THEN UPDATE inventory SET quantity = quantity - 1 WHERE part_number = item_number; ELSE ... END IF;
100
Relational Operators
The relational operators allow you to compare arbitrarily complex expressions. The following list gives the meaning of each operator: Operator
= <>, !=, ~=, ^= < > <= >=
Meaning equal to not equal to less than greater than less than or equal to greater than or equal to
IS NULL Operator
The IS NULL operator returns the Boolean value TRUE if its operand is null or FALSE if it is not null. Comparisons involving nulls always yield NULL. So, test for nullity (the state of being null), as follows:
IF variable IS NULL THEN ...
LIKE Operator
You use the LIKE operator to compare a character, string, or CLOB value to a pattern. Case is significant. LIKE returns the Boolean value TRUE if the patterns match or FALSE if they do not match. The patterns matched by LIKE can include two special-purpose characters called wildcards. An underscore (_) matches exactly one character; a percent sign (%) matches zero or more characters. For example, if the value of ename is 'JOHNSON', the following expression is true:
ename LIKE 'J%SON'
BETWEEN Operator
The BETWEEN operator tests whether a value lies in a specified range. It means "greater than or equal to low value and less than or equal to high value." For example, the following expression is false:
45 BETWEEN 38 AND 44
101
IN Operator
The IN operator tests set membership. It means "equal to any member of." The set can contain nulls, but they are ignored. For example, the following statement does not delete rows in which the ename column is null:
DELETE FROM emp WHERE ename IN (NULL, 'KING', 'FORD');
yield FALSE if the set contains a null. For example, instead of deleting rows in which the ename column is not null and not 'KING', the following statement deletes no rows:
DELETE FROM emp WHERE ename NOT IN (NULL, 'KING');
Concatenation Operator
Double vertical bars (||) serve as the concatenation operator, which appends one string (CHAR, VARCHAR2, CLOB, or the equivalent Unicode-enabled type) to another. For example, the expression
'suit' || 'case'
If both operands have datatype CHAR, the concatenation operator returns a CHAR value. If either operand is a CLOB value, the operator returns a temporary CLOB. Otherwise, it returns a VARCHAR2 value.
Boolean Expressions
PL/SQL lets you compare variables and constants in both SQL and procedural statements. These comparisons, called Boolean expressions, consist of simple or complex expressions separated by relational operators. Often, Boolean expressions are connected by the logical operators AND, OR, and NOT. A Boolean expression always yields TRUE, FALSE, or NULL. In a SQL statement, Boolean expressions let you specify the rows in a table that are affected by the statement. In a procedural statement, Boolean expressions are the basis
102
for conditional control. There are three kinds of Boolean expressions: arithmetic, character, and date.
By setting the initialization parameter NLS_COMP=ANSI, you can make comparisons use use the collating sequence identified by the NLS_SORT initialization parameter. A collating sequence is an internal ordering of the character set in which a range of numeric codes represents the individual characters. One character value is greater than another if its internal numeric value is larger. Each language might have different rules about where such characters occur in the collating sequence. For example, an accented letter might be sorted differently depending on the database character set, even though the binary value is the same in each case. There are semantic differences between the CHAR and VARCHAR2 base types that come into play when you compare character values. For more information, see Appendix B Many types can be converted to character types. For example, you can compare, assign, and do other character operations using CLOB variables. For details on the possible conversions, see "Character Types" 103
In general, do not compare real numbers for exact equality or inequality. Real numbers are stored as approximate values. So, for example, the following IF condition might not yield TRUE:
count := 1; IF count = 1.0 THEN ... END IF;
It is a good idea to use parentheses when doing comparisons. For example, the following expression is not allowed because 100 < tax yields a Boolean value, which cannot be compared with the number 500:
100 < tax < 500 -- not allowed
A Boolean variable is itself either true or false. So, comparisons with the Boolean values TRUE and FALSE are redundant. For example, assuming the variable done is of type BOOLEAN, the WHILE statement
WHILE NOT (done = TRUE) LOOP ... END LOOP;
104
Using CLOB values with comparison operators, or functions such as LIKE and BETWEEN, can result in creation of temporary LOBs. You might need to make sure your temporary tablespace is large enough to handle these temporary LOBs. For details, see the "Modeling and Design".
CASE Expressions
A CASE expression selects a result from one or more alternatives, and returns the result. The CASE expression uses a selector, an expression whose value determines which alternative to return. A CASE expression has the following form:
CASE selector WHEN expression1 THEN result1 WHEN expression2 THEN result2 ... WHEN expressionN THEN resultN [ELSE resultN+1] END;
The selector is followed by one or more WHEN clauses, which are checked sequentially. The value of the selector determines which clause is executed. The first WHEN clause that matches the value of the selector determines the result value, and subsequent WHEN clauses are not evaluated. An example follows:
DECLARE grade CHAR(1) := 'B'; appraisal VARCHAR2(20); BEGIN appraisal := CASE grade WHEN 'A' THEN 'Excellent' WHEN 'B' THEN 'Very Good' WHEN 'C' THEN 'Good' WHEN 'D' THEN 'Fair' WHEN 'F' THEN 'Poor' ELSE 'No such grade' END; END;
The optional ELSE clause works similarly to the ELSE clause in an IF statement. If the value of the selector is not one of the choices covered by a WHEN clause, the ELSE clause is executed. If no ELSE clause is provided and none of the WHEN clauses are matched, the expression returns NULL. An alternative to the CASE expression is the CASE statement, where each WHEN clause can be an entire PL/SQL block. For details, see "CASE Statement"
105
A searched CASE expression has no selector. Each WHEN clause contains a search condition that yields a Boolean value, which lets you test different variables or multiple conditions in a single WHEN clause. An example follows:
DECLARE grade CHAR(1); appraisal VARCHAR2(20); BEGIN ... appraisal := CASE WHEN grade = 'A' THEN WHEN grade = 'B' THEN WHEN grade = 'C' THEN WHEN grade = 'D' THEN WHEN grade = 'F' THEN ELSE 'No such grade' END; ... END;
The search conditions are evaluated sequentially. The Boolean value of each search condition determines which WHEN clause is executed. If a search condition yields TRUE, its WHEN clause is executed. After any WHEN clause is executed, subsequent search conditions are not evaluated. If none of the search conditions yields TRUE, the optional ELSE clause is executed. If no WHEN clause is executed and no ELSE clause is supplied, the value of the expression is NULL.
Comparisons involving nulls always yield NULL Applying the logical operator NOT to a null yields NULL
106
In conditional control statements, if the condition yields NULL, its associated sequence of statements is not executed If the expression in a simple CASE statement or CASE expression yields NULL, it cannot be matched by using WHEN NULL. In this case, you would need to use the searched case syntax and test WHEN expression IS NULL.
In the example below, you might expect the sequence of statements to execute because x and y seem unequal. But, nulls are indeterminate. Whether or not x is equal to y is unknown. Therefore, the IF condition yields NULL and the sequence of statements is bypassed.
x := 5; y := NULL; ... IF x != y THEN -- yields NULL, not TRUE sequence_of_statements; -- not executed END IF;
In the next example, you might expect the sequence of statements to execute because a and b seem equal. But, again, that is unknown, so the IF condition yields NULL and the sequence of statements is bypassed.
a := NULL; b := NULL; ... IF a = b THEN -- yields NULL, not TRUE sequence_of_statements; -- not executed END IF;
NOT Operator
Recall that applying the logical operator NOT to a null yields NULL. Thus, the following two statements are not always equivalent:
IF x > y THEN high := x; ELSE high := y; END IF; | | | | | IF NOT x > y THEN high := y; ELSE high := x; END IF;
The sequence of statements in the ELSE clause is executed when the IF condition yields FALSE or NULL. If neither x nor y is null, both IF statements assign the same value to high. However, if either x or y is null, the first IF statement assigns the value of y to high, but the second IF statement assigns the value of x to high.
107
Zero-Length Strings
PL/SQL treats any zero-length string like a null. This includes values returned by character functions and Boolean expressions. For example, the following statements assign nulls to the target variables:
null_string := TO_CHAR(''); zip_code := SUBSTR(address, 25, 0); valid := (name != '');
So, use the IS NULL operator to test for null strings, as follows:
IF my_string IS NULL THEN ...
Concatenation Operator
The concatenation operator ignores null operands. For example, the expression
'apple' || NULL || NULL || 'sauce'
Functions
If a null argument is passed to a built-in function, a null is returned except in the following cases. The function DECODE compares its first argument to one or more search expressions, which are paired with result expressions. Any search or result expression can be null. If a search is successful, the corresponding result is returned. In the following example, if the column rating is null, DECODE returns the value 1000:
SELECT DECODE(rating, NULL, 1000, 'C', 2000, 'B', 4000, 'A', 5000) INTO credit_limit FROM accts WHERE acctno = my_acctno;
The function NVL returns the value of its second argument if its first argument is null. In the example below, if hire_date is null, NVL returns the value of SYSDATE. Otherwise, NVL returns the value of hire_date:
start_date := NVL(hire_date, SYSDATE);
108
The function REPLACE returns the value of its first argument if its second argument is null, whether the optional third argument is present or not. For instance, after the assignment
new_string := REPLACE(old_string, NULL, my_string);
the values of old_string and new_string are the same. If its third argument is null, REPLACE returns its first argument with every occurrence of its second argument removed. For example, after the assignments
syllabified_name := 'Gold-i-locks'; name := REPLACE(syllabified_name, '-', NULL);
the value of name is 'goldilocks' If its second and third arguments are null, REPLACE simply returns its first argument.
Built-In Functions
PL/SQL provides many powerful functions to help you manipulate data. These built-in functions fall into the following categories: error reporting number character datatype conversion date object reference miscellaneous Except for the error-reporting functions SQLCODE and SQLERRM, you can use all the functions in SQL statements. Also, except for the object-reference functions DEREF, REF, and VALUE and the miscellaneous functions DECODE, DUMP, and VSIZE, you can use all the functions in procedural statements. Although the SQL aggregate functions (such as AVG and COUNT) and the SQL analytic functions (such as CORR and LAG) are not built into PL/SQL, you can use them in SQL statements (but not in procedural statements).
109
7.1(A)Committing TransactIOns
To commit a transaction, use the COMMIT command. The following two statements are equivalent and commit the current transaction:
COMMIT WORK; COMMIT;
The COMMIT command lets you include the COMMENT parameter along with a comment (less than 50 characters) that provides information about the transaction being committed. This option is useful for including information about the origin of the transaction when you commit distributed transactions:
COMMIT COMMENT 'Dallas/Accts_pay/Trans_type 10B';
110
The WORK option of the ROLLBACK command has no function. To roll back to a savepoint defined in the current transaction, use the TO option of the ROLLBACK command. For example, either of the following statements rolls back the current transaction to the savepoint named POINT1:
SAVEPOINT Point1; ... ROLLBACK TO SAVEPOINT Point1; ROLLBACK TO Point1;
If you create a second savepoint with the same identifier as an earlier savepoint, the earlier savepoint is erased. After creating a savepoint, you can roll back to the savepoint. There is no limit on the number of active savepoints for each session. An active savepoint is one that has been specified since the last commit or rollback.
Results First savepoint of this transaction First DML statement of this transaction Second savepoint of this transaction Second DML statement of this transaction Third savepoint of this transaction Third DML statement of this transaction.
UPDATE INSERT
statement is rolled back, savepoint C remains defined statement is rolled back, savepoint C is lost, savepoint B remains 111
SQL Statement
b; ROLLBACK TO c; INSERT INTO...; COMMIT;
Results defined
ORA-01086
New DML statement in this transaction Commits all actions performed by the first DML statement (the DELETE statement) and the last DML statement (the second INSERT statement) All other statements (the second and the third statements) of the transaction were rolled back before the COMMIT. The savepoint A is no longer active.
7.3TYPES OF CURSOR:
1.Implicit Cursors Attributes 2.Explicit cursors Attributes
Keyword and Parameter Descriptions %BULK_ROWCOUNT A composite attribute designed for use with the FORALL statement. This attribute acts like an index-by table. Its ith element stores the number of rows processed by the ith execution of an UPDATE or DELETE statement. If the ith execution affects no rows, %BULK_ROWCOUNT(i) returns zero. %BULK_EXCEPTIONS An associative array that stores information about any exceptions encountered by a FORALL statement that uses the SAVE EXCEPTIONS clause. You must loop through its elements to determine where the exceptions occurred and what they were. For each index value i between 1 and SQL%BULK_EXCEPTIONS.COUNT, SQL %BULK_EXCEPTIONS(i).ERROR_INDEX specifies which iteration of the FORALL loop caused an exception. SQL%BULK_EXCEPTIONS(i).ERROR_CODE specifies the Oracle Database error code that corresponds to the exception. %FOUND Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or more rows or a SELECT INTO statement returned one or more rows. Otherwise, it returns FALSE. %ISOPEN Always returns FALSE, because the database closes the SQL cursor automatically after executing its associated SQL statement. %NOTFOUND The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or DELETE statement affected no rows, or a SELECT INTO statement returned no rows. Otherwise, it returns FALSE. %ROWCOUNT Returns the number of rows affected by an INSERT, UPDATE, or DELETE statement, or returned by a SELECT INTO statement. SQL The name of the implicit cursor. 113
Usage Notes You can use cursor attributes in procedural statements but not in SQL statements. Before the database opens the SQL cursor automatically, the implicit cursor attributes return NULL. The values of cursor attributes always refer to the most recently executed SQL statement, wherever that statement appears. It might be in a different scope. If you want to save an attribute value for later use, assign it to a variable immediately. If a SELECT INTO statement fails to return a row, PL/SQL raises the predefined exception NO_DATA_FOUND, whether you check SQL%NOTFOUND on the next line or not. A SELECT INTO statement that invokes a SQL aggregate function never raises NO_DATA_FOUND, because those functions always return a value or a NULL. In such cases, SQL%NOTFOUND returns FALSE. %BULK_ROWCOUNT is not maintained for bulk inserts because a typical insert affects only one row. See Counting Rows Affected by FORALL (%BULK_ROWCOUNT Attribute). You can use the scalar attributes %FOUND, %NOTFOUND, and %ROWCOUNT with bulk binds. For example, %ROWCOUNT returns the total number of rows processed by all executions of the SQL statement. Although %FOUND and %NOTFOUND refer only to the last execution of the SQL statement, you can use %BULK_ROWCOUNT to deduce their values for individual executions. For example, when %BULK_ROWCOUNT(i) is zero, %FOUND and %NOTFOUND are FALSE and TRUE, respectively
2. Explicit Cursor
An explicit cursor names the unnamed work area in which the database stores processing information when it executes a multiple-row query. When you have named the work area, you can access its information, and process the rows of the query individually. Syntax cursor declaration ::=
114
cursor_parameter_declaration ::=
115
Keyword and Parameter Descriptions cursor_name An explicit cursor previously declared within the current scope. datatype A type specifier. For the syntax of datatype, see Constant db_table_name A database table or view that must be accessible when the declaration is elaborated. expression A combination of variables, constants, literals, operators, and function calls. The simplest expression consists of a single variable. When the declaration is elaborated, the value of expression is assigned to the parameter. The value and the parameter must have compatible data types. Note: If you supply an actual parameter for parameter_name when you open the cursor, then expression is not evaluated. parameter_name A variable declared as the formal parameter of a cursor. A cursor parameter can appear in a query wherever a constant can appear. The formal parameters of a cursor must be IN parameters. The query can also reference other PL/SQL variables within its scope. record_name A user-defined record previously declared within the current scope. record_type_name A user-defined record type that was defined using the data type specifier RECORD.
RETURN
116
Specifies the data type of a cursor return value. You can use the %ROWTYPE attribute in the RETURN clause to provide a record type that represents a row in a database table or a row returned by a previously declared cursor. Also, you can use the %TYPE attribute to provide the data type of a previously declared record. A cursor body must have a SELECT statement and the same RETURN clause as its corresponding cursor specification. Also, the number, order, and data types of select items in the SELECT clause must match the RETURN clause. %ROWTYPE A record type that represents a row in a database table or a row fetched from a previously declared cursor or cursor variable. Fields in the record and corresponding columns in the row have the same names and data types. select_statement A SQL SELECT statement. If the cursor declaration declares parameters, each parameter must appear in select_statement. %TYPE Provides the data type of a previously declared user-defined record. Usage Notes You must declare a cursor before referencing it in an OPEN, FETCH, or CLOSE statement. Note: An explicit cursor declared in a package specification is affected by the AUTHID clause of the package. For more information, see "CREATE PACKAGE Statement" You must declare a variable before referencing it in a cursor declaration. The word SQL is reserved by PL/SQL as the default name for SQL cursors, and cannot be used in a cursor declaration. You cannot assign values to a cursor name or use it in an expression. However, cursors and variables follow the same scoping rules. For more information, see Scope and Visibility of PL/SQL Identifiers. You retrieve data from a cursor by opening it, then fetching from it. Because the FETCH statement specifies the target variables, using an INTO clause in the SELECT statement of a cursor_declaration is redundant and invalid.
117
The scope of cursor parameters is local to the cursor, meaning that they can be referenced only within the query used in the cursor declaration. The values of cursor parameters are used by the associated query when the cursor is opened. The query can also reference other PL/SQL variables within its scope. The data type of a cursor parameter must be specified without constraints, that is, without precision and scale for numbers, and without length for strings
Each cursor requires virtual memory, so a session's total number of cursors is limited by the memory available to that process. A systemwide limit of cursors for each session is set by the initialization parameter named OPEN_CURSORS found in the parameter file (such as INIT.ORA).
Explicitly creating cursors for precompiler programs can offer some advantages in tuning those applications. For example, increasing the number of cursors can often reduce the frequency of parsing and improve performance. If you know how many cursors may be required at a given time, then you can make sure you can open that many simultaneously.
118
The V$SQL_PLAN view contains the execution plan information for each child cursor loaded in the library cache. The V$SQL_PLAN_STATISTICS view provides execution statistics at the row source level for each child cursor. The V$SQL_PLAN_STATISTICS_ALL view contains memory usage statistics for row sources that use SQL memory (sort or hash-join). This view concatenates information in V$SQL_PLAN with execution statistics from V$SQL_PLAN_STATISTICS and V$SQL_WORKAREA.
Closing Cursors
Closing a cursor means that the information currently in the associated private area is lost and its memory is deallocated. Once a cursor is opened, it is not closed until one of the following events occurs:
The user program terminates its connection to the server. If the user program is an OCI program or precompiler application, then it explicitly closes any open cursor during the execution of that program. (However, when this program terminates, any cursors remaining open are implicitly closed.)
Canceling Cursors
Canceling a cursor frees resources from the current fetch.The information currently in the associated private area is lost but the cursor remains open, parsed, and associated with its bind variables. Note:
119
120