Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introduction.

Similar presentations


Presentation on theme: "Introduction."— Presentation transcript:

1 Introduction

2 Oracle Database 10g: SQL and PL/SQL New Features 1 - 2
Objectives After completing this lesson, you should be able to: Describe the organization of the course Review the schemas that are used in this course Review the SQL*Plus environment used in this course Review the SQL Developer environment that you can optionally use in this course Oracle Database 10g: SQL and PL/SQL New Features

3 Oracle Database 10g: SQL and PL/SQL New Features 1 - 3
Course Objectives After completing this course, you should be able to do the following: Describe the data type enhancements Use the large object (LOB) enhancements Use the Nested Table and Varray enhancements Identify SQL performance, data warehousing, and general enhancements Use regular expressions Identify the new PL/SQL enhancements Explain the SQL MODEL Clause Oracle Database 10g: SQL and PL/SQL New Features

4 Oracle Database 10g: SQL and PL/SQL New Features 1 - 4
Course Agenda Day 1: Introduction Using Oracle Database 10g Data Types Using Large Object (LOB) Enhancements Using Nested Table and VARRAY Enhancements Handling SQL Performance and Using General SQL Enhancements Oracle Database 10g: SQL and PL/SQL New Features

5 Oracle Database 10g: SQL and PL/SQL New Features 1 - 5
Course Agenda Day 2: Using Regular Expressions in SQL and PL/SQL Using the New PL/SQL Compiler Programming with PL/SQL Enhancements Using the SQL Model Clause Using SQL Enhancements for Data Warehousing Oracle Database 10g: SQL and PL/SQL New Features

6 Oracle Database 10g: SQL and PL/SQL New Features 1 - 6
Lesson Agenda Appendices and tables used in this course Overview of SQL*Plus Overview of Oracle SQL Developer Oracle 10g documentation and additional resources Oracle Database 10g: SQL and PL/SQL New Features

7 Appendices Used in this Course
Appendix A: Practices Appendix B: Practice Solutions Appendix C: Table Descriptions Appendix D: Using Oracle SQL Developer Appendix E: Using SQL*Plus and New SQL*Plus Enhancements Appendix F: Using Oracle JDeveloper Appendix G: Working with Collections Oracle Database 10g: SQL and PL/SQL New Features

8 Tables Used in This Course
The sample schemas that are used in this course are: Order Entry (OE) schema Human Resources (HR) schema Sales History (SH) schema Print Media (PM) schema Tables Used in This Course The sample company portrayed by Oracle Database Sample Schemas operates worldwide to fulfill orders for several different products. The company has several divisions: The Human Resources division tracks information about the employees and facilities of the company. The Order Entry division tracks product inventories and sales of the company’s products through various channels. The Sales History division tracks business statistics to facilitate business decisions. Each of these divisions is represented by a schema. All scripts necessary to create the OE schema reside in the $ORACLE_HOME/demo/schema/order_entry folder. All scripts necessary to create the HR schema reside in the $ORACLE_HOME/demo/schema/human_resources folder. Note Appendix B contains more information about the sample schemas. The code examples and the practices in this course specify the schema that needs to be used. Oracle Database 10g: SQL and PL/SQL New Features

9 The Order Entry (OE) Schema
CUSTOMERS customer_id cust_first_name cust_ last_name cust_ address_typ phone_numbers nls_language nls_territory credit_limit cust_ account_mgr_id date_of_birth marital_status gender Income_level ORDER_ITEM order_id line_item_id product_id unit_price quantity ORDERS order_id order_date order_mode customer_id order_status order_total sales_rep_id promotion_id street_address postal_code city state_province country_id PRODUCT_ INFORMATION product_id product_name product_description category_id weight_class warranty_period supplier_id product_status list_price min_price catalog_url PRODUCT_ DESCRIPTION product_id language_id product_name product_description The Order Entry (OE) Schema Description The company sells several categories of products, including computer hardware and software, music, clothing, and tools. The company maintains product information that includes product identification numbers, the category into which the product falls, the weight group (for shipping purposes), the warranty period if applicable, the supplier, the status of the product, a list price, a minimum price at which a product will be sold, and a URL for manufacturer information. INVENTORIES product_id warehouse_id quantity_on_hand WAREHOUSES warehouse_id warehouse_name location_id Oracle Database 10g: SQL and PL/SQL New Features

10 The Human Resources (HR) Schema
DEPARTMENTS department_id department_name manager_id location_id LOCATIONS location_id street_address postal_code city state_province country_id JOB_HISTORY employee_id start_date end_date job_id department_id EMPLOYEES employee_id first_name last_name phone_number hire_date job_id salary commission_pct manager_id department_id COUNTRIES country_id country_name region_id JOBS job_id job_title min_salary max_salary REGIONS region_id region_name The Human Resources (HR) Schema Description In the Human Resource (HR) records, each employee has an identification number, address, job identification code, salary, and manager. Some employees earn commissions in addition to their salary. The company also tracks information about jobs within the organization. Each job has an identification code, job title, and a minimum and maximum salary range for the job. Some employees have been with the company for a long time and have held different positions within the company. When an employee resigns, the duration the employee was working, the job identification number, and the department are recorded. The sample company is regionally diverse, so it tracks the locations of its warehouses and departments. Each employee is assigned to a department, and each department is identified by either a unique department number or a short name. Each department is associated with one location, and each location has a full address that includes the street name, postal code, city, state or province, and the country code. In places where the departments and warehouses are located, the company records details such as the country name, currency symbol, currency name, and the region where the country is located geographically. Oracle Database 10g: SQL and PL/SQL New Features

11 The Sales History (SH) Schema
TIMES time_id day_name day_number_in_week day_number_in_month calendar_week_number fiscal_week_number week_ending_day week_ending_day_id calendar_month_number fiscal_month_number calendar_month_desc calendar_month_id fiscal_month_id days_in_cal_month days_in_fis_month end_of_cal_ month end_of_fis_month calendar _month _name fiscal _month _name calendar _quarter _desc calendar_quarter_id fiscal _quarter _desc fiscal _quarter _id days_in_cal_quarter days_in_fis_quarter end_of_cal_quarter end_of_fis_quarter calendar_quarter_number fiscal_quarter_number calendar_year calendar_year_id fiscal_year fiscal_year_id days_in_cal_year days_in_fis_year end_of_cal_year end_of_fis_year PROMOTIONS promo_id promo_name promo_subcategory promo_subcategory_id promo_category promo_category_id promo_cost promo_begin_date promo_end_date promo_total promo_total_id COSTS prod_id time_id promo_id channel_id unit_cost unit_price SALES prod_id cust_id time_id channel_id promo_id quantity_sold amount_sold The Sales History (SH) Schema Description The company does a high volume of business, so it runs business statistics reports to aid in decision support. Many of these reports are time based and nonvolatile. That is, they analyze past data trends. The company loads data into its data warehouse regularly to gather statistics for the reports. The reports include annual, quarterly, monthly, and weekly sales figures by product. The company also runs reports on the distribution channels through which its sales are delivered. When the company runs special promotions on its products, it analyzes the impact of the promotions on sales. It also analyzes sales by geographical area. CHANNELS channel_id channel_desc channel_class channel_class_id channel_total channel_total_id PRODUCTS Oracle Database 10g: SQL and PL/SQL New Features

12 The Sales History (SH) Schema
COSTS SALES SALES PRODUCTS prod_id prod_name prod_desc prod_subcategory prod_subcategory_id prod_subcategory_desc prod_category prod_category_id prod_category_desc prod_weight_class prod_unit_of_measure prod_pack_size supplier_id prod_status prod_list_price prod_min_price prod_total prod_total_id prod_src_id prod_eff_from prod_eff_to prod_valid CUSTOMERS cust_id cust_first_name cust_last_name cust_gender cust_year_of_birth cust_marital_status cust_street_address cust_postal_code cust_city cust_city_id cust_state_province cust_state_province_id country_id cust_main_phone_number cust_income_level cust_credit_limit cust_ cust_total cust_total_id cust_src_id cust_eff_from cust_eff_to cust_valid COUNTRIES country_id country_iso_code country_name country_subregion country_subregion_id country_region country_region_id country_total country_total_id Country_name_hist Oracle Database 10g: SQL and PL/SQL New Features

13 The Print Media (PM) Schema
PRODUCT_ INFORMATION product_id product_name product_description category_id weight_class warranty_period supplier_id product_status list_price min_price catalog_url OE Schema ONLINE_MEDIA product_id product_photo product_photo_signature product_thumbnail product_video product_audio product_text product_testimonials PRINT_MEDIA product_id first_name ad_id ad_composite ad_sourcetext ad_finaltext ad_fltexttn ad_textdocs_ntab ad_photo ad_graphic ad_header press_release ADHEADER_TYP header_name creation_date header_text logo The Print Media (PM) Schema Description The company stores multimedia and print information about its products in the database. The Print Media (PM) schema is used to store such data. Examples of such information are: Promotional audio and video clips Product images and thumbnails for Web publishing Press release texts Print media advertisements Other promotion texts and translations TEXTDOC_TYP document_typ formatted_doc Oracle Database 10g: SQL and PL/SQL New Features

14 Oracle Database 10g: SQL and PL/SQL New Features 1 - 14
Lesson Agenda Appendices and tables used in this course Overview of SQL*Plus Overview of Oracle SQL Developer Oracle 10g documentation and additional resources Oracle Database 10g: SQL and PL/SQL New Features

15 Overview of SQL*Plus Used in This Course
Logging in to SQL*Plus Describing the table structure Executing SQL from SQL*Plus Reviewing SQL*Plus file commands SQL*Plus SQL*Plus is an environment in which you can do the following: Execute SQL statements to retrieve, modify, add, and remove data from the database. Format, perform calculations on, store, and print query results in the form of reports. Create script files to store SQL statements for repeated use in the future. SQL*Plus commands can be divided into the following main categories: Note: For additional information about SQL*Plus, see Appendix E in this course. Oracle Database 10g: SQL and PL/SQL New Features

16 Oracle Database 10g: SQL and PL/SQL New Features 1 - 16
Logging In to SQL*Plus 1 2 sqlplus Logging In to SQL*Plus How you invoke SQL*Plus depends on which type of operating system or Windows environment you are running. To log in from a Windows environment, use one of the following methods: Double-click the SQL*Plus icon on your desktop if you have created a SQL*Plus shortcut on your desktop. Select Start > Programs > Oracle > Application Development > SQL*Plus. Next, enter the username, password, and database name. To log in from a command-line environment, perform the following steps: 1. Log on to your machine. Enter the SQL*Plus command and optionally enter your username, password (Your password is visible if you enter it here.), and the database connect string. Note To ensure the integrity of your password, do not enter it at the operating system prompt. Instead, enter only your username. Enter your password at the password prompt. After you log in to SQL*Plus, you see the message shown in the screenshot in the slide (if you are using SQL*Plus version ). The “ [ ]” indicates an optional parameter. Oracle Database 10g: SQL and PL/SQL New Features

17 Displaying Table Structure
DESCRIBE departments Name Null? Type DEPARTMENT_ID NOT NULL NUMBER(4) DEPARTMENT_NAME NOT NULL VARCHAR2(30) MANAGER_ID NUMBER(6) LOCATION_ID NUMBER(4) Displaying Table Structure The example in the slide displays information about the structure of the DEPARTMENTS table. In the result: Null?: Specifies whether a column must contain data (NOT NULL indicates that a column must contain data.) Type: Displays the data type for a column The following table describes the data types: Oracle Database 10g: SQL and PL/SQL New Features

18 Executing SQL from SQL*Plus
SELECT last_name, manager_id, department_id FROM employees LAST_NAME MANAGER_ID DEPARTMENT_ID OConnell Grant Whalen Hartstein Fay Mavris Baer Higgins Gietz King ... 107 rows selected. Oracle Database 10g: SQL and PL/SQL New Features

19 SQL*Plus File Commands
SAVE filename GET filename START filename @filename EDIT filename SPOOL filename EXIT SQL*Plus File Commands Use the following commands to control the environment, format results, and manage files: Oracle Database 10g: SQL and PL/SQL New Features

20 Oracle Database 10g: SQL and PL/SQL New Features 1 - 20
Lesson Agenda Appendices and tables used in this course Overview of SQL*Plus Overview of Oracle SQL Developer Oracle 10g documentation and additional resources Oracle Database 10g: SQL and PL/SQL New Features

21 What Is Oracle SQL Developer?
Oracle SQL Developer is a free graphical tool that enhances productivity and simplifies database development tasks. You can connect to any target Oracle database schema using standard Oracle database authentication. What Is Oracle SQL Developer? Oracle SQL Developer is a free graphical tool designed to improve your productivity and simplify the development of everyday database tasks. With just a few clicks, you can easily create and debug stored procedures, test SQL statements, and view optimizer plans. SQL Developer, the visual tool for database development, simplifies the following tasks: Browsing and managing database objects Executing SQL statements and scripts Editing and debugging PL/SQL statements Creating reports You can connect to any target Oracle database schema using standard Oracle database authentication. When connected, you can perform operations on objects in the database. SQL Developer Oracle Database 10g: SQL and PL/SQL New Features

22 Installing SQL Developer
Download the Oracle SQL Developer kit and unzip it into any directory on your machine. Installing SQL Developer Oracle SQL Developer does not require an installer. To install SQL Developer, you need an unzip tool. To install SQL Developer, perform the following steps: 1. Create a folder as <local drive>:\SQL Developer. 2. Download the SQL Developer kit from the Oracle SQL Developer Home page at: 3. Unzip the downloaded SQL Developer kit into the folder created in step 1. To start SQL Developer, go to <local drive>:\SQL Developer, and double-click sqldeveloper.exe. Note: In addition to using the Oracle SQL Developer Home page to download the software for free, you can use this page to do the following: View the Oracle SQL Developer online Help, presentations, white papers, technical information, lessons, tutorials, and so on. Oracle Database 10g: SQL and PL/SQL New Features

23 Menus for SQL Developer
4 6 2 5 1 3 Menus for SQL Developer SQL Developer has two main navigation tabs: Connections Navigator: By using this tab, you can browse database objects and users to which you have access. Reporting Tab: By using this tab, you can run predefined reports or create and add your own reports. SQL Developer uses the left side for navigation to find and select objects, and the right side to display information about selected objects. You can customize many aspects of the appearance and behavior of SQL Developer by setting preferences. The menus at the top contain standard entries, plus entries for features specific to SQL Developer. 1. View: Contains options that affect what is displayed in the SQL Developer interface 2. Navigate: Contains options for navigating to panes and for the execution of subprograms 3. Run: Contains the Run File and Execution Profile options that are relevant when a function or procedure is selected 4. Debug: Contains options that are relevant when a function or procedure is selected 5. Source: Contains options for use when editing functions and procedures 6. Tools: Invokes SQL Developer tools such as SQL*Plus, Preferences, and SQL Worksheet Oracle Database 10g: SQL and PL/SQL New Features

24 Creating a Database Connection
You must have at least one database connection to use SQL Developer. You can create and test connections: For multiple databases For multiple schemas SQL Developer automatically imports any connections defined in the tnsnames.ora file on your system. You can export connections to an XML file. Each additional database connection created is listed in the Connections Navigator hierarchy. Creating a Database Connection A connection is a SQL Developer object that specifies the necessary information for connecting to a specific database as a specific user of that database. To use SQL Developer, you must have at least one database connection, which may be existing, created, or imported. You can create and test connections for multiple databases and for multiple schemas. By default, the tnsnames.ora file is located in the $ORACLE_HOME/network/admin directory. But, it can also be in the directory specified by the TNS_ADMIN environment variable or registry value. When you start SQL Developer and display the New/Select Database Connection window, SQL Developer automatically imports any connections defined in the tnsnames.ora file on your system. Note: On Windows systems, if the tnsnames.ora file exists but its connections are not being used by SQL Developer, then define TNS_ADMIN as a system environment variable. You can export connections to an XML file so that you can reuse it later. You can create additional connections as different users to the same database or to connect to the different databases. Oracle Database 10g: SQL and PL/SQL New Features

25 Creating a Database Connection
Creating a Database Connection (continued) To create a database connection, perform the following steps: 1. Double-click <your_path>\sqldeveloper\sqldeveloper.exe. 2. On the Connections tabbed page, right-click Connections and select New Database Connection. 3. Enter the connection name, username, password, host name, and system identifier (SID) for the database you want to connect to. Click Test to make sure that the connection has been set correctly. Click Connect. On the Basic tabbed page, at the bottom, fill in the following options: Hostname: The host system for the Oracle database Note: In the classroom, enter the host name associated with your PC. Port: Listener port SID: Database name Service name: Network service name for a remote database connection If you select the Save Password check box, the password is saved to an XML file. The next time you access the SQL Developer connection, you will not be prompted for the password. Oracle Database 10g: SQL and PL/SQL New Features

26 Browsing Database Objects
Use the Database Navigator to: Browse through many objects in a database schema Review the definitions of objects at a glance Browsing Database Objects After you have created a database connection, you can use the Database Navigator to browse through many objects in a database schema including Tables, Views, Indexes, Packages, Procedures, Triggers, Types, and so on. SQL Developer uses the left side for navigation to find and select objects, and the right side to display information about the selected objects. You can customize many aspects of the appearance of SQL Developer by setting preferences. You can see the definition of the objects broken into tabs of information that is pulled out of the data dictionary. For example, if you select a table in the Navigator, the details about columns, constraints, grants, statistics, triggers, and more are all displayed in an easy-to-read tabbed page. If you want to see the definition of the EMPLOYEES table as shown in the slide, perform the following steps: 1. Expand the Connections node in the Connections Navigator. 2. Expand Tables. 3. Double-click EMPLOYEES. Using the Data tab, you can enter new rows, update data, and commit these changes to the database. Oracle Database 10g: SQL and PL/SQL New Features

27 Oracle Database 10g: SQL and PL/SQL New Features 1 - 27
Using SQL Worksheet Use SQL Worksheet to enter and execute SQL, PL/SQL, and SQL*Plus statements. Specify any actions that can be processed by the database connection associated with the worksheet. Using SQL Worksheet When you connect to a database, a SQL Worksheet window for that connection is automatically opened. You can use SQL Worksheet to enter and execute SQL, PL/SQL, and SQL*Plus statements. SQL Worksheet supports SQL*Plus statements to a certain extent. SQL*Plus statements that are not supported by SQL Worksheet are ignored and not passed to the database. You can specify any actions that can be processed by the database connection associated with the worksheet, such as: Creating a table Inserting data Creating and editing a trigger Selecting data from a table Saving the selected data to a file You can display a SQL worksheet by using any of the following two options: Select Tools > SQL Worksheet. Click the Open SQL Worksheet icon. Oracle Database 10g: SQL and PL/SQL New Features

28 Oracle Database 10g: SQL and PL/SQL New Features 1 - 28
Using SQL Worksheet 2 4 6 8 1 5 7 3 Using SQL Worksheet (continued) You may want to use shortcut keys or icons to perform certain tasks such as executing a SQL statement, running a script, and viewing the history of SQL statements that you have executed. You can use the SQL Worksheet toolbar that contains icons to perform the following tasks: 1. Execute Statement: Executes the statement at the cursor in the Enter SQL Statement box. You can use bind variables in the SQL statements but not substitution variables. 2. Run Script: Executes all statements in the Enter SQL Statement box using the Script Runner. You can use substitution variables in the SQL statements but not bind variables. 3. Commit: Writes any changes to the database and ends the transaction 4. Rollback: Discards any changes to the database, without writing them to the database, and ends the transaction 5. Cancel: Stops the execution of any statements currently being executed 6. SQL History: Displays a dialog box with information about SQL statements that you have executed 7. Execute Explain Plan: Generates the execution plan, which you can see by clicking the Explain tab 8. Clear: Erases the statement or statements in the Enter SQL Statement box Oracle Database 10g: SQL and PL/SQL New Features

29 Executing SQL Statements
Use the Enter SQL Statement box to enter single or multiple SQL statements. Executing SQL Statements In SQL Worksheet, you can use the Enter SQL Statement box to type a single or multiple SQL statements. For a single statement, the semicolon at the end is optional. When you enter the statement, the SQL keywords are automatically highlighted. To execute a SQL statement, ensure that your cursor is within the statement and click the Execute Statement icon. Alternatively, you can press the F9 key. To execute multiple SQL statements and see the results, click the Run Script icon. Alternatively, you can press the F5 key. In the example in the slide, because there are multiple SQL statements, the first statement is terminated with a semicolon. The cursor is in the first statement and so when the statement is executed, results corresponding to the first statement are displayed in the Results box. Oracle Database 10g: SQL and PL/SQL New Features

30 Oracle Database 10g: SQL and PL/SQL New Features 1 - 30
Lesson Agenda Appendices and tables used in this course Overview of SQL*Plus Overview of Oracle SQL Developer Oracle 10g documentation and additional resources Oracle Database 10g: SQL and PL/SQL New Features

31 Oracle 10g SQL and PL/SQL Documentation
Navigate to > Click the Books tab: Oracle Database New Features Guide 10g Release 2 (10.2) Oracle Database Application Developer's Guide – Fundamentals 10g Release 2 (10.2) Oracle Database Globalization Support Guide 10g Release 2 (10.2) Oracle Database PL/SQL User's Guide and Reference 10g Release 2 (10.2) Oracle Database 10g: SQL and PL/SQL New Features

32 Oracle 10g SQL and PL/SQL Documentation
Oracle Database Reference 10g Release 2 (10.2) Oracle Database SQL Reference 10g Release 2 (10.2) Oracle Database PL/SQL Packages and Types Reference 10g Release 2 (10.2) Oracle Database Application Developer's Guide - Large Objects 10g Release 2 (10.2) Oracle Database 10g: SQL and PL/SQL New Features

33 Oracle Database 10g: SQL and PL/SQL New Features 1 - 33
Additional Resources For additional information about the new Oracle 10g SQL and PL/SQL new features, refer to the following: Oracle Database 10g: New Features eStudies Oracle by Example series (OBE): Oracle Database 10g What’s New in PL/SQL in Oracle Database 10g on the Oracle Technology Network (OTN): Oracle Database 10g: SQL and PL/SQL New Features

34 Oracle Database 10g: SQL and PL/SQL New Features 1 - 34
Summary In this lesson, you should have learned how to: Describe the organization of the course Review the schemas that are used in this course Review the SQL*Plus environment used in this course Review the SQL Developer environment that you can optionally use in this course Oracle Database 10g: SQL and PL/SQL New Features

35 Oracle Database 10g: SQL and PL/SQL New Features 1 - 35
Practice 1: Overview This practice covers the following topics: Logging on to SQL*Plus and describing the structure of a table, and displaying the table’s data Starting SQL Developer and creating a new database connection, describing the structure of a table, and displaying the table’s data Using the SQL Worksheet to execute a SQL statement Accessing the Oracle Database 10g Release 2 online documentation Practice 1: Overview This is the first of many practices in this course. The solutions (if you require them) can be found in Appendix B. Practices are intended to cover all topics that are presented in the corresponding lesson. Note the following location for the lab files: E:\labs\… If you are asked to save any lab files, save them at this location. To start SQL*Plus, click the SQL*Plus icon on your desktop. In any practice, there may be exercises that are prefaced with the phrases “If you have time” or “If you want an extra challenge.” Work on these exercises only if you have completed all other exercises in the allocated time and would like a further challenge to your skills. Perform the practices slowly and precisely. You can experiment with saving and running command files. If you have any questions at any time, ask your instructor. Oracle Database 10g: SQL and PL/SQL New Features

36 Using Oracle Database 10g Data Types

37 Oracle Database 10g: SQL and PL/SQL New Features 1 - 37
Objectives After completing this lesson, you should be able to: Use the new native floating-point data types BINARY_FLOAT BINARY_DOUBLE Supporting functions Exceptions Use NCHAR literals in the data manipulation language (DML) Convert LONG and LONG RAW columns to LOBs Objectives In this lesson, you learn about the new binary-float data types introduced in Oracle Database 10g. You learn what they are, how to use them, and when to use them. You also learn about the NCHAR literals enhancement in Oracle Database 10g, Release 2. Oracle Database 10g: SQL and PL/SQL New Features

38 Oracle Database 10g: SQL and PL/SQL New Features 1 - 38
Lesson Agenda Using the new native floating-point data types Supporting NCHAR string literals Changing LONG and LONG RAW columns to LOBs Oracle Database 10g: SQL and PL/SQL New Features

39 The New BINARY_FLOAT and BINARY_DOUBLE Numeric Data Types
Store floating-point data in IEEE 754 format Benefits: Are part of numerous other standards and systems such as Java, XML, and so on Are more efficient than the NUMBER type Have the arithmetic operations implemented in hardware on most platforms May use less space in memory or disk Provide seamless support in SQL and PL/SQL Overview of Native Floating-Point Data Types SQL provides the NUMBER data type and its subtypes to store numeric data and perform calculations. For floating-point numeric operations, you can use NUMBER without any precision or scale. Alternatively, you can use the NUMBER subtypes REAL, FLOAT, and DOUBLE PRECISION to comply with ANSI standards. In Oracle Database 10g, you can use two floating-point data types: BINARY_FLOAT (single precision 32-bit) and BINARY_DOUBLE (double precision 64-bit). The new data types are based on the IEEE Standard for binary floating-point arithmetic and ANSI/IEEE Std [IEEE 754]. The IEEE 754 standard is well accepted by the majority of numerical computation users to implement numerical algorithms and is implemented on many major hardware platforms. Applications that require extensive floating-point computations can benefit from these data types. This includes the areas of life sciences, OLAP, and data mining. Oracle Database 10g: SQL and PL/SQL New Features

40 Floating-Point Formats
Three components: Signed bit, exponent, significand Binary Float (32 total bits): 1 sign 8 exponent 23 signficand Binary Double (64 total bits): 11 exponent Exponent Significand Sign Floating-Point Formats A floating-point number consists of three components: a sign, an exponent, and a significand (or mantisse), and assumes that the base is fixed. Its value is the signed product of its significand and the base raised to the power of its exponent. This format specifies how the three components are represented, and determines the range and precision of the values that the format can represent. Oracle Database 10g: SQL and PL/SQL New Features

41 Oracle Database 10g: SQL and PL/SQL New Features 1 - 41
Numeric Ranges Range and Precision Single Precision Double Precision Oracle Number Max positive normal number e+38 e+308 < 1.0e126 Min positive normal number e-38 e-308 1.0e-130 Max positive subnormal number e-38 e-308 not applicable Min positive subnormal number e-45 e-324 Precision (decimal digits) 6 - 9 Numeric Ranges The table in the slide shows the range and precision of the required formats in the IEEE 754 standard and those of Oracle NUMBER data type. Range limits are expressed here in terms of positive numbers; they also apply to the absolute value of a negative number. Note that a significand is normalized when the leading bit of the significand is set. IEEE 754 defines denormal or subnormal values as numbers that are too small to be represented with an implied leading set bit in the significand. The number is too small because its exponent would be too large if its significand were normalized to have an implied leading bit set. IEEE 754 formats support subnormal values. Oracle Database 10g: SQL and PL/SQL New Features

42 Using BINARY_FLOAT and BINARY_DOUBLE Data Types
Not a replacement for NUMBER Values beyond Oracle NUMBER Closed arithmetic operations Transparent rounding Using BINARY_FLOAT and BINARY_DOUBLE Data Types BINARY_FLOAT and BINARY_DOUBLE do not replace the Oracle NUMBER data type. They are alternatives, offering better interoperability, increased speed, and size economics. For example, BINARY_FLOAT requires five bytes and BINARY_DOUBLE requires nine bytes, as opposed to Oracle NUMBER using anywhere from 1 to 22 bytes. There are also important semantic differences between NUMBER and the BINARY_FLOAT and BINARY_DOUBLE types—for example, differences in rounding behavior (see the section on Precision). If you decide to use the new floating-point data types, then you should either consistently use them in new PL/SQL numerical intensive programs or modify existing programs to obtain better performance on platforms where floating-point numbers are natively part of the instruction set. Precision Although Oracle NUMBERs are portable across all software platforms, they are decimal as opposed to binary. The base affects many properties of the format, including rounding. For a decimal floating-point number, rounding is done to the nearest decimal place (for example, 1000, 10, or 0.01). For a binary floating-point number, rounding is done to the nearest binary place (for example, 1024, 512, or 1/64). Most financial applications require decimal-rounding behavior, whereas purely scientific applications may not. Oracle Database 10g: SQL and PL/SQL New Features

43 Floating-Point Special Values
Numeric literals use suffix f or d: Constant literals: BINARY_FLOAT_NAN BINARY_DOUBLE_NAN BINARY_FLOAT_INFINITY BINARY_DOUBLE_INFINITY 103948f d 3.0f 7.9d f Not A Number Floating-Point Special Values New numeric literals and constant literals are available to support the floating-point data types. You can also use the supporting functions that are discussed later in this lesson. You can specify floating-point numeric literals by using the syntax for Oracle NUMBER followed by a suffix. BINARY_FLOAT literals must have the suffix F or f; BINARY_DOUBLE literals must have the suffix D or d. Constant Literals Arithmetic operations on BINARY_FLOAT and BINARY_DOUBLE data types produce a numeric value or a special value. The string representations of the special values are 0, +INF (positive infinity), -INF (negative infinity), and NAN (Not A Number). Predefined constants are available in both SQL and PL/SQL to represent these special values. The constants available include: BINARY_FLOAT_NAN: A value v for which v IS NAN is true and sign(v)=1 BINARY_FLOAT_INFINITY: Single-precision positive infinity BINARY_DOUBLE_NAN: A value v for which v IS NAN is true and sign(v)=1 BINARY_DOUBLE_INFINITY: Double-precision positive infinity Note: SQL supports the constants that are listed above. PL/SQL implements a superset to support both normal and subnormal floating-point notations. Infinity Oracle Database 10g: SQL and PL/SQL New Features

44 Using Comparison Operations on Binary Floats
Rules: NAN is ordered as follows: All non-NAN < NAN Any NAN = any other NAN Infinity can be compared. -INF is the smallest value and +INF is the largest value. NAN = NAN returns TRUE NAN = 3.0f returns FALSE NAN != NAN returns FALSE NAN != 3.0f returns TRUE NAN > 3.0f returns TRUE Using Comparison Operations on Binary Floats You can use the following comparison operators for operations involving floating-point data types: Equal to Not equal to Greater than Greater than or equal to Less than Less than or equal to Unordered –INF < every finite number < +INF INF < 3.0f and +INF = +INF Oracle Database 10g: SQL and PL/SQL New Features

45 Oracle Database 10g: SQL and PL/SQL New Features 1 - 45
SQL Example CREATE TABLE t (f BINARY_FLOAT, d BINARY_DOUBLE); Table created. INSERT INTO t VALUES (2.0f, 2.0d); 1 row created. INSERT INTO t VALUES (1.5f/0.5f, 1.5d/0.5d); INSERT INTO t VALUES (BINARY_FLOAT_INFINITY, BINARY_DOUBLE_INFINITY); SELECT * FROM t; F D 2.0E E+000 3.0E E+000 Inf Inf Using the Binary Data Types in SQL You can use the binary-float and binary-double data types in SQL like any other scalar data type. In the example in the slide, a table is created with two columns: the first column uses the binary-float data type and the second column uses the binary-double data type. Data is inserted into the table. Note the use of the suffix extensions on the numbers to denote whether the value is a binary float or a binary double. The infinity values are inserted using the constant literals. You could also express the infinity value as a single quoted INF value. Although not shown, you can use either the NAN constant literals or a single quoted NAN value in your SQL statements. Untagged numeric literals in SQL are parsed as NUMBER. Oracle Database 10g: SQL and PL/SQL New Features

46 Oracle Database 10g: SQL and PL/SQL New Features 1 - 46
PL/SQL Example DECLARE bf_var BINARY_FLOAT := 2.0f; bd_var BINARY_DOUBLE := 2.0d; BEGIN bf_var := 1.5f/0.5f; bd_var := 1.5d/0.5d; dbms_output.put_line('Binary float value is: ' || bf_var); dbms_output.put_line('Binary double value is: ' || bd_var); END; Binary float value is: 3.0E+000 Binary double value is: 3.0E+000 PL/SQL procedure successfully completed. Using the Binary Data Types in PL/SQL PL/SQL supports the use of binary data types. In the example in the slide, two variables are created that are of the new floating-point data types. Note the use of the suffix extensions on the numbers to denote whether the value is a binary float or a binary double. Oracle Database 10g: SQL and PL/SQL New Features

47 Using the Floating-Point Literals
INSERT INTO t VALUES (BINARY_FLOAT_NAN, BINARY_DOUBLE_NAN); 1 row created. SELECT * FROM t; F D ... Nan Nan 1 DECLARE bf_var BINARY_FLOAT := BINARY_FLOAT_INFINITY; bd_var BINARY_DOUBLE := BINARY_DOUBLE_NAN; BEGIN dbms_output.put_line('Binary float value is: ' || bf_var); dbms_output.put_line('Binary double value is: ' || bd_var); END; 2 Floating-Point Constant Literals You can use the floating-point constant literals in both SQL and PL/SQL. In the first example, the constants for NAN are inserted into table t. In the second example, the constants for NAN and Infinity are assigned to local variables. The output is: Binary-float value is: Inf Binary-double value is: Nan PL/SQL procedure successfully completed. Note the values for Infinity and Not A Number are printed as INF and NAN, respectively. Oracle Database 10g: SQL and PL/SQL New Features

48 Floating-Point Exceptions
Cause Result INVALID OPERATION Arithmetic operations on infinities NAN INEXACT RESULT Loss of precision Any value, rounded ZERO DIVIDE Division by zero -INF, +INF, NAN NUMERIC OVERFLOW Value too large for precision limit -INF, +INF NUMERIC UNDERFLOW Value too small for precision limit Floating-Point Exceptions By the IEEE 754 standard, arithmetic operations on BINARY_FLOAT and BINARY_DOUBLE numeric values can raise five possible exceptions: INVALID_OPERATION, INEXACT_RESULT, ZERO_DIVIDE, NUMERIC_UNDERFLOW, and NUMERIC_OVERFLOW. IEEE 754 defines the behavior for the scenario where exceptions are either enabled or disabled. The Oracle database does not allow these exceptions to be enabled, so the behavior follows the IEEE 754 rules for the scenario where exceptions are disabled. Numeric Overflow and Underflow The NUMERIC_OVERFLOW exception is raised if a value is generated that is too large for the precision limit. The NUMERIC_UNDERFLOW exception is raised if a value is generated that is too tiny for the precision limit. The NUMERIC_UNDERFLOW exception is also raised if an arithmetic operation or conversion operation results in an extraordinary loss of accuracy. Oracle Database 10g: SQL and PL/SQL New Features

49 Floating-Point Exceptions: Example
SELECT f/0, d/0 FROM t; F/ D/0 Inf Inf Nan Nan 1 DECLARE bf_var BINARY_FLOAT := 2.0f; BEGIN bf_var := 1.5f/0; dbms_output.put_line('Binary float value is: ' || bf_var); END; 2 Floating-Point Exceptions: Example In the first example, the floating-point numbers in table T are divided by zero. According to the IEEE 754 standard, division by zero can result with a value of +INF, –INF, or NAN when exceptions are disabled. In the second example, the PL/SQL defines a local variable of the BINARY FLOAT type. Division by zero results in INF. Binary-float value is: Inf PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

50 Using the Floating-Point Functions
Description TO_BINARY_FLOAT Converts a BINARY_DOUBLE, NUMBER, VARCHAR2, or CHAR value to a BINARY_FLOAT value TO_BINARY_DOUBLE Converts a BINARY_FLOAT, NUMBER, VARCHAR2, or CHAR value to a BINARY_DOUBLE value IS [NOT] NAN Determines whether or not a floating-point value is NAN IS [NOT] INFINITE Determines whether or not a floating-point value is positive infinity or negative infinity NANVL Translates a NAN to a specified value Using the Floating-Point Functions You can use the floating-point functions that are available with the new floating-point data types. Oracle Database 10g: SQL and PL/SQL New Features

51 Using the Floating-Point Functions: Example
COLUMN "Inf Test" format a10 SELECT CASE WHEN f IS INFINITE THEN 'gi-normous' ELSE TO_CHAR(f) END "Inf Test", NANVL(f, 0) FROM t; Inf Test NANVL(F,0) 2.0E E+000 3.0E E+000 gi-normous Inf Nan Using the Floating-Point Functions (continued) In the example shown in the slide, the IS INFINITE function is used to determine whether the values in the columns of table T are either positive or negative infinity. The NANVL function substitutes a numeric value for the NAN value. Oracle Database 10g: SQL and PL/SQL New Features

52 Using Conversion Operations on Binary Floats
Be careful—the conversions may not be exact because different bases are used: From BINARY_FLOAT or BINARY_DOUBLE to a CHARACTER type From BINARY_FLOAT or BINARY_DOUBLE to a NUMBER From NUMBER to BINARY_FLOAT or BINARY_DOUBLE From BINARY_DOUBLE to BINARY_FLOAT Floating-Point Conversion Operations Operations with operands in different format types (for example, multiplying a NUMBER type with a BINARY_DOUBLE type) are resolved via implicit conversion of one or all the operands to a common numeric type before the operation is performed. In most cases, default rounding is used. Here are some rules governing conversions: From BINARY_FLOAT or BINARY_DOUBLE to a CHARACTER type: The conversion may not be exact because CHARACTER uses base 10 to represent a number as opposed to base 2. The resultant string does not have the type-specific suffix f or d. From BINARY_FLOAT or BINARY_DOUBLE to a NUMBER: The conversion may not be exact because NUMBER uses base 10. If the BINARY_FLOAT or BINARY_DOUBLE represents NAN, an Oracle error is raised. Positive or negative infinity is converted to an Oracle NUMBER that represents positive or negative infinity. If a BINARY_DOUBLE exceeds the range supported by Oracle NUMBER and the exponent is negative, then underflow occurs and the result is 0. If a BINARY_DOUBLE exceeds the range supported by Oracle NUMBER and the exponent is positive, overflow occurs and the result is positive or negative infinity. The sign for the infinity result is determined by the sign of the BINARY_DOUBLE. Oracle Database 10g: SQL and PL/SQL New Features

53 Performance Example: Binary Float Versus Number
Application: Use binary floats in arithmetic computation–intensive applications. For simple looping constructs, PLS_INTEGER is sufficient. Note: Do not use binary floats for financial applications due to rounding differences between the bases. Examining Binary-Float Performance Binary floats are most useful in arithmetic computation–intensive applications. Generally, arithmetic and math functions that use the binary-float data types are faster and also may use less disk space. However, for simple looping constructs, the PLS_INTEGER data type is sufficient. The example on the next page demonstrates the performance benefit of the binary float over the NUMBER data type. Oracle Database 10g: SQL and PL/SQL New Features

54 Examining Binary-Float Performance
CREATE OR REPLACE PROCEDURE Leibniz_Pi_Series IS SUBTYPE Math_Real IS BINARY_DOUBLE; Expected_Pi CONSTANT Math_Real := d; --SUBTYPE Math_Real IS NUMBER; -- Expected_Pi CONSTANT Math_Real := ; ... EXECUTE Leibniz_Pi_Series 330 centiseconds CREATE OR REPLACE PROCEDURE Leibniz_Pi_Series IS --SUBTYPE Math_Real IS BINARY_DOUBLE; -- Expected_Pi CONSTANT Math_Real := d; SUBTYPE Math_Real IS NUMBER; Expected_Pi CONSTANT Math_Real := ; ... EXECUTE Leibniz_Pi_Series 1135 centiseconds Examining Binary-Float Performance (continued) The slide shows the resulting timing from executing the LEIBNIZ_PI_SERIES procedure defined on the previous page. Note the timing difference between using a BINARY_DOUBLE data type and a NUMBER data type. Oracle Database 10g: SQL and PL/SQL New Features

55 Oracle Database 10g: SQL and PL/SQL New Features 1 - 56
Lesson Agenda Using the new native floating-point data types Supporting NCHAR string literals Changing LONG and LONG RAW columns to LOBs Oracle Database 10g: SQL and PL/SQL New Features

56 Supporting NCHAR String Literals
SQL NCHAR literals used in insert and update statements no longer rely on the database character set for conversion. Multilingual data can be added without restrictions such as having to provide hex Unicode values. Support for this feature is available in SQL, PL/SQL, OCI, and JDBC. Database side NCHAR Uses database character set Uses client character set: NLS_LANG OCI UTF-16 Support for NCHAR String Literals In previous releases of the database, you had the potential to lose data when performing NCHAR string literal replacement. The NCHAR literal is represented as N' (N-Quote). Within a SQL or PL/SQL statement, the text of any literal, with or without the prefix N, is encoded in the same character set as the rest of the statement. On the client side, the statement is in the client character set, which is determined by the client character set defined in NLS_LANG, or specified in the OCIEnvNlsCreate() call, or predefined as UTF-16 in JDBC. On the server side, the statement is in the database character set. When the SQL or PL/SQL statement is transferred from the client to the database server, its character set is converted accordingly. It is important to note that if the database character set does not contain all characters used in the text literals, then the data is lost in this conversion. This problem affects NCHAR string literals more than the CHAR text literals. This is because the N' literals are designed to be independent of the database character set, and should be able to provide any data that the client character set supports. To avoid data loss in conversion to an incompatible database character set, you can activate the NCHAR literal replacement functionality. The functionality transparently replaces the N' literals on the client side with an internal format. The database server then decodes this to Unicode when the statement is executed. NCHAR Client side Oracle Database 10g: SQL and PL/SQL New Features

57 Supporting NCHAR String Literals
On the database side, set the environment variable $ORA_NCHAR_LITERAL_REPLACE to TRUE. This setting transparently replaces the N'text' internally and preserves the text literal for SQL processing. On the client side, set the property specific to the language. Support for NCHAR String Literals (continued) To avoid potential loss of data during the text literal conversion, set the environment variable $ORA_NCHAR_LITERAL_REPLACE to TRUE. This setting transparently replaces the N'text' internally and preserves the text literal for SQL processing. On the client side, set the property specific to the language. For more information, refer to the Oracle Database Globalization Support Guide. Oracle Database 10g: SQL and PL/SQL New Features

58 Oracle Database 10g: SQL and PL/SQL New Features 1 - 59
Lesson Agenda Using the new native floating-point data types Supporting NCHAR string literals Changing LONG and LONG RAW columns to LOBs Oracle Database 10g: SQL and PL/SQL New Features

59 Support for Additional Data Types
LONG > CLOB LONG RAW > BLOB Changing LONG and LONG RAW Columns to LOBs In earlier releases, there were some restrictions on online redefinition of tables containing certain data types. In Oracle Database 10g, the following additional data types are supported for online redefinition: Tables with columns defined as LONG can be redefined online. The LONG column must be converted to character large object (CLOB). Tables with columns defined as LONG RAW can be defined online. The LONG RAW column must be converted to binary large object (BLOB). This information is covered in detail in the lesson titled “Using Large Object (LOB) Enhancements.” Oracle Database 10g: SQL and PL/SQL New Features

60 Oracle Database 10g: SQL and PL/SQL New Features 1 - 61
Summary In this lesson, you should have learned how to: Use the new native floating-point data types BINARY_FLOAT BINARY_DOUBLE Supporting functions Exceptions Use NCHAR literals in data manipulation language (DML) Convert LONG and LONG RAW columns to LOBs Summary In this lesson, you learned how and when to use the new binary-float data types. These data types are available to you starting in Oracle Database 10g and they follow the IEEE 754 standard for floating-point data types. You also learned about the enhancements to the NCHAR literals and LONG and LONG RAW column conversions. Oracle Database 10g: SQL and PL/SQL New Features

61 Practice 2-1 Overview: Using the Floating-Point Data Types
This practice covers the following topics: Determining when floating-point data types are appropriate Using the floating-point constants and expressions Analyzing results when using floating-point data types Practice 2-1 Overview: Using the Floating-Point Data Types In this practice, you analyze situations and determine when floating-point numbers are needed and you use the new IEEE floating-point data types. Oracle Database 10g: SQL and PL/SQL New Features

62 Using Large Object (LOB) Enhancements

63 Oracle Database 10g: SQL and PL/SQL New Features 1 - 64
Objectives After completing this lesson, you should be able to do the following: Review large object (LOB) data types Identify the LOB enhancements Convert between CLOB and NCLOB data types Oracle Database 10g: SQL and PL/SQL New Features

64 Oracle Database 10g: SQL and PL/SQL New Features 1 - 65
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

65 Oracle Database 10g: SQL and PL/SQL New Features 1 - 66
What Is a LOB? LOBs are used to store large unstructured data such as text, graphic images, films, and sound waveforms. “Four score and seven years ago our fathers brought forth upon this continent, a new nation, conceived in LIBERTY, and dedicated to the proposition that all men are created equal.” LOB: Overview A LOB is a data type that is used to store large, unstructured data such as text, graphic images, video clippings, and so on. Structured data, such as a customer record, may be a few hundred bytes, but even small amounts of multimedia data can be thousands of times larger. Also, multimedia data may reside in operating system (OS) files, which may need to be accessed from a database. There are four large object data types: BLOB represents a binary large object, such as images, audio, and video. CLOB represents a character large object. Used for large strings or documents that use the database character set exclusively (fixed width format). NCLOB represents a multibyte character large object. Stores string data in National Character Set format. Used for large strings or documents in the National Character Set. It supports characters of varying width format. BFILE represents a binary file stored in an OS binary file outside the database. The BFILE column or attribute stores a file locator that points to the external file. LOBs are characterized as either binary or character. LOBs can be stored internally (inside the database) or in host files. There are two categories of LOBs: Internal LOBs (CLOB, NCLOB, BLOB): Stored in the database External files (BFILE): Stored outside the database Movie (BFILE) Text (CLOB) Photo (BLOB) Oracle Database 10g: SQL and PL/SQL New Features

66 Oracle Database 10g: SQL and PL/SQL New Features 1 - 67
Anatomy of a LOB The LOB column stores a locator to the LOB’s value. LOB locator LOB column of a table LOB value Components of a LOB There are two distinct parts to a LOB: LOB value: The data that constitutes the real object being stored LOB locator: A pointer to the location of the LOB value stored in the database Regardless of where the value of LOB is stored, a locator is stored in the row. You can think of a LOB locator as a pointer to the actual location of the LOB value. A LOB column does not contain the data; it contains the locator of the LOB value. When a user creates an internal LOB, the value is stored in the LOB segment and a locator to the out-of-line LOB value is placed in the LOB column of the corresponding row in the table. External LOBs store the data outside the database, so only a locator to the LOB value is stored in the table. To access and manipulate LOBs without SQL DML, you must create a LOB locator. The programmatic interfaces operate on the LOB values, using these locators in a manner similar to OS file handles. Oracle Database 10g: SQL and PL/SQL New Features

67 Oracle Database 10g: SQL and PL/SQL New Features 1 - 68
Internal LOBs The LOB value is stored in the database. “Four score and seven years ago our fathers brought forth upon this continent, a new nation, conceived in LIBERTY, and dedicated to the proposition that all men are created equal.” Features of Internal LOBs The internal LOB is stored in the Oracle server. A BLOB, NCLOB, or CLOB can be one of the following: An attribute of a user-defined type A column in a table A bind or host variable A PL/SQL variable, parameter, or result Internal LOBs can take advantage of Oracle features such as: Concurrency mechanisms Redo logging and recovery mechanisms Transactions with COMMIT or ROLLBACK The BLOB data type is interpreted by the Oracle server as a bitstream, similar to the LONG RAW data type. The CLOB data type is interpreted as a single-byte character stream. The NCLOB data type is interpreted as a multiple-byte character stream, based on the byte length of the database national character set. CLOB BLOB Oracle Database 10g: SQL and PL/SQL New Features

68 Managing Internal LOBs
SELECT FOR UPDATE Create the table with the LOB column. Declare and initialize the LOB locator. Lock the row containing the LOB. Managing Internal LOBs To manage an internal LOB, perform the following steps: 1. Create and populate the table containing the LOB data type. 2. Declare and initialize the LOB locator in the program. 3. Use SELECT FOR UPDATE to lock the row containing the LOB into the LOB locator. 4. Manipulate the LOB with DBMS_LOB package procedures, OCI calls, Oracle Objects for OLE, Oracle precompilers, or JDBC using the LOB locator as a reference to the LOB value. You can also manage LOBs through SQL. 5. Use the COMMIT command to make any changes permanent. How to Manage LOBs To interact fully with LOB, file-like interfaces are provided in: PL/SQL package DBMS_LOB Oracle Call Interface (OCI) Oracle Objects for object linking and embedding (OLE) Pro*C/C++ and Pro*COBOL precompilers JDBC (Java Database Connectivity) The Oracle server provides some support for LOB management through SQL. Use COMMIT to make changes permanent. Manipulate the LOB. Oracle Database 10g: SQL and PL/SQL New Features

69 Oracle Database 10g: SQL and PL/SQL New Features 1 - 70
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

70 Large Object Enhancements: Overview
Increased LOB size limit from 4 GB to 8–128 TB LOB performance enhancements: LOB performance enhancements in INSERT, UPDATE, and SELECT operations Direct support for LOBs in the JDBC Thin driver Regular expression support Improved parallel LONG-to-LOB migration Implicit conversion between NCLOB and CLOB New ABSTRACT_LOBS column added to the V$TEMPORARY_LOBS table Large Object Enhancements: Overview The following are the LOB enhancements in Oracle Database 10g: Increased LOB size limit: Previous releases supported LOBs up to a maximum size of 4 GB. The maximum size limit for LOBs is 8 to 128 terabytes, depending on your database block size. The following support this new size limit: The DBMS_LOB PL/SQL package C: Using the Oracle Call Interface (OCI) Java: Using the Java Database Connectivity (JDBC) Performance enhancements: Enhanced LOB performance in INSERT, UPDATE, and SELECT operations Direct support for LOBs in the JDBC Thin driver. The JDBC Thin driver now provides direct support for BFILEs, BLOBs, and CLOBs. Before this release, it supported them through calls to PL/SQL routines. Regular expression support: A set of SQL functions introduced in this release enable you to perform queries and manipulate string data stored in LOB data types and other character data types using regular expressions. You can use these functions on a text literal, bind variable, or any column that holds character data such as CLOB and NCLOB. Note: Regular expressions are covered in the lesson titled “Using Regular Expressions and Linguistic Sort and Comparison.” Oracle Database 10g: SQL and PL/SQL New Features

71 Large Object Enhancements: Overview
NCLOB is allowed as an attribute of an object type at table creation. LOB columns are now supported in all types of partitioned index-organized tables. Data interface support is available for remote LOBs. Reading and writing LOB data for multiple locators in one round-trip is supported by new OCI functions. Large Object Enhancements: Overview (continued) NCLOB as an attribute of an object type at table creation: In previous releases, you could not specify an NCLOB as an attribute of an object type when creating a table. This restriction no longer applies. Partitioned index-organized tables LOB support: LOB columns are now supported in all types of partitioned index-organized tables. You can partition tables that contain LOB columns. As a result, LOBs can take advantage of all of the benefits of partitioning including the following: LOB segments can be spread between several tablespaces to balance I/O load and to make backup and recovery more manageable. LOBs in a partitioned table become easier to maintain. Data interface for remote LOBs: In Oracle Database 10g, the data interface for LOBs enables you to INSERT, UPDATE, and SELECT LOBs across remote databases using database links. Read and write of LOB data for locators supported by new OCI functions: Two new LOB APIs OCILobArrayRead and OCILobArrayWrite are introduced. OCILobArrayRead() OCI reads LOB data for multiple locators in one round-trip. OCILobArrayWrite() OCI writes LOB data for multiple locators in one round-trip. Oracle Database 10g: SQL and PL/SQL New Features

72 Oracle Database 10g: SQL and PL/SQL New Features 1 - 73
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

73 Migrating from LONG to LOB
You can migrate LONG columns to LOB columns. Data migration consists of the procedure to move existing tables containing LONG columns to use LOBs: Application migration consists of changing existing LONG applications to work with LOB data types. ALTER TABLE [<schema>.] <table_name> MODIFY (<long_col_name> {CLOB | BLOB | NCLOB}[DEFAULT <default_value>]) Migrating from LONG to LOB You can use an API to migrate LONG to LOB. In data migration, existing tables that contain LONG columns need to be moved to use LOB columns. This can be done by using the ALTER TABLE command. Before Oracle9i (Oracle8i), an operator named TO_LOB had to be used to copy a LONG to a LOB. You can modify a LONG column to a CLOB or an NCLOB column and a LONG RAW column to a BLOB column. Note: The ALTER TABLE statement copies the contents of the table into a new space, and frees the old space at the end of the operation. This temporarily doubles the space requirements for both the LONG and LOB data. The constraints of the LONG column (NULL and NOT NULL are the only allowed constraints) are maintained for the new LOB columns. The default value specified for the LONG column is also copied to the new LOB column. For example, suppose you have the following table: CREATE TABLE long_tab (id NUMBER, long_col LONG); To change the long_col column in long_tab table to the CLOB data type, use: ALTER TABLE long_tab MODIFY ( long_col CLOB ); In application migration, the existing programmatic environments (such as PL/SQL packages and OCIs) that support LONG data types, are changed to support LOB data types as well. You can use SQL and PL/SQL to access LONGs and LOBs. The LONG-to-LOB migration API is provided for both OCI and PL/SQL. Oracle Database 10g: SQL and PL/SQL New Features

74 Migrating from LONG to LOB
Explicit conversion: TO_CLOB() converts LONG, VARCHAR2, and CHAR to CLOB. TO_BLOB() converts LONG RAW and RAW to BLOB. Implicit conversion: From LONG (LONG RAW) or a VARCHAR2(RAW) variable to a CLOB (BLOB) variable, and vice versa During function and procedure parameter passing, you can: Use CLOBs and BLOBs as actual parameters, and Use VARCHAR2, LONG, RAW, and LONG RAW as formal parameters, and vice versa LOB data is acceptable in most of the SQL and PL/SQL operators and built-in functions. Migrating from LONG to LOB (continued) With the new LONG-to-LOB API introduced in Oracle Database 10g, data from CLOB and BLOB columns can be referenced by regular SQL and PL/SQL statements. Implicit assignment and parameter passing: The LONG-to-LOB migration API supports assigning a CLOB (BLOB) variable to a LONG (LONG RAW) or a VARCHAR2(RAW) variable, and vice versa. Explicit conversion functions: You can convert other data types to CLOB and BLOB as part of LONG-to-LOB migration using the following explicit conversion functions: TO_CLOB() converts LONG, VARCHAR2, and CHAR to CLOB. TO_BLOB() converts LONG RAW and RAW to BLOB. Note: TO_CHAR() is enabled to convert a CLOB to a CHAR type. Function and procedure parameter passing: Enables the use of CLOBs and BLOBs as actual parameters where VARCHAR2, LONG, RAW, and LONG RAW are formal parameters, and vice versa. In SQL and PL/SQL built-in functions and operators, a CLOB can be passed to SQL and PL/SQL VARCHAR2 built-in functions, behaving exactly like a VARCHAR2. Or the VARCHAR2 variable can be passed into DBMS_LOB APIs acting like a LOB locator. For more information, see “Migrating from LONGs to LOBs” in Application Developer’s Guide - Large Objects. Oracle Database 10g: SQL and PL/SQL New Features

75 Oracle Database 10g: SQL and PL/SQL New Features 1 - 76
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

76 Oracle Database 10g: SQL and PL/SQL New Features 1 - 77
The DBMS_LOB Package Working with LOBs often requires the use of the Oracle-supplied DBMS_LOB package. DBMS_LOB provides routines to access and manipulate internal and external LOBs. Oracle Database 10g enables retrieving LOB data directly using SQL without a special LOB API. In PL/SQL, you can define a VARCHAR2 for a CLOB and a RAW for a BLOB. The DBMS_LOB Package In releases before Oracle9i, you must use the DBMS_LOB package for retrieving data from LOBs. To create the DBMS_LOB package, the dbmslob.sql and prvtlob.plb scripts must be executed as SYS. The catproc.sql script executes the scripts. Then users can be granted appropriate privileges to use the package. The package does not support any concurrency control mechanism for BFILE operations. The user is responsible for locking the row containing the destination internal LOB before calling any subprograms that involve writing to the LOB value. These DBMS_LOB routines do not implicitly lock the row containing the LOB. The two constants, LOBMAXSIZE and FILE_READONLY, defined in the package specification are also used in the procedures and functions of DBMS_LOB—for example, use them to achieve the maximum level of purity to be used in SQL expressions. The DBMS_LOB functions and procedures can be broadly classified into two types: mutators and observers. The mutators can modify LOB values: APPEND, COPY, ERASE, TRIM, WRITE, FILECLOSE, FILECLOSEALL, and FILEOPEN. The observers can read LOB values: COMPARE, FILEGETNAME, INSTR, GETLENGTH, READ, SUBSTR, FILEEXISTS, and FILEISOPEN. Oracle Database 10g: SQL and PL/SQL New Features

77 Initializing LOB Columns Added to a Table
Create the table with columns using the LOB type, or add the LOB columns by using ALTER TABLE. Initialize the column LOB locator value with the DEFAULT option or DML statements by using: EMPTY_CLOB() function for a CLOB column EMPTY_BLOB() function for a BLOB column ALTER TABLE employees ADD (resume CLOB, picture BLOB); CREATE TABLE emp_hiredata ( employee_id NUMBER(6), full_name VARCHAR2(45), resume CLOB DEFAULT EMPTY_CLOB(), picture BLOB DEFAULT EMPTY_BLOB()); Initializing LOB Columns Added to a Table LOB columns are defined by using SQL data definition language (DDL), as in the ALTER TABLE statement in the slide. The contents of a LOB column are stored in the LOB segment, whereas the column in the table contains only a reference to that specific storage area, called the LOB locator. In PL/SQL, you can define a variable of the LOB type, which contains only the value of the LOB locator. You can initialize the LOB locators using: EMPTY_CLOB() function for a CLOB column EMPTY_BLOB() function for a BLOB column Note: These functions create the LOB locator value and not the LOB content. In general, you use the DBMS_LOB package subroutines to populate the content. The functions are available in Oracle SQL DML, and are not part of the DBMS_LOB package. The last example in the slide shows how you can use the EMPTY_CLOB() and EMPTY_BLOB() functions in the DEFAULT option in a CREATE TABLE statement. In this way, the LOB locator values are populated in their respective columns when a row is inserted into the table and the LOB columns have not been specified in the INSERT statement. The next page shows how to use the functions in INSERT and UPDATE statements to initialize the LOB locator values. Oracle Database 10g: SQL and PL/SQL New Features

78 Populating LOB Columns
Insert rows into a table with LOB columns: Initialize a LOB using the EMPTY_BLOB() function and update a CLOB column: INSERT INTO emp_hiredata (employee_id, full_name, resume, picture) VALUES (405, 'Marvin Ellis', EMPTY_CLOB(), NULL); VALUES (170, 'Joe Wolf', 'Date of Birth: 1 June 1956', NULL); UPDATE emp_hiredata SET picture = EMPTY_BLOB(), resume = 'Date of Birth: 8 February 1951' WHERE employee_id = 405; Populating LOB Columns You can insert a value directly into a LOB column by using host variables in SQL or in PL/SQL, 3GL-embedded SQL, or OCI. You can use the special EMPTY_BLOB()and EMPTY_CLOB() functions in INSERT or UPDATE statements of SQL DML to initialize a NULL or non-NULL internal LOB to empty. You can populate a LOB column as follows: 1. Initialize the LOB column to a non-NULL value—that is, set a LOB locator pointing to an empty or populated LOB value. This is done by using EMPTY_BLOB()and EMPTY_CLOB() functions. 2. Populate the LOB contents by using the DBMS_LOB package routines. However, as shown in the slide examples, the two UPDATE statements initialize the resume LOB locator value and populate its contents by supplying a literal value. This can also be done in an INSERT statement. A LOB column can be updated to: Another LOB value A NULL value A LOB locator with empty contents by using the EMPTY_*LOB() built-in function You can update the LOB by using a bind variable in embedded SQL. When assigning one LOB to another, a new copy of the LOB value is created. Use a SELECT FOR UPDATE statement to lock the row containing the LOB column before updating a piece of the LOB contents. Oracle Database 10g: SQL and PL/SQL New Features

79 Updating LOB by Using DBMS_LOB in PL/SQL
DECLARE lobloc CLOB; serves as the LOB locator text VARCHAR2(50) := 'Resigned = 5 June 2000'; amount NUMBER ; -- amount to be written offset INTEGER; -- where to start writing BEGIN SELECT resume INTO lobloc FROM emp_hiredata WHERE employee_id = 405 FOR UPDATE; offset := DBMS_LOB.GETLENGTH(lobloc) + 2; amount := length(text); DBMS_LOB.WRITE (lobloc, amount, offset, text); text := ' Resigned = 30 September 2000'; WHERE employee_id = 170 FOR UPDATE; DBMS_LOB.WRITEAPPEND(lobloc, amount, text); COMMIT; END; / Updating LOB by Using DBMS_LOB in PL/SQL In the example in the slide, the LOBLOC variable serves as the LOB locator, and the AMOUNT variable is set to the length of the text you want to add. The SELECT FOR UPDATE statement locks the row and returns the LOB locator for the RESUME LOB column. Finally, the PL/SQL WRITE package procedure is called to write the text into the LOB value at the specified offset. WRITEAPPEND appends to the existing LOB value. The example shows how to fetch a CLOB column in releases before Oracle9i. In those releases, it was not possible to fetch a CLOB column directly into a character column. The column value needed to be bound to a LOB locator, which is accessed by the DBMS_LOB package. An example later in this lesson shows that you can directly fetch a CLOB column by binding it to a character variable. Note: Versions before Oracle9i did not allow LOBs in the WHERE clause of UPDATE and SELECT statements. Now SQL functions of LOBs are allowed in predicates of WHERE. An example is shown later in this lesson. Oracle Database 10g: SQL and PL/SQL New Features

80 Selecting CLOB Values by Using SQL
SELECT employee_id AS ID, full_name, resume -- CLOB FROM emp_hiredata WHERE employee_id IN (405, 170); ID FULL_NAME RESUME 405 Marvin Ellis Date of Birth: 8 February 1951 Resigned = 5 June 2000 170 Joe Wolf Date of Birth: 1 June 1956 Resigned = 30 September 2000 Selecting CLOB Values by Using SQL It is possible to see the data in a CLOB column by using a SELECT statement. It is not possible to see the data in a BLOB or BFILE column by using a SELECT statement in iSQL*Plus. You have to use a tool that can display binary information for a BLOB, as well as the relevant software for a BFILE—for example, you can use Oracle Forms. Oracle Database 10g: SQL and PL/SQL New Features

81 Selecting CLOB Values by Using DBMS_LOB
DBMS_LOB.SUBSTR (lob_loc, amount, start_pos) DBMS_LOB.INSTR (lob_loc, pattern,[offset],[occurrence]) SELECT DBMS_LOB.SUBSTR (resume, 5, 18), DBMS_LOB.INSTR (resume,' = ') FROM emp_hiredata WHERE employee_id IN (170, 405); DBMS_LOB.SUBSTR(RESUME,5,18) DBMS_LOB.INSTR(RESUME,'=') Febru June Selecting CLOB Values by Using DBMS_LOB DBMS_LOB.SUBSTR Use DBMS_LOB.SUBSTR to display a part of a LOB. It is similar in functionality to the SUBSTR SQL function. The default for the starting position is 1. DBMS_LOB.INSTR Use DBMS_LOB.INSTR to search for information within the LOB. This function returns the numerical position of the information. The default value for the offset (starting position) and occurrence is 1. Note: Starting with Oracle9i, you can also use the SUBSTR and INSTR SQL functions to perform the operations shown in the slide. Oracle Database 10g: SQL and PL/SQL New Features

82 Selecting CLOB Values in PL/SQL and Implicit Conversion
SET LINESIZE 50 SERVEROUTPUT ON FORMAT WORD_WRAP DECLARE text VARCHAR2(4001); /* The RESUME column value is implicitly converted from a CLOB into a VARCHAR2 and stored in TEXT. */ BEGIN SELECT resume INTO text FROM emp_hiredata WHERE employee_id = 170; DBMS_OUTPUT.PUT_LINE('Text is: '|| text); END; / Text is: Date of Birth: 1 June 1956 Resigned = 30 September 2000 PL/SQL procedure successfully completed. Selecting CLOB Values in PL/SQL The slide shows the code for accessing CLOB values that can be implicitly converted to VARCHAR2 in Oracle Database 10g. When selected, the RESUME column value is implicitly converted from a CLOB into a VARCHAR2 to be stored in the TEXT variable. Before Oracle9i, you first retrieved the CLOB locator value into a CLOB variable, and then read the LOB contents specifying the amount and offset in the DBMS_LOB.READ procedure: DECLARE rlob CLOB; text VARCHAR2(4001); amt NUMBER := 4001; offset NUMBER := 1; BEGIN SELECT resume INTO rlob FROM emp_hirdata WHERE employee_id = 170; DBMS_LOB.READ(rlob, amt, offset, text); DBMS_OUTPUT.PUT_LINE('text is: '|| text); END; / Oracle Database 10g: SQL and PL/SQL New Features

83 Oracle Database 10g: SQL and PL/SQL New Features 1 - 84
Removing LOBs Delete a row containing LOBs: Disassociate a LOB value from a row: DELETE FROM emp_hiredata WHERE employee_id = 405; UPDATE emp_hiredata SET resume = EMPTY_CLOB() WHERE employee_id = 170; Removing LOBs A LOB instance can be deleted (destroyed) using appropriate SQL DML statements. The SQL statement DELETE deletes a row and its associated internal LOB value. To preserve the row and destroy only the reference to the LOB, you must update the row by replacing the LOB column value with NULL or an empty string, or by using the EMPTY_B/CLOB() function. Note: Replacing a column value with NULL and using EMPTY_B/CLOB are not the same. Using NULL sets the value to null; using EMPTY_B/CLOB ensures that there is nothing in the column. A LOB is destroyed when the row containing the LOB column is deleted, when the table is dropped or truncated, or when all the LOB data is updated. You must explicitly remove the file associated with a BFILE using OS commands. To erase part of an internal LOB, you can use DBMS_LOB.ERASE. Oracle Database 10g: SQL and PL/SQL New Features

84 Oracle Database 10g: SQL and PL/SQL New Features 1 - 85
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

85 Conversion Between CLOB and NCLOB
Transparent implicit conversion: SQL IN and OUT bind variables for query and DML PL/SQL function and procedure parameter passing PL/SQL variable assignment CLOB NCLOB Implicit Conversion Between CLOB and NCLOB The requirement to convert data between Unicode and the database national language character set is becoming more common. Explicit conversion between CLOB and NCLOB is already available in SQL and in PL/SQL via the TO_CLOB and TO_NCLOB functions. Oracle Database 10g introduces implicit conversion for SQL IN and OUT bind variables in queries and DML operations, as well as for PL/SQL function and procedure parameter passing, and PL/SQL variable assignment. Oracle Database 10g: SQL and PL/SQL New Features

86 Oracle Database 10g: SQL and PL/SQL New Features 1 - 87
Lesson Agenda Reviewing large object (LOB) data types Identifying LOB enhancements Migrating from LONG to LOB Updating, selecting, and removing LOBs Converting between CLOB and NCLOB Using LOBs with abstract data types, remote databases, and array read/write Oracle Database 10g: SQL and PL/SQL New Features

87 Data Interface for LOBs in Abstract Data Types
-- Insert a value of type RAW into an abstract data type -- column in the PRINT_MEDIA table that has a BLOB -- attribute. DECLARE my_logo RAW(6000) := hextoraw(LPAD ('b',6000, 'b')); BEGIN INSERT INTO print_media(product_id, ad_id, ad_header) VALUES (10000, 10, adheader_typ ('1726', SYSDATE, 123, my_logo) ); END; / Data Interface for LOBs in Abstract Data Types In earlier releases, the Oracle Database allowed character data to be bound to CLOB columns and raw data to BLOB columns for insert and update through PL/SQL, OCI, and JDBC. However, if the LOB was an attribute of an ADT, you could only bind a LOB to it for insert and update. Oracle Database 10g Release 2 allows character and RAW binds to LOBs that are attributes of abstract data type (ADT) columns, using PL/SQL, OCI, and all JDBC interfaces without having to use a LOB locator. In the example in the slide, you are inserting into the PRINT_MEDIA table (in the PM schema) a value of type RAW into an abstract data type column that has a BLOB attribute. Note: In order for this example to work, you must disable the foreign key constraint on the print_media table as follows: ALTER TABLE print_media DISABLE CONSTRAINT PRINTMEDIA_FK; Oracle Database 10g: SQL and PL/SQL New Features

88 Data Interface for Remote LOBs
-- In 10g, the data interface for LOBs enables you to -- INSERT, UPDATE, and SELECT LOBs across remote -– databases using database links. DECLARE my_ad VARCHAR(6000) := LPAD('b', 6000,'b'); BEGIN INSERT INTO product_id, ad_id, ad_finaltext) VALUES (10000, 10, my_ad); -- Reset the buffer value my_ad := 'a'; SELECT ad_finaltext INTO my_ad FROM WHERE product_id = 10000; . . . END; Data Interface for Remote LOBs Since release Oracle9i, the Oracle database has supported binding and defining LOB columns as character or RAW types. This interface for accessing LOBs is called the data interface. However, the data interface did not support retrieval of LOBs across database links. One workaround was to have a local table with a CLOB, and perform an insert-as-remote-select of the remote CLOB to insert it into the local table, and then read from the local table. This was very inefficient because of duplicate reading and writing of data. In Oracle Database 10g Release 2, the data interface for LOBs enables you to insert, update, and select LOBs across remote databases using database links. Assume that this table exists in two databases: db1 and db2. The LOB relevant to the discussion here is PRINT_MEDIA.AD_FINALTEXT. In the example shown in the graphic, you are inserting into and retrieving from the PRINT_MEDIA table that is in db2 while logged into db1. The database link for the db2 database is DBS2. This functionality is new to Oracle Database 10g Release 2. Distributed LOB support provides easy-to-use and efficient support for accessing unstructured data in a distributed environment. Oracle Database 10g: SQL and PL/SQL New Features

89 Support for LOB Array Read and Write
LOB array read and write functionality enables applications to pass multiple locators in a single LOB read and write call. Applications can use the array interface to read large amount of LOB data for multiple locators in one round-trip. The two new LOB APIs are: OCILobArrayRead   OCILobArrayWrite Support for LOB Array Read and Write Oracle Database 10g Release 2 supports LOB array read and write functionality This feature enables applications to pass multiple locators in a single LOB read or write call. Applications can use the array interface to read LOB data for multiple locators in one round-trip, which improves performance. Two new LOB APIs OCILobArrayRead and OCILobArrayWrite are introduced. Note: For detailed information on the new OCILobArrayRead and OCILobArrayWrite APIs, see the Oracle Database Application Developer’s Guide - Large Objects 10g Release 2 (10.2) guide. Oracle Database 10g: SQL and PL/SQL New Features

90 Oracle Database 10g: SQL and PL/SQL New Features 1 - 91
Summary In this lesson, you should have learned how to: Review large object (LOB) data types Identify the LOB enhancements Convert between CLOB and NCLOB data types Oracle Database 10g: SQL and PL/SQL New Features

91 Oracle Database 10g: SQL and PL/SQL New Features 1 - 92
Practice 3: Overview This practice covers the following topics: Creating object types using the CLOB and BLOB data types Creating a table with LOB data types as columns Using the DBMS_LOB package to populate and interact with the LOB data Practice 3: Overview In this practice, you create a table with both BLOB and CLOB columns. Then you use the DBMS_LOB package to populate the table and manipulate the data. Oracle Database 10g: SQL and PL/SQL New Features

92 Using Nested Table and VARRAY Enhancements

93 Oracle Database 10g: SQL and PL/SQL New Features 1 - 94
Objectives After completing this lesson, you should be able to: Describe the collection enhancements Change the size of a VARRAY Support VARRAY columns in temporary tables Use a different tablespace for a nested table’s storage table Describe nested table support for predicates, operators returning nested tables, and aggregation functions Use the multiset operators on collections Objectives In this lesson, you learn about the enhancements made to nested collections. Nested collections are sets of data elements. With a nested table, the set is unordered. With a VARRAY, the set is ordered. Oracle collections consist of nested tables and VARRAYs. In ANSI, nested tables are called “multisets” and VARRAYs are called “arrays.” ANSI defines operations for multisets and arrays. In Oracle Database 10g, additional functionality is added in compliance with the standards. Note: If you are not familiar with collections, refer to the appendix titled “Working with Collections.” Oracle Database 10g: SQL and PL/SQL New Features

94 Oracle Database 10g: SQL and PL/SQL New Features 1 - 95
Lesson Agenda Introducing collection enhancements VARRAY and nested table enhancements Adjusting the size Using VARRAYs in temporary tables Changing the tablespace storage Using the ANSI support on nested table collections Using the multiset operators Oracle Database 10g: SQL and PL/SQL New Features

95 Benefits of Collections
Oracle collections: Include ANSI functionality in nested tables and VARRAYs Support type evolution Support VARRAY columns in temporary tables Store nested tables’ storage tables in a different tablespace Benefits of Collections Nested tables and VARRAYs are enhanced to include more ANSI functionality for these data types. Both are enhanced to support type evolution to propagate changes or invalidate dependent objects. Temporary tables are enhanced to allow VARRAY columns. Nested tables are enhanced to enable the storage table to be stored in a different tablespace. The ANSI/ISO specification has a number of operations for multisets and arrays, including predicates, operators returning collections, aggregation functions, and operators returning elements of the collection and cardinality. In Oracle Database 10g, several ANSI operators and predicates are supported, including CARDINALITY, IS A SET, IS EMPTY, MULTISET UNION, MULTISET INTERSECT, MULTISET EXCEPT, EQUALITY, !=, IN. You can refer to the ANSI SQL guide on MULTISETs for the detailed definition of the operators and predicates named above. In earlier releases, you could use a nested table with limited accessor and mutator functionality. Although this functionality is sufficient for many applications, the ANSI multiset data type is far richer and offers performance improvements and greater functionality. Oracle Database 10g: SQL and PL/SQL New Features

96 Oracle Database 10g: SQL and PL/SQL New Features 1 - 97
Lesson Agenda Introducing collection enhancements VARRAY and nested table enhancements Adjusting the size Using VARRAYs in temporary tables Changing the tablespace storage Using the ANSI support on nested table collections Using the multiset operators Oracle Database 10g: SQL and PL/SQL New Features

97 Adjusting the Size of an Element Type
Changing the size of an element type: Applies to nested tables and VARRAYs Can occur if the element type is: Variable character RAW Numeric Can use a CASCADE option to propagate the change of the collection type and table dependents Can use an INVALIDATE option to invalidate all dependent objects Increasing the Size or Precision of a Collection’s Element Type When a VARRAY or a nested table’s element type is of a variable character, a RAW, or a numeric type, you can increase the size. The INVALIDATE option enables you to invalidate all dependent objects. The CASCADE option enables you to propagate the change of the collection type to its dependents. For example, you have the following VARRAY type defined in the OE sample schema: DESCRIBE phone_list_typ phone_list_typ VARRAY(5) OF VARCHAR2(25) To increase the variable character length limit and propagate the change to its dependents, use: ALTER TYPE phone_list_typ MODIFY ELEMENT TYPE VARCHAR2(64) CASCADE; Type altered. Oracle Database 10g: SQL and PL/SQL New Features

98 Using the VARRAY LIMIT Size
You can increase the number of elements of VARRAY type: ALTER TYPE orderitemlist_vartyp MODIFY LIMIT 1000 INVALIDATE; Type altered. DESCRIBE orderitemlist_vartyp orderitemlist_vartyp VARRAY(1000) OF ORDERITEM_TYP Name Null? Type LINE_ITEM_ID NUMBER QUANTITY NUMBER UNIT_PRICE NUMBER PRODUCT_ID NUMBER SUBTOTAL NUMBER Using the LIMIT Option The enhanced syntax in Oracle Database 10g enables you to increase the number of elements in a VARRAY type. You can use the INVALIDATE and CASCADE options. Examine the following type definitions: CREATE OR REPLACE TYPE orderitem_typ AS OBJECT ( line_item_id NUMBER, quantity NUMBER, unit_price NUMBER, product_id NUMBER, subtotal NUMBER); / Type created. CREATE OR REPLACE TYPE orderitemlist_vartyp AS VARRAY (20) OF orderitem_typ; To increase the number of elements and invalidate all dependent objects on orderitemlist_vartyp, use: ALTER TYPE orderitemlist_vartyp MODIFY LIMIT 1000 INVALIDATE; Type altered. Oracle Database 10g: SQL and PL/SQL New Features

99 Using VARRAY Columns in Temporary Tables
Temporary tables can now contain columns of VARRAY type: CREATE GLOBAL TEMPORARY TABLE order_temp_tab (orderno NUMBER, items orderitemlist_vartyp) ON COMMIT PRESERVE ROWS; Table created. VARRAY Columns in Temporary Tables Oracle Database 10g supports VARRAY columns in temporary tables. Restriction If you use the VARRAY_store_as_lob clause, then TABLESPACE, storage_clause, and logging_clause cannot be used. Note: ON COMMIT PRESERVE ROWS makes the data in the table session specific. The other option is ON COMMIT DELETE ROWS, which is transaction specific, meaning all rows are deleted after each COMMIT operation. Oracle Database 10g: SQL and PL/SQL New Features

100 Changing a Nested Table’s Storage Tablespace
CREATE TYPE LineItem_objtyp AS OBJECT( LineItemNo NUMBER, Quantity NUMBER, Discount NUMBER); / Type created. CREATE TYPE LineItemList_ntabtyp AS TABLE OF LineItem_objtyp; CREATE TABLE order_tab( Orderno NUMBER, items LineItemList_ntabtyp) NESTED TABLE items STORE AS item_tab (TABLESPACE system); Table created. 1 Making Changes to the Tablespace of a Nested Table’s Storage Table When creating a table with a nested table column, the default behavior places the nested table’s storage table in the same tablespace as the parent table. You may want the nested table placed in a specific tablespace. You can identify a different tablespace for a nested table’s storage with the TABLESPACE clause in the CREATE TABLE statement and the ALTER TABLE MOVE statement. In the example shown: 1. A nested table is created with the tablespace identified as SYSTEM. 2. The tablespace for the nested table is moved to EXAMPLE with the ALTER statement. ALTER TABLE item_tab MOVE TABLESPACE example; Table altered. 2 Oracle Database 10g: SQL and PL/SQL New Features

101 Oracle Database 10g: SQL and PL/SQL New Features 1 - 102
Lesson Agenda Introducing collection enhancements VARRAY and nested table enhancements Adjusting the size Using VARRAYs in temporary tables Changing the tablespace storage Using the ANSI support on nested table collections Using the multiset operators Oracle Database 10g: SQL and PL/SQL New Features

102 ANSI Support for Nested Tables
Oracle Database 10g supports multiset value usage in the following: Predicates Operators returning nested tables and operators returning elements of the nested table Cardinality of a nested table Functions specifically added for the itemset counting project: POWERMULTISET POWERMULTISET_BY_CARDINALITY for nested tables (multisets) Equality and Inequality Predicates (= and <>) You can use the Oracle Database 10g enhancements to support the equality and inequality predicate on nested tables. The equal (=) and not equal (<>) operators can be used to compare nested tables to one another. A Boolean result is returned from the comparison. Nested tables are considered equal if they have: The same named type The same cardinality Elements that are equal To make nested table comparisons, the element type needs to be comparable. Oracle Database 10g: SQL and PL/SQL New Features

103 Using the Equality and Inequality Predicates (= and <>)
CREATE OR REPLACE TYPE billdate IS TABLE OF DATE; / DECLARE b1 BOOLEAN; notice billdate; payments billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06', '15-JAN-06'); b1 := notice = payments; IF b1 THEN dbms_output.put_line('They are equal.'); ELSE dbms_output.put_line('They are NOT equal.'); END IF; END; 1 Using the Equality and Inequality Predicates In the PL/SQL code shown in the slide, the two nested tables, NOTICE and BILLDATE, are compared (1) and the output shows that they are considered equal (2). You can use the same logic with SQL statements. In the code that follows, the NEW_ORDERS table is created and contains two nested tables of the same type. A row is inserted, then the NEW_ORDERS table is updated, and the two nested table columns are updated for order 2458. The values added into the two columns are considered equal because they match in number and element value. The SELECT statement shows that the two are equivalent. CREATE TABLE new_orders ( ord_id NUMBER, notice billdate , payments billdate) NESTED TABLE notice STORE AS notice_store_tab NESTED TABLE payments STORE AS payments_store_tab; Table created. INSERT INTO new_orders (ord_id) VALUES (2458); 1 row created. Type created. They are equal. PL/SQL procedure successfully completed. 2 Oracle Database 10g: SQL and PL/SQL New Features

104 Using Nested Tables and the IN Operator
DECLARE notice billdate; payments billdate; receipt billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06', '15-JAN-06'); receipt := billdate('15-MAR-06', '15-JAN-06', '15-FEB-06'); IF (receipt IN (notice, payments)) THEN dbms_output.put_line('It is in the list'); ELSE dbms_output.put_line('It was not found in the list'); END IF; END; / 1 Using Nested Tables and the IN Operator The IN operator determines whether a named nested table appears in a list of named nested tables. A Boolean value is returned. In the PL/SQL example shown in the graphic, the RECEIPT nested table is compared to the NOTICE and PAYMENTS nested tables with the IN operator (1). The results show (2) that the values in the RECEIPT column appear in at least one of the nested tables, either NOTICE or PAYMENTS (in this case, it is both). It is in the list PL/SQL procedure successfully completed. 2 Oracle Database 10g: SQL and PL/SQL New Features

105 Using Nested Tables and the IN Operator
ALTER TABLE new_orders ADD (receipt billdate) NESTED TABLE receipt STORE AS receipt_store_tab; Table altered. UPDATE new_orders SET receipt = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06') WHERE ord_id = 2458; 1 row updated. SELECT * FROM new_orders WHERE receipt IN (notice, payments); Using Nested Tables and the IN Operator (continued) In SQL, you can use the IN operator to determine whether a named nested table column appears in a list of named nested table columns. This example first alters the ORDERS table by adding a nested table column. The SELECT statement checks whether values in the RECEIPT column match values in the NOTICE and PAYMENTS columns. These are the results from the SELECT statement shown in the slide: ORD_ID NOTICE PAYMENTS RECEIPT 2458 BILLDATE('15-JAN-06', '15-FEB-06', '15-MAR-06') BILLDATE('15-FEB-06', '15-MAR-06', '15-JAN-06') Oracle Database 10g: SQL and PL/SQL New Features

106 Using the SUBMULTISET Operator
DECLARE notice billdate; payments billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06', '15-JAN-06'); IF payments SUBMULTISET OF notice THEN dbms_output.put_line('Payments is a subset of receipt.'); ELSE dbms_output.put_line('Payments are not a subset.'); END IF; END; / 1 Using the SUBMULTISET Operator You can use the SUBMULTISET operator to test whether a given nested table is a submultiset of another nested table. The operator returns a Boolean value and works on nested tables only. In the illustration in the slide, the NOTICE and PAYMENTS nested table variables are assigned values. The SUBMULTISET operator checks whether PAYMENTS is a subset of NOTICE (1). The OF keyword shown above is optional. The results show that the PAYMENTS nested table is a subset of the RECEIPT nested table (2). Payments is a subset of receipt. PL/SQL procedure successfully completed. 2 Oracle Database 10g: SQL and PL/SQL New Features

107 Using the SUBMULTISET Operator
UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-JAN-06') WHERE ord_id = 2458; 1 row updated. SELECT ord_id, order_mode, customer_id, order_status FROM new_orders, orders WHERE orders.order_id = new_orders.ord_id AND payments SUBMULTISET OF notice; ORD_ID ORDER_MO CUSTOMER_ID ORDER_STATUS 2458 direct Using the SUBMULTISET Operator (continued) You can use the SUBMULTISET operator in SQL statements. In the statements shown in the slide, values are added to the NOTICE and PAYMENTS columns. The SUBMULTISET operator in the WHERE clause of the SELECT statement returns whether PAYMENTS is a subset of NOTICE. Oracle Database 10g: SQL and PL/SQL New Features

108 Oracle Database 10g: SQL and PL/SQL New Features 1 - 109
Lesson Agenda Introducing collection enhancements VARRAY and nested table enhancements Adjusting the size Using VARRAYs in temporary tables Changing the tablespace storage Using the ANSI support on nested table collections Using the multiset operators Oracle Database 10g: SQL and PL/SQL New Features

109 Introducing the Multiset Operators
MULTISET UNION, MULTISET INTERSECT, and MULTISET EXCEPT operators: Return a nested table whose values are those of two input nested tables Can be used only where the input and output tables are of the same type Accept the following options: The ALL option is the default, that is, all elements in the input table are part of the result. The DISTINCT option eliminates duplicates. Introducing the Multiset Operators The MULTISET UNION, MULTISET INTERSECT, and MULTISET EXCEPT operators that are used on multisets are equivalent to the mathematical notion of union, intersect, and except. You can use the MULTISET UNION operator to return a nested table whose values are those of the two input nested tables. The input and output nested tables must be of the same data type. You can use the MULTISET INTERSECT operator to return a nested table whose values are common in the two input nested tables. The input and output nested tables must be of the same data type. The MULTISET UNION and MULTISET INTERSECT operators are similar to the UNION and INTERSECT operators except that they work on nested tables. The MULTISET EXCEPT operator takes two nested tables as input and returns a nested table whose elements are in the first nested table, but not the second. The input and output nested tables must be of the same data type. For all three of these operators, you can use two options: ALL or DISTINCT. The default is ALL. With the ALL option, all elements that are in the input tables would be part of the result, including NULLs. With the DISTINCT option, duplicates are eliminated, including duplicate NULLs. Oracle Database 10g: SQL and PL/SQL New Features

110 Using the Multiset Operators
Example of MULTISET UNION and MULTISET INTERSECT in PL/SQL: DECLARE notice billdate; payments billdate; activity billdate; response billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06', '15-APR-06'); activity := notice MULTISET UNION DISTINCT payments; response := notice MULTISET INTERSECT payments; ... END; / Using the Multiset Operators (continued) You can use the MULTISET UNION and MULTISET INTERSECT operators in SQL and PL/SQL statements. In the PL/SQL code shown above, the ACTIVITY and RESPONSE nested tables are compared using the MULTISET UNION and MULTISET INTERSECT operators, respectively. To see the contents of the ACTIVITY and RESPONSE variables, you can add the following code before the END statement: ... FOR i IN activity.first..activity.last LOOP dbms_output.put_line(activity(i)); END LOOP; FOR i IN response.first..response.last LOOP dbms_output.put_line(response(i)); Oracle Database 10g: SQL and PL/SQL New Features

111 Using the Multiset Operators
UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-APR-06') WHERE ord_id = 2458; 1 row updated. SELECT notice MULTISET UNION payments FROM new_orders WHERE ord_id = 2458; NOTICEMULTISETUNIONPAYMENTS BILLDATE('15-JAN-06', '15-FEB-06', '15-MAR-06', '15-FEB-06', '15-MAR-06', '15-APR-06') SELECT notice MULTISET INTERSECT DISTINCT payments NOTICEMULTISETINTERSECTDISTINCTPAYMENTS BILLDATE('15-FEB-06', '15-MAR-06') Using the Multiset Operators (continued) Using the NEW_ORDERS table shown previously, the UPDATE statement shown in the slide modifies the values in the NOTICE and PAYMENTS nested table columns for the order The SELECT statements retrieve the union and the intersection of the two columns’ values. Oracle Database 10g: SQL and PL/SQL New Features

112 Using the MULTISET EXCEPT Operator
Use the MULTISET EXCEPT operator to return all the values from one nested table that are not found in a second nested table. DECLARE notice billdate; payments billdate; activity billdate; BEGIN ... notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06', '15-APR-06'); activity := notice MULTISET EXCEPT ALL payments; END; / Using the MULTISET EXCEPT Operator You use the MULTISET EXCEPT operator to return all the values from one nested table that are not found in a second nested table. In the PL/SQL code shown in the graphic, the ACTIVITY nested table is compared using the MULTISET EXCEPT ALL operator against the PAYMENTS nested table. Using the NEW_ORDERS table shown previously, the SQL syntax is: UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-JAN-06') WHERE ord_id = 2458; 1 row updated. SELECT notice MULTISET EXCEPT ALL payments FROM new_orders Oracle Database 10g: SQL and PL/SQL New Features

113 Using the CARDINALITY Operator
DECLARE notice billdate; payments billdate; num_notice NUMBER; num_payments NUMBER; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06'); num_notice := CARDINALITY(notice); num_payments := CARDINALITY(payments); DBMS_OUTPUT.PUT_LINE('Number of notices: '|| num_notice); DBMS_OUTPUT.PUT_LINE('Number of payments: '|| num_payments); END; / Using the CARDINALITY Operator You can use the CARDINALITY operator to return the number of elements in a nested table. The return value is a number. The example shown in the slide retrieves the number of elements in the NOTICE and PAYMENTS nested table variables. Using the NEW_ORDERS table shown, where the NOTICE column is a nested table, you can determine the number of times an order has had a notice sent: SELECT count(ord_id) FROM new_orders WHERE CARDINALITY(notice) > 1; COUNT(ORD_ID) 1 Number of notices: 3 Number of payments 2 PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

114 Using the MEMBER OF Operator
DECLARE notice billdate; payments billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); payments := billdate('15-FEB-06', '15-MAR-06'); IF '15-FEB-06' MEMBER OF notice THEN DBMS_OUTPUT.PUT_LINE('Notice sent on 15-Feb-2006.'); END IF; IF '15-JAN-06' NOT MEMBER OF payments THEN DBMS_OUTPUT.PUT_LINE('No payment in January.'); END; / 1 2 Using the MEMBER OF Operator You can use the MEMBER OF operator to test whether an element is a member of a nested table. It returns a Boolean value. The OF keyword is optional. In the PL/SQL code shown in the slide, the value '15-FEB-06' is checked against the values in the NOTICE nested table (1). The NOTICE nested table holds a value of '15-FEB-06'. The output shows this is true (3). The value '15-JAN-06' is checked against the values of the PAYMENTS nested table (2). The output shows that it is not a value of PAYMENTS (3). Using the NEW_ORDERS table shown previously, you can determine whether the element '15-FEB-06' is a member of the NOTICE nested table column in the NEW_ORDERS table: UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-JAN-06') WHERE ord_id = 2458; 1 row updated. SELECT * FROM new_orders WHERE '15-FEB-06' MEMBER OF notice; Notice sent on 15-Feb-2006. No payment in January. PL/SQL procedure successfully completed. 3 Oracle Database 10g: SQL and PL/SQL New Features

115 Oracle Database 10g: SQL and PL/SQL New Features 1 - 116
Using the SET Operator PL/SQL: SQL: DECLARE notice billdate; back_notice billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06', '15-JAN-06'); IF sysdate > '15-APR-06' THEN back_notice := SET(notice); END IF; END; / 1 SELECT SET(notice) FROM new_orders WHERE ord_id = 2458; SET(NOTICE) BILLDATE('15-JAN-06', '15-FEB-06', '15-MAR-06') 2 Using the SET Operator You use the SET operator to convert a nested table into a set and return a nested table with elements that are distinct from one another. The returned nested table is of the same data type as the input nested table. In the first example, the BACK_NOTICE variable will hold the results: 15-JAN-06 15-FEB-06 15-MAR-06 In the second example, the NOTICE column did not have any duplicate values; however, if duplicates were present, the results would only show the distinct values. Oracle Database 10g: SQL and PL/SQL New Features

116 Using the IS A SET Operator
DECLARE notice billdate; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-JAN-06'); IF notice IS A SET THEN DBMS_OUTPUT.PUT_LINE('Values are unique.'); ELSE DBMS_OUTPUT.PUT_LINE('Duplicates exist.'); END IF; END; / Duplicates exist. PL/SQL procedure successfully completed. Using the IS A SET Operator You can use the IS A SET operator to determine whether a nested table is made up of distinct elements. A Boolean value of TRUE is returned if the values are distinct. The IS NOT A SET operator also determines whether a nested table is made up of distinct elements. A Boolean value of TRUE is returned if the values are not distinct. Using the NEW_ORDERS table shown previously, the UPDATE statement adds some elements to the NOTICE and PAYMENTS nested table columns. To find whether the NOTICE nested table column contains distinct values, execute the following SELECT statement: UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-JAN-06') WHERE ord_id = 2458; 1 row updated. SELECT * FROM new_orders WHERE notice IS A SET; Oracle Database 10g: SQL and PL/SQL New Features

117 Using the IS EMPTY Operator
DECLARE notice billdate; v_empty BOOLEAN; BEGIN notice := billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'); v_empty := notice IS EMPTY; IF v_empty THEN DBMS_OUTPUT.PUT_LINE('The nested table is empty.'); ELSE DBMS_OUTPUT.PUT_LINE('The nested table is not empty '); END IF; END; / Using the IS EMPTY Operator Use the IS EMPTY operator to determine whether a nested table is empty. A Boolean value is returned. In the PL/SQL code shown above, the IS EMPTY operator checks whether the NOTICE nested table is empty. The Boolean value returned from the IS EMPTY operator is stored in the V_EMPTY variable. The output shows that the IS EMPTY operator returned false, indicating that the NOTICE table is not empty. The nested table is not empty. PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

118 Using the IS NOT EMPTY Operator
UPDATE new_orders SET notice = billdate('15-JAN-06', '15-FEB-06', '15-MAR-06'), payments = billdate('15-FEB-06', '15-MAR-06', '15-JAN-06') WHERE ord_id = 2458; 1 row updated. SELECT * FROM new_orders WHERE notice IS NOT EMPTY; NOTICE PAYMENTS RECEIPT 2458 BILLDATE('15-JAN-06', '15-FEB-06', '15-MAR-06') BILLDATE('15-FEB-06', '15-MAR-06', '15-JAN-06') Using the IS NOT EMPTY Operator The IS NOT EMPTY operator checks whether a given nested table is empty or not empty, regardless of whether any of the elements are NULL. If a NULL is given for the nested table, the result is NULL. The result is returned as a Boolean value. Using the NEW_ORDERS table shown previously, you can execute the SELECT statement shown in the slide to determine whether the NOTICE nested table column contains values. Oracle Database 10g: SQL and PL/SQL New Features

119 Using the COLLECT Operator
Use the COLLECT operator to collect the rows into a collection: ALTER TABLE new_orders ADD created date; UPDATE new_orders SET created = sysdate WHERE ord_id = 2458; SELECT CAST(COLLECT(created) AS billdate ) FROM new_orders; CAST(COLLECT(CREATED)ASBILLDATE) BILLDATE('18-JUL-06') Using the COLLECT Operator You can use the COLLECT operator on nested tables. It is part of the ANSI SQL standards. COLLECT is an aggregation function that creates a nested table from a set of elements. It takes a column of the element type as input and creates a nested table from the rows selected. You need to use the CAST operator to specify the output type of COLLECT. In the example shown, a new column is added to the NEW_ORDERS table of DATE type. The new column has a value updated into it. The COLLECT operator in the SELECT statement takes the CREATED column of the DATE data type and creates a nested table of type BILLDATE in the output. This operator is available in SQL. Oracle Database 10g: SQL and PL/SQL New Features

120 Using the POWERMULTISET Operator
Use the POWERMULTISET operator to create every possible subset of a particular multiset: SELECT * FROM TABLE (POWERMULTISET(BILLDATE ('01-JAN-06', '01-FEB-06', '01-MAR-06'))); COLUMN_VALUE BILLDATE('01-JAN-06') BILLDATE('01-FEB-06') BILLDATE('01-JAN-06', '01-FEB-06') BILLDATE('01-MAR-06') BILLDATE('01-JAN-06', '01-MAR-06') BILLDATE('01-FEB-06', '01-MAR-06') BILLDATE('01-JAN-06', '01-FEB-06', '01-MAR-06') 7 rows selected. Using the POWERMULTISET Operator The POWERMULTISET operator is used on nested tables to generate a nonempty subnested table from a nested table. It outputs rows of nested table values on the basis of the input nested table values. The input value cannot be NULL; otherwise, an error is generated. This operator is available in SQL. Oracle Database 10g: SQL and PL/SQL New Features

121 Using the POWERMULTISET_BY_CARDINALITY Operator
You can restrict the results of POWERMULTISET to a certain number of elements with the POWERMULTISET_BY_CARDINALITY operator. SELECT * FROM TABLE (POWERMULTISET_BY_CARDINALITY(BILLDATE ('01-JAN-06', '02-JAN-06', '03-JAN-06'),2 )); COLUMN_VALUE BILLDATE('01-JAN-06', '02-JAN-06') BILLDATE('01-JAN-06', '03-JAN-06') BILLDATE('02-JAN-06', '03-JAN-06') Using the POWERMULTISET_BY_CARDINALITY Operator This operator returns all nonempty subnested table values on the basis of a nested table and the specified cardinality. The output is rows of nested tables. The POWERMULTISET_BY_CARDINALITY operator accepts two parameters. The first parameter is an expression that evaluates to a nested table, and the second parameter is the length (or cardinality) value. The length parameter must be a positive integer. This operator is available in SQL. Note: COLLECT, POWERMULTISET, and POWERMULTISET_BY_CARDINALITY operators are not implemented in PL/SQL. Oracle Database 10g: SQL and PL/SQL New Features

122 Oracle Database 10g: SQL and PL/SQL New Features 1 - 123
Summary In this lesson, you should have learned how to: Change the size of a VARRAY Support VARRAY columns in temporary tables Use a different tablespace for a nested table’s storage table Describe nested table support for predicates, operators returning nested tables, and aggregation functions Use the multiset operators on collections Summary In this lesson, you learned how to change the size of a VARRAY, use VARRAYs in temporary tables, and change the tablespace for a nested table’s storage. A number of the multiset operators are supported for the nested table collection type. You learned about the predicates, operators, and multiset options on collections. Oracle Database 10g: SQL and PL/SQL New Features

123 Practice 4-1 Overview: Using the Enhancements for Collections
This practice covers the following topics: Defining a collection type Analyzing snippets of code used for an online book-ordering company Use the ANSI operators on collections Use the multiset operators on collections Practice 4-1 Overview: Using the Enhancements for Collections In this practice, you use and write code that uses the enhancements on nested tables and varrays. Using the scenario of an online book ordering company, you examine and write code based on available book titles, book orders, and shopping basket. Oracle Database 10g: SQL and PL/SQL New Features

124 Using General SQL Enhancements

125 Oracle Database 10g: SQL and PL/SQL New Features 1 - 126
Objectives After completing this lesson, you should be able to: Query row versions Perform FLASHBACK operations Describe extensibility enhancements on table functions Other SQL enhancements Alternative quotes Privileges and roles Drop and purge tables Bulk returning with single-set aggregates Objectives Oracle Database 10g provides enhancements to the table functions and versioning of rows, the flashback feature, and many other SQL enhancements. In this lesson, you learn about these new features. Oracle Database 10g: SQL and PL/SQL New Features

126 Oracle Database 10g: SQL and PL/SQL New Features 1 - 127
Lesson Agenda Querying row versions Using flashback Flashback query FLASHBACK TABLE FLASHBACK DATABASE Describing extensibility enhancements Reviewing other SQL enhancements Oracle Database 10g: SQL and PL/SQL New Features

127 Introducing the VERSIONS Clause
Versions of retrieved rows SELECT FROM Use it in the FROM clause of a SELECT statement. It produces all versions of all rows that exist or existed between the time of the query and the UNDO_RETENTION seconds. Introducing the VERSIONS Clause You can use Oracle Database 10g to specify a new clause called VERSIONS in the FROM clause of the SELECT statement of SQL queries. You can use a query on a table with a VERSIONS clause to produce all the versions of all the rows that exist or ever existed between the time the query was executed and the undo_retention seconds before the current time. undo_retention is an initialization parameter, which is an autotuned parameter. A query that includes a VERSIONS clause is referred to as a version query. The results of a version query behave as if the WHERE clause were applied to the versions of the rows. The version query returns versions of the rows only across transactions. The VERSIONS clause does not change the plan of the query. For example, if you run a query on a table that uses the index access method, then the same query on the same table with a VERSIONS clause still uses the index access method. The versions of the rows returned by the version query are versions of the rows across transactions. The VERSIONS clause has no effect on the transactional behavior of a query. This means that a query on a table with a VERSIONS clause still inherits the query environment of the ongoing transaction. System Change Number (SCN) An SCN is a stamp that defines a committed version of a database at a point in time. Every committed transaction is assigned a unique SCN. The VERSIONS clause uses SCNs. Oracle Database 10g: SQL and PL/SQL New Features

128 Retrieving Row Versions
SELECT salary FROM employees WHERE employee_id = 107; SALARY 4200 1 UPDATE employees SET salary = salary * 1.30 WHERE employee_id = 107; COMMIT; 2 SELECT salary FROM employees VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE WHERE employee_id = 107; SALARY 5460 4200 3 Retrieving Row Versions You can use the VERSIONS clause to retrieve the different versions of specific rows that existed during a given time interval. A new row version is created whenever a COMMIT occurs. In the example in the slide, the salary for employee 107 is retrieved (1). The salary for employee 107 is increased by 10 percent and this change is committed (2). The different versions of salary are displayed (3). The default VERSIONS clause can be specified as: VERSIONS BETWEEN {SCN|TIMESTAMP} MINVALUE AND MAXVALUE The VERSIONS clause is a SQL extension only for queries. You can have data manipulation language (DML) and data definition language (DDL) operations that use a VERSIONS clause within subqueries. The row-version query retrieves all the committed versions of the selected rows. Changes made by the current active transaction are not returned. The version query retrieves all incarnations of the rows. This essentially means that versions returned include delete and subsequent reinsert versions of the rows. The row access for a version query can be defined in one of the following two categories: ROWID-based row access: In case of ROWID-based access, all versions of the specified ROWID are returned irrespective of the row content. This essentially means that all versions of the slot in the block indicated by the ROWID are returned. All other row access: For all other accesses, all versions of the rows are returned. Oracle Database 10g: SQL and PL/SQL New Features

129 Supporting Pseudocolumns and Functions
Description VERSIONS_STARTSCN SCN at which this version of the row was created VERSIONS_STARTTIME TIMESTAMP at which this version of the row was created VERSIONS_ENDSCN SCN at which this version of the row expired VERSIONS_ENDTIME TIMESTAMP at which this version of the row expired VERSIONS_XID ID of the transaction that created this version of the row VERSIONS_OPERATION Operation done by this transaction ORA_ROWSCN Row SCN of the retrieved row Conversion Functions Description SCN_TO_TIMESTAMP Converts SCN(number) to TIMESTAMP TIMESTAMP_TO_SCN Converts TIMESTAMP to SCN(number) Pseudocolumns The VERSIONS query returns versions of the rows along with the validity range (such as the start and the end time) of the version, the transaction that created this version, and the operation that produced this version. The validity range is closed at the lower bound and open at the upper bound. This means that a given version is valid for all time t, where VERSIONS_STARTTIME <= t < VERSIONS_ENDTIME. This information is returned as values of the pseudocolumns. These pseudocolumns can be specified as part of the WHERE clause to retrieve the specified versions of the rows. This selection of the versions of the rows essentially enables the users to sample events based on visible versions of the database. Functions The conversion functions have been added to support the versions functionality. You can convert between the time stamp and the SCN value. Either of these can be used with the VERSIONS clause. Oracle Database 10g: SQL and PL/SQL New Features

130 Using ORA_ROWSCN to Find SCNs
Is used to retrieve the SCN of the selected rows Can be used for any SQL query statement on a table SELECT ora_rowscn "ROW_SCN", employee_id, last_name FROM employees; ROW_SCN EMPLOYEE_ID LAST_NAME King Kochhar De Haan ... Walsh Feeney 107 rows selected. Using ORA_ROWSCN to Find SCNs You can use the new pseudocolumn ORA_ROWSCN to retrieve SCN of the selected rows. This pseudocolumn can be used for any SQL query statement on a table. You cannot select this pseudocolumn from a view. However, a view definition can use the pseudocolumn for underlying tables. You can also use the ORA_ROWSCN pseudocolumn as part of the predicate for UPDATE and DELETE statements. This pseudocolumn is not supported for fixed tables or external tables. Oracle Database 10g: SQL and PL/SQL New Features

131 Using the Row Versions Feature
The departments in which employee Kochhar worked: The names of past presidents of the company: SELECT a.versions_starttime"START_DATE", a.versions_endtime "END_DATE", b.department_name "DEPT_NAME" FROM employees VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP(' ', 'YYYY-MM-DD') AND TO_TIMESTAMP(' ', 'YYYY-MM-DD') a, departments b WHERE a.department_id = b.department_id AND a.last_name = 'Kochhar'; 1 SELECT last_name FROM employees VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE WHERE job_id='AD_PRES'; Using the Row Versions Feature The first query finds the departments where Kochhar worked for one year. The second example finds the names of past presidents of the company. Applications for Row Versions By using a version query, you can obtain a direct interface to get multiple versions of the rows. It also provides for a way to audit the rows of a table and get information about the transactions that changed the rows and also times when it was changed. Using the transaction ID, you can do transaction mining through Logminer or undo transaction-mining capabilities to get complete information about the transaction. 2 Oracle Database 10g: SQL and PL/SQL New Features

132 Using the SCN_TO_TIMESTAMP and TIMESTAMP_TO_SCN Functions
DECLARE right_now TIMESTAMP; yesterday TIMESTAMP; sometime TIMESTAMP; scn1 INTEGER; scn2 INTEGER; scn3 INTEGER; BEGIN right_now := SYSTIMESTAMP; -- Get the current timestamp scn1 := TIMESTAMP_TO_SCN(right_now); DBMS_OUTPUT.PUT_LINE('Current SCN is ' || scn1); yesterday := right_now - 1; -- Get the SCN from exactly 1 day ago scn2 := TIMESTAMP_TO_SCN(yesterday); DBMS_OUTPUT.PUT_LINE('SCN from yesterday is ' || scn2); -- Find an arbitrary SCN somewhere between yesterday and today -- In a real program store the SCN at some significant moment scn3 := (scn1 + scn2) / 2; sometime := SCN_TO_TIMESTAMP(scn3);--What time was that SCN in effect? DBMS_OUTPUT.PUT_LINE('SCN ' || scn3 || ' was in effect at ' || TO_CHAR(sometime)); END; Using the Conversion Functions with SCNs You can use the functions to convert SCNs to and from TIMESTAMP data types. Executing the program shown in the slide results in: Current SCN is SCN from yesterday is SCN was in effect at 13-JUL PM PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

133 Oracle Database 10g: SQL and PL/SQL New Features 1 - 134
Lesson Agenda Querying row versions Using flashback Flashback query FLASHBACK TABLE FLASHBACK DATABASE Describing extensibility enhancements Reviewing other SQL enhancements Oracle Database 10g: SQL and PL/SQL New Features

134 Introducing Flashback Features
Flashback query: To retrieve data for a time in the past FLASHBACK TABLE: To recover a table to a state in a previous point of time FLASHBACK DATABASE: To return the database to an earlier point in time FLASHBACK Features The flashback features provide you with ways to view past states of database objects or to return database objects to a previous state without using point-in-time media recovery. You can use flashback features of the database to do the following: Perform queries that return past data. Recover tables or rows to a previous point in time. Return the database to an earlier point in time. Oracle Database 10g: SQL and PL/SQL New Features

135 Oracle Database 10g: SQL and PL/SQL New Features 1 - 136
Using Flashback Query DELETE FROM copy_emp WHERE last_name = 'Greenberg'; 1 row deleted. COMMIT; Commit complete. SELECT last_name, employee_id, salary, manager_id FROM copy_emp AS OF TIMESTAMP TO_TIMESTAMP(' :24:07 PM', 'YYYY-MM-DD HH:MI:SS PM') WHERE last_name = 'Greenberg'; LAST_NAME EMPLOYEE_ID SALARY MANAGER_ID Greenberg INSERT INTO copy_emp (SELECT * FROM copy_emp AS OF TIMESTAMP WHERE last_name = 'Greenberg'); 1 row created. 1 Retrieving a Row with Flashback Query Suppose that you accidentally deleted a row and committed the change. You can use flashback query to retrieve the row. In the example shown in the slide, employee Greenberg is deleted and the change is committed. The approximate time of the change is “08-AUG PM -04:00.” The information about the time was retrieved by issuing this SELECT statement: SELECT systimestamp FROM dual; To reverse the change, first, the row is found before the time the row was deleted. The SELECT statement in the slide (labeled “1”) displays this information. An INSERT is performed based on the row information before the DELETE and COMMIT actions. The INSERT statement in the slide (labeled “2”) displays this information. Note: In the example shown in the slide, a copy of the EMPLOYEES table was created. It is called COPY_EMP. CREATE TABLE copy_emp AS SELECT * FROM employees; 2 Oracle Database 10g: SQL and PL/SQL New Features

136 Introducing the FLASHBACK TABLE Statement
Enables you to recover tables to a specified point in time with a single statement Restores table data along with associated indexes, triggers, and constraints Enables you to revert the table and its contents to a certain point in time or SCN Introducing the FLASHBACK TABLE Statement Oracle Flashback Table enables you to recover tables to a specified point in time with a single statement. You can restore table data along with associated indexes, triggers, and constraints, while the database is online, undoing changes to only the specified tables. The Flashback Table feature is similar to a self-service repair tool. For example, if a user accidentally deleted important rows from a table and then wanted to recover the deleted rows, you can use the FLASHBACK TABLE statement to restore the table to the time before the deletion and see the missing rows in the table. When using the FLASHBACK TABLE statement, you can revert the table and its contents to a certain time or to an SCN. Use Flashback Table with Oracle Flashback Version query and Flashback Transaction Query to find a time to which the table should be restored. SCN Oracle Database 10g: SQL and PL/SQL New Features

137 Benefits of the FLASHBACK TABLE Statement
Alternative for point-in-time database recovery Repair tool for accidental table modifications Restores a table to an earlier point in time Benefits: Ease of use, availability, fast execution Performed in place Fast, reliable, ease of use Works while the database is online FLASHBACK TABLE Benefits Self-Service Repair Facility Oracle Database 10g provides a new SQL DDL command, FLASHBACK TABLE, to restore the state of a table to an earlier point in time in case it is inadvertently deleted or modified. The FLASHBACK TABLE command is a self-service repair tool to restore data in a table along with associated attributes such as indexes or views. This is done while the database is online by rolling back only the subsequent changes to the given table. Compared to traditional recovery mechanisms, this feature offers significant benefits such as ease of use, availability, and faster restoration. It also takes the burden off the DBA to find and restore application-specific properties. The Flashback Table feature does not address physical corruption caused because of a bad disk. Oracle Database 10g: SQL and PL/SQL New Features

138 Steps for Enabling FLASHBACK TABLE Statement
Configure the recovery area: Specify sufficient disk quota. Set the initialization parameters UNDO_MANAGEMENT and UNDO_RETENTION. Turn on database flashback mode. Set DB_FLASHBACK_RETENTION_TARGET. Issue the FLASHBACK TABLE statement. UNDO_MANAGEMENT = AUTO UNDO_RETENTION = 900 –- in seconds ALTER DATABASE FLASHBACK ON; Configuration Considerations Follow these steps to enable the Flashback Table feature: 1. Configure the recovery area and specify sufficient disk quota. In automatic undo management mode, undo space is managed in undo tablespaces. To use automatic undo management mode, the database administrator needs to only create an undo tablespace for each instance and set the UNDO_MANAGEMENT initialization parameter to AUTO. Oracle Database 10g automatically tunes a parameter called the undo retention period. By default, it is set to 900. Both of these parameters can be set either in the initialization parameter file or with the ALTER SYSTEM statement. 2. Enable the flashback database mode. You can use ALTER DATABASE FLASHBACK ON; to accomplish this. Turning on flashback mode starts the recovery writer background process. This new background process writes flashback data to flashback database logs. 3. Set your retention target (expressed in minutes). The amount of flashback data in the recovery area directly controls how far back you can flash back the database. For example, if you want to keep flashback data for one day, set the DB_FLASHBACK_RETENTION_TARGET parameter in the initialization parameter file to 1440. 4. Issue the FLASHBACK TABLE statement when needed. DB_FLASHBACK_RETENTION_TARGET = 1440 Oracle Database 10g: SQL and PL/SQL New Features

139 Using the FLASHBACK TABLE Statement
FLASHBACK TABLE[schema.]table[, [ schema.]table ]... TO { TIMESTAMP | SCN } expr [ { ENABLE | DISABLE } TRIGGERS ]; DROP TABLE copy_emp; Table dropped SELECT original_name, operation, droptime FROM recyclebin; ORIGINAL_NAME OPERATION DROPTIME COPY_EMP DROP :14:46:10 FLASHBACK TABLE copy_emp TO BEFORE DROP; Flashback complete Syntax and Example The example restores the COPY_EMP table to a state before a DROP statement. The recycle bin is actually a data dictionary table containing information about dropped objects. Dropped tables and any associated objects (such as indexes, constraints, nested tables, and so on) are not removed and still occupy space. They continue to count against user space quotas, until specifically purged from the recycle bin or the unlikely situation where they must be purged by the database because of tablespace space constraints. Each user can be thought of as an owner of a recycle bin because unless a user has the SYSDBA privilege, the only objects that the user has access to in the recycle bin are those that the user owns. A user can view his or her objects in the recycle bin using the following statement: SELECT * FROM RECYCLEBIN; When you drop a user, any objects belonging to that user are not placed in the recycle bin and any objects in the recycle bin are purged. You can purge the recycle bin with the following statement: PURGE RECYCLEBIN; Oracle Database 10g: SQL and PL/SQL New Features

140 Introducing the FLASHBACK DATABASE Statement
Alternative for point-in-time database recovery Benefits: Fast, reliable, ease of use Syntax: Examples: FLASHBACK [STANDBY] DATABASE [database] TO { TIMESTAMP | SCN } expr; FLASHBACK DATABASE TO SCN 53214; FLASHBACK DATABASE TO TIMESTAMP (sysdate – 1/24); (' :00:00’); The FLASHBACK DATABASE Statement You can use the FLASHBACK DATABASE statement to return the database to a past time or system change number (SCN). This statement provides a fast alternative to performing incomplete database recovery. The Flashback Database feature uses a new concept called flashback database logs. Flashback database logs primarily contain data block images for blocks changed by the database. Oracle Database 10g automatically creates, deletes, and manages flashback database logs inside the recovery area (a directory or an OSM disk group set aside for recovery). During a flashback database operation, these data block images are used to quickly reverse changes to the database. Syntax and Examples You can execute the Flashback Database operation for a primary as well as a standby database. You specify the point in time to which you want to revert by providing a valid time stamp or a valid system change number (SCN). The first example restores the database using a SCN. The second and third examples use a time stamp. Oracle Database 10g: SQL and PL/SQL New Features

141 Oracle Database 10g: SQL and PL/SQL New Features 1 - 142
Lesson Agenda Querying row versions Using flashback Flashback query FLASHBACK TABLE FLASHBACK DATABASE Describing extensibility enhancements Reviewing other SQL enhancements Oracle Database 10g: SQL and PL/SQL New Features

142 Overview of Table Functions
Produce a collection of rows as either a nested table or a varray Often used in data warehousing during data transformations Pipelined transformation: T1 T2 T3 T1 OLTP Data Warehouse Overview of Table Functions You use table functions to produce a collection of rows (either a nested table or a varray) that can be queried like a regular database table. Table functions are used in the FROM clause of a query, where you place the name of the table function. Table functions are often used in a decision support system (DSS) scenario where several transformations of the data are needed before being loaded into the database. The table functions are used to produce the rows and the resulting collections are staged before undergoing another transformation, if needed. A table function can take a collection of rows as input, either as a collection type or a REF CURSOR. Execution of a table function can be parallelized, and returned rows can be streamed directly to the next process without intermediate staging. Rows from a collection returned by a table function can also be pipelined—that is, iteratively returned as they are produced instead of in a batch after all processing of the table function’s input is completed. Pipelining enables a table function to return rows faster and can reduce the memory required to cache a table function’s results. T1 T=transformation Oracle Database 10g: SQL and PL/SQL New Features

143 Overview of Table Functions
Pipelined table functions can be implemented in two ways: Native PL/SQL approach Simpler Uses native PL/SQL mechanism Cannot be used for table functions written in C or Java Interface approach Can be used for table functions written in C or Java Requires you to implement a set of well-defined interfaces in a procedural language New to Oracle 10g: Uses enhanced Oracle Data Cartridge Interface (ODCI) methods Basic Example of the PL/SQL Approach You declare a pipelined table function by specifying the PIPELINED keyword. CREATE PACKAGE pkg1 AS TYPE numset_t IS TABLE OF NUMBER; FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED; END pkg1; / CREATE PACKAGE BODY pkg1 AS -- FUNCTION f1 returns a collection of elements (1,2,3,... x) FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS BEGIN FOR i IN 1..x LOOP PIPE ROW(i); END LOOP; RETURN; END; -- pipelined function is used in a SELECT statement SELECT * FROM TABLE(pkg1.f1(5)); Oracle Database 10g: SQL and PL/SQL New Features

144 Processing for the Interface Approach Using ODCI
ODCITableStart ODCITableFetch Is result null? Yes No Process result Processing for the Interface Approach Using ODCI When using the interface approach, you need to define an implementation type that implements the ODCITable interface. This interface consists of start, fetch, and close routines whose signatures are specified by the Oracle server and which you implement as methods of the type. The Oracle server invokes the methods to perform the following steps in the execution of a query containing a table function: 1. Start: Initialize the scan context parameter. This is then used during the second phase. 2. Fetch: Produce a subset of the rows in the result collection. This routine is invoked as many times as necessary to return the entire collection. 3. Close: Clean up (for example, release memory) after the last fetch. For more information, refer to the Oracle® Database Data Cartridge Developer’s Guide. ODCITableClose Oracle Database 10g: SQL and PL/SQL New Features

145 Understanding the Enhanced ODCI Functions
These are the Oracle Database 10g enhancements: ODCITablePrepare is the new optional compile time callout. The ODCITable interface is extended. ODCITableStart is the first routine invoked to begin retrieving rows from a table function. AnyDataSet is enhanced to return a transient anonymous type. Enhanced ODCI Functions ODCITableStart is used as the first routine to begin retrieving rows from a table function. You use this routine to perform the setup needed for the scan, create the scan context (as an object instance sctx) and return it to the Oracle server. In earlier releases, a table function that returned a collection of User Defined Types (UDTs) had to set every attribute of the UDT of each element before returning it to the Oracle server. Even the attributes not referenced in the query were set, because the table function did not know which attributes were referenced. This is different than the case of selecting from a regular table, which only fetches the required columns and not every column in the table. In many cases, UDTs have many attributes, but only a few of them are actually referenced. In Oracle Database 10g, the ODCITable interface is extended to communicate to the table function the list of referenced attributes. This is done by building and passing an array of attribute positions to the table function’s ODCITableStart callout. Oracle Database 10g: SQL and PL/SQL New Features

146 Oracle Database 10g: SQL and PL/SQL New Features 1 - 147
ODCI (Java) Example CREATE TYPE StockPivotImpl AS OBJECT ( key INTEGER, STATIC FUNCTION ODCITableStart(sctx OUT StockPivotImpl, cur SYS_REFCURSOR) RETURN NUMBER AS LANGUAGE JAVA NAME 'StockPivotImpl.ODCITableStart(oracle.sql.STRUCT[], java.sql.ResultSet) return java.math.BigDecimal', MEMBER FUNCTION ODCITableFetch(self IN OUT StockPivotImpl, nrows IN NUMBER, outSet OUT TickerTypeSet) NAME 'StockPivotImpl.ODCITableFetch(java.math.BigDecimal, oracle.sql.ARRAY[]) return java.math.BigDecimal', MEMBER FUNCTION ODCITableClose(self IN StockPivotImpl) AS LANGUAGE JAVA NAME 'StockPivotImpl.ODCITableClose() return java.math.BigDecimal' ); / ODCI (Java) Example The code in the slide shows the declaration of the implementation type that references the Java methods. You need the following structures created to execute the code shown in the graphic. CREATE OR REPLACE DIRECTORY JavaDir AS 'E:\Java'; CREATE AND COMPILE JAVA SOURCE NAMED source01 USING BFILE (JavaDir,'StockPivotImpl.java'); Note: The body for the code shown is quite long and beyond the scope of this class. For a full declaration, refer to the Oracle® Database Data Cartridge Developer’s Guide. Oracle Database 10g: SQL and PL/SQL New Features

147 Oracle Database 10g: SQL and PL/SQL New Features 1 - 148
Lesson Agenda Querying row versions Using flashback Flashback query FLASHBACK TABLE FLASHBACK DATABASE Describing extensibility enhancements Reviewing other SQL enhancements Oracle Database 10g: SQL and PL/SQL New Features

148 Oracle Database 10g: SQL and PL/SQL New Features 1 - 149
More SQL Enhancements Alternative quotes Drop and purge tables Bulk returning with single-set aggregates Oracle Database 10g: SQL and PL/SQL New Features

149 Using Alternative Quotes
The q quote operator eliminates the need to use escape characters for single quotation marks in text literals. Available in SQL and PL/SQL Supports CHAR and NCHAR literals Valid values are: Any single or multibyte character Paired [ ], { }, ( ), and < > SELECT cust_address FROM customers WHERE cust_last_name = q'X 'John's Bait Shop' X'; Using the Alternative Quote Operator Many SQL statements use character literals in expressions or conditions. If the literal itself contains a single quotation mark, you need to use two single quotation marks as in ‘Pat’’s motorcycle.’ In this example, the opening and closing single quotation mark indicate the start and the end of the character literal. The quotation mark inside the character literal, is preceded by a single quotation mark that acts as an escape character. Having to use additional quotation marks inside a character literal is both cumbersome and error prone. As an alternative, you can use the quote operator, q. The new quote operator enables you to choose your own quotation mark delimiter and supports both CHAR and NCHAR literals. You can choose any convenient delimiter, single or multibyte, or any of the [ ], { }, ( ), < > character pairs. The delimiter can even be a single quotation mark. However, if the delimiter appears in the text literal itself, ensure that it is not immediately followed by a single quotation mark. In the first example in the slide, X is used as the quotation mark delimiter. You do not need to prefix the single quotation mark inside ‘John’s Bait Shop’ with another single quotation mark. The second example above shows that you can use the new quote operator in PL/SQL. The example uses the paired [ ] as the delimiter. Therefore, you do not need to use two single quotation marks inside the character string used to initialize the v_string1 variable. This makes it much more readable. ... v_string1 := q'['So,' she said, 'It's finished.']'; v_string2 := q'!name LIKE '%DBMS_%'!'; Oracle Database 10g: SQL and PL/SQL New Features

150 Oracle Database 10g: SQL and PL/SQL New Features 1 - 151
DROP TABLE … PURGE DROP TABLE copy_emp PURGE; DROP TABLE ... PURGE When you drop a table, the database does not immediately release the space associated with the table. Rather, the database renames the table and places it in a recycle bin, where it can later be recovered with the FLASHBACK TABLE statement if you find that you dropped the table in error. If you want to immediately release the space associated with the table at the time you issue the DROP TABLE statement, then include the PURGE clause as shown in the statement in the slide. Specify PURGE only if you want to drop the table and release the space associated with it in a single step. If you specify PURGE, then the database does not place the table and its dependent objects into the recycle bin. Using this clause is equivalent to first dropping the table and then purging it from the recycle bin. This clause saves you one step in the process. It also provides enhanced security if you want to prevent sensitive material from appearing in the recycle bin. Note: You cannot roll back a DROP TABLE statement with the PURGE clause, nor can you recover the table if you drop it with the PURGE clause. This feature was not available in earlier releases. Oracle Database 10g: SQL and PL/SQL New Features

151 Bulk Returning with Single-Set Aggregates
UPDATE ... RETURNING SUM() ... SUM(column) Using Bulk Returning with Single-Set Aggregates In Oracle Database 10g, you can return a summary function’s value in the returning clause. You can also return the summary function as part of a BULK collect operation. Example: Using the RETURNING Clause The following example updates the ORDERS table and increases the ORDER_TOTAL by adding tax amount to it. The MAX() function would not have been acceptable syntax in earlier releases. The MAX() function returns the maximum value of only the rows updated and not the entire table. That is, the maximum order total for customer 146. SQL> variable x number UPDATE orders SET order_total= order_total *1.10 WHERE customer_id =146 RETURNING MAX(order_total) INTO :x; 5 rows updated. SQL> print x X Oracle Database 10g: SQL and PL/SQL New Features

152 Oracle Database 10g: SQL and PL/SQL New Features 1 - 153
Summary In this lesson, you should have learned how to: Query row versions Perform FLASHBACK operations Describe extensibility enhancements on table functions Other SQL enhancements Alternative quotes Drop and purge tables Bulk returning with single-set aggregates Summary In this lesson, you learned about several of the new SQL enhancements pertaining to performance and general use. Oracle Database 10g: SQL and PL/SQL New Features

153 Practice 5-1 Overview: Using the SQL Enhancements
This practice covers the following topics: Using flashback features to: Query a previous version of rows and restore the rows Restore a table Using the DROP TABLE statement Viewing the recycle bin Purging Practice 5-1 Overview: Using the SQL Enhancements In this practice, you use the flashback enhancements. You use the flashback query and flashback table features. Also, you examine the contents of the recycle bin and the impact of the PURGE statement on the recycle bin. Oracle Database 10g: SQL and PL/SQL New Features

154 Using Regular Expressions and Linguistic Sort and Comparison

155 Oracle Database 10g: SQL and PL/SQL New Features 1 - 156
Objectives After completing this lesson, you should be able to do the following: Use regular expressions to search for, match, and replace strings Use linguistic sort and comparison Objectives In this lesson, you learn to use the regular expression support feature that has been introduced in Oracle Database 10g. Regular expression support is available in both SQL and PL/SQL. Oracle Database 10g: SQL and PL/SQL New Features

156 What Are Regular Expressions?
You can use regular expressions to search for (and manipulate) simple and complex patterns in string data by using standard syntax conventions. You can use a set of SQL functions and conditions to search for and manipulate strings in SQL and PL/SQL. You specify a regular expression by using: Metacharacters, which are operators that specify the search algorithms Literals, which are the characters for which you are searching What Are Regular Expressions? Oracle Database 10g introduces support for regular expressions. The implementation complies with the Portable Operating System for UNIX (POSIX) standard, controlled by the Institute of Electrical and Electronics Engineers (IEEE), for ASCII data-matching semantics and syntax. Oracle’s multilingual capabilities extend the matching capabilities of the operators beyond the POSIX standard. Regular expressions are a method of describing both simple and complex patterns for searching and manipulating. String manipulation and searching contribute to a large percentage of the logic within a Web-based application. Usage ranges from the simple, such as finding the word “San Francisco” in a specified text, to the complex task of extracting all URLs from the text and the more complex task of finding all words whose every second character is a vowel. When coupled with native SQL, the use of regular expressions allows for very powerful search and manipulation operations on any data stored in an Oracle database. You can use this feature to easily solve problems that would otherwise involve complex programming. Oracle Database 10g: SQL and PL/SQL New Features

157 The Benefits of Using Regular Expressions
Regular expressions enable you to implement complex match logic in the database with the following benefits: By centralizing match logic in the Oracle Database, you avoid intensive string processing of SQL results sets by middle-tier applications. Using server-side regular expressions to enforce constraints, you eliminate the need to code data validation logic on the client. The built-in SQL and PL/SQL regular expression functions and conditions make string manipulations more powerful and easier than in previous releases. The Benefits of Using Regular Expressions Regular expressions are a powerful text-processing component of programming languages such as PERL and Java. For example, a PERL script can process each HTML file in a directory, read its contents into a scalar variable as a single string, and then use regular expressions to search for URLs in the string. One reason for many developers writing in PERL is that it has a robust pattern-matching functionality. Oracle’s support of regular expressions enables developers to implement complex match logic in the database. This technique is useful for the following reasons: By centralizing match logic in Oracle Database, you avoid intensive string processing of SQL results sets by middle-tier applications. The SQL regular expression functions move the processing logic closer to the data, thereby providing a more efficient solution. Before Oracle Database 10g, developers often coded data validation logic on the client, requiring the same validation logic to be duplicated for multiple clients. Using server-side regular expressions to enforce constraints solves this problem. The built-in SQL and PL/SQL regular expression functions and conditions make string manipulations more powerful and less cumbersome than in previous releases of Oracle Database. Oracle Database 10g: SQL and PL/SQL New Features

158 Oracle Database 10g: SQL and PL/SQL New Features 1 - 159
Using the Regular Expressions Functions and Conditions in SQL and PL/SQL Function or Condition Name Description REGEXP_LIKE Similar to the LIKE operator, but performs regular expression matching instead of simple pattern matching (condition) REGEXP_REPLACE Searches for a regular expression pattern and replaces it with a replacement string (function) REGEXP_INSTR Searches a string for a regular expression pattern and returns the position where the match is found (function) REGEXP_SUBSTR Searches for a regular expression pattern within a given string and extracts the matched substring (function) Using the Regular Expressions Functions and Conditions in SQL and PL/SQL Oracle Database 10g provides a set of SQL functions that you can use to search and manipulate strings using regular expressions. You can use these functions on a text literal, bind variable, or any column that holds character data such as CHAR, NCHAR, CLOB, NCLOB, NVARCHAR2, and VARCHAR2 (but not LONG). A regular expression must be enclosed or wrapped between single quotation marks. This ensures that the entire expression is interpreted by the SQL function and can improve the readability of your code. REGEXP_LIKE: This condition searches a character column for a pattern. Use this condition in the WHERE clause of a query to return rows matching the regular expression you specify. REGEXP_REPLACE: This function searches for a pattern in a character column and replaces each occurrence of that pattern with the pattern you specify. REGEXP_INSTR: This function searches a string for a given occurrence of a regular expression pattern. You specify which occurrence you want to find and the start position to search from. This function returns an integer indicating the position in the string where the match is found. REGEXP_SUBSTR: This function returns the actual substring matching the regular expression pattern you specify. Oracle Database 10g: SQL and PL/SQL New Features

159 What Are Metacharacters?
Metacharacters are special characters that have a special meaning such as a wildcard, a repeating character, a nonmatching character, or a range of characters. You can use several predefined metacharacter symbols in the pattern matching. For example, the ^(f|ht)tps?:$ regular expression searches for the following from the beginning of the string: The literals f or ht The t literal The p literal, optionally followed by the s literal The colon “:” literal at the end of the string Note: For a complete list of the regular expressions’ metacharacters, see the Oracle Database Application Developer's Guide – Fundamentals 10g Release 2 (10.2). Oracle Database 10g: SQL and PL/SQL New Features

160 Using Metacharacters with Regular Expressions
Syntax Description . Matches any character in the supported character set, except NULL + Matches one or more occurrence ? Matches zero or one occurrence * Matches zero or more occurrences of preceding subexpression {m} Matches exactly m occurrences of the preceding expression {m, } Matches at least m occurrences of the preceding subexpression {m,n} Matches at least m, but not more than n occurrences of the preceding subexpression […] Matches any single character in the list within the brackets | Matches one of the alternatives ( ... ) Treats the enclosed expression within the parentheses as a unit. The sub expression can be a string of literals or a complex expression containing operators. Using Metacharacters in Regular Expressions Functions Any character, “ . ” : a.b matches the strings abb, acb, and adb, but not acc. One or more, “ + ” : a+ matches the strings a, aa, and aaa, but does not match bbb. Zero or one, “ ? ”: ab?c matches the strings abc and ac, but does not match abbc. Zero or more, “ * ”: ab*c matches the strings ac, abc, and abbc, but does not match abb. Exact count, “ {m} ”: a{3} matches the strings aaa, but does not match aa. At least count, “ {m,} ”: a{3,} matches the strings aaa and aaaa, but not aa. Between count, “ {m,n} ”: a{3,5} matches the strings aaa, aaaa, and aaaaa, but not aa. Matching character list, “ […] ”: [abc] matches the first character in the strings all, bill, and cold, but does not match any characters in doll. Or, “ | ”: a|b matches character a or character b. Subexpression, “ (…) ”:(abc)?def matches the optional string abc, followed by def. The expression matches abcdefghi and def, but does not match ghi. The subexpression can be a string of literals or a complex expression containing operators. Oracle Database 10g: SQL and PL/SQL New Features

161 Using Metacharacters with Regular Expressions
Syntax Description ^ Matches the beginning of a string $ Matches the end of a string \ Treats the subsequent metacharacter in the expression as a literal \n Matches the nth (1–9) preceding subexpression of whatever is grouped within parentheses. The parentheses cause an expression to be remembered; a backreference refers to it. \d A digit character [:class:] Matches any character belonging to the specified POSIX character class [^:class:] Matches any single character not in the list within the brackets Using Metacharacters in Regular Expressions Functions (continued) Beginning/end of line anchor, “ ^ ” and “$”: ^def matches def in the string defghi but does not match def in abcdef. def$ matches def in the string abcdef but does not match def in the string defghi. Escape character “ \ ”: \+ searches for a +. It matches the plus character in the string abc+def, but does not match Abcdef. Backreference, “ \n ”:(abc|def)xy\1 matches the strings abcxyabc and defxydef, but does not match abcxydef or abcxy. A backreference enables you to search for a repeated string without knowing the actual string ahead of time. For example, the expression ^(.*)\1$ matches a line consisting of two adjacent instances of the same string. Digit character, “\d”: The expression ^\[\d{3}\] \d{3}-\d{4}$ matches [650] but does not match Character class, “ [:class:] ” : [[:upper:]]+ searches for one or more consecutive uppercase characters. This matches DEF in the string abcDEFghi but does not match the string abcdefghi. Nonmatching character list (or class), “ [^...] ” : [^abc] matches the character d in the string abcdef, but not the character a, b, or c. Oracle Database 10g: SQL and PL/SQL New Features

162 Regular Expressions Functions and Conditions: Syntax
REGEXP_LIKE (source_char, pattern [,match_option] REGEXP_INSTR (source_char, pattern [, position [, occurrence [, return_option [, match_option]]]]) REGEXP_SUBSTR (source_char, pattern [, position [, occurrence [, match_option]]]) Regular Expressions Functions and Conditions: Syntax The syntax for the regular expressions functions/condition is as follows: source_char: A character expression that serves as the search value pattern: A regular expression, a text literal occurrence: A positive integer indicating which occurrence of pattern in source_char Oracle Server should search for. The default is 1. position: A positive integer indicating the character of source_char where Oracle Server should begin the search. The default is 1. return_option: 0: Returns the position of the first character of the occurrence (default) 1: Returns the position of the character following the occurrence Replacestr: Character string replacing pattern match_parameter: “ c ”: Uses case-sensitive matching (default) “ i ”: Uses case-insensitive matching “ n ”: Allows match-any-character operator “ m ”: Treats source string as multiple lines REGEXP_REPLACE(source_char, pattern [,replacestr [, position [, occurrence [, match_option]]]]) Oracle Database 10g: SQL and PL/SQL New Features

163 Performing a Basic Search Using the REGEXP_LIKE Condition
REGEXP_LIKE(source_char, pattern [, match_parameter ]) SELECT first_name, last_name FROM employees WHERE REGEXP_LIKE (first_name, '^Ste(v|ph)en$'); FIRST_NAME LAST_NAME Steven King Steven Markle Stephen Stiles Performing a Basic Search Using the REGEXP_LIKE Condition REGEXP_LIKE is similar to the LIKE condition, except that REGEXP_LIKE performs regular-expression matching instead of the simple pattern matching performed by LIKE. This condition evaluates strings using characters as defined by the input character set. Example of REGEXP_LIKE In this query, against the EMPLOYEES table, all employees with first names containing either Steven or Stephen are displayed. In the expression used, '^Ste(v|ph)en$' : ^ indicates the beginning of the sentence $ indicates the end of the sentence | indicates either/or Oracle Database 10g: SQL and PL/SQL New Features

164 Finding Patterns Using the REGEXP_INSTR Function
REGEXP_INSTR (source_char, pattern [, position [, occurrence [, return_option [, match_option]]]]) SELECT street_address, REGEXP_INSTR(street_address,'[^[:alpha:]]')NON_ALPHA_POS FROM locations WHERE REGEXP_INSTR(street_address,'[^[:alpha:]]')> 1; STREET_ADDRESS NON_ALPHA_POS Magdalen Centre, The Oxford Science Park Schwanthalerstr Rua Frei Caneca Murtenstrasse . . . 6 rows selected. Finding Patterns Using the REGEXP_INSTR Function In this example, the REGEXP_INSTR function is used to search the street address to find the location of the first nonalphabetic character, regardless of whether it is in uppercase or lowercase. The search is performed only on those addresses that do not start with a number. Note that [:<class>:] implies a character class and matches any character from within that class; [:alpha:] matches with any alphabetic character. The results are displayed. In the expression used in the query '[^[:alpha:]]': [ starts the expression ^ indicates NOT [:alpha:] indicates alpha character class ] ends the expression Note: The POSIX character class operator enables you to search for an expression within a character list that is a member of a specific POSIX character class. You can use this operator to search for specific formatting, such as uppercase characters, or you can search for special characters such as digits or punctuation characters. The full set of POSIX character classes is supported. Use the syntax [:class:] where class is the name of the POSIX character class to search for. The following regular expression searches for one or more consecutive uppercase characters : [[:upper:]]+ . Oracle Database 10g: SQL and PL/SQL New Features

165 Extracting Substrings Using the REGEXP_SUBSTR Function
REGEXP_SUBSTR (source_char, pattern [, position [, occurrence [, match_option]]]) SELECT REGEXP_SUBSTR(street_address , ' [^ ]+ ') "Road" FROM locations; Road Via Calle Jabberwocky Interiors Zagora . . . Extracting Substrings Using the REGEXP_SUBSTR Function In this example, the road names are extracted from the LOCATIONS table. To do this, the contents in the STREET_ADDRESS column that are after the first space are returned using the REGEXP_SUBSTR function. In the expression used in the query ‘ [^ ]+ ’ : [ starts the expression ^ indicates NOT indicates space ] ends the expression + indicates 1 or more Oracle Database 10g: SQL and PL/SQL New Features

166 Replacing Patterns Using the REGEXP_REPLACE Function
REGEXP_REPLACE(source_char, pattern [,replacestr [, position [, occurrence [, match_option]]]]) SELECT REGEXP_REPLACE(country_name, '(.)', '\1 ') AS REGEXP_REPLACE FROM countries; REGEXP_REPLACE A r g e n t i n a A u s t r a l i a B e l g i u m B r a z i l C a n a d a . . . 25 rows selected. Replacing Patterns Using the REGEXP_REPLACE Function This example examines COUNTRY_NAME. The Oracle database reformats this pattern with a space after each non-null character in the string. Oracle Database 10g: SQL and PL/SQL New Features

167 Regular Expressions and Check Constraints: Examples
-- Create a Check constraint for the _addr column: ALTER TABLE employees ADD CONSTRAINT _addr NOVALIDATE; Table altered. -- Attempt to insert a row that violates the newly added -- column constraint INSERT INTO employees VALUES (500,'Christian','Patel','ChrisP2creme.com', ,'12-Jan-2004','HR_REP',2000,null,102,40, null, null); * ERROR at line 1: ORA-02290: check constraint (HR. _ADDR) violated Regular Expressions and Check Constraints: Examples Regular expressions can also be used in CHECK constraints. In this example, a CHECK constraint is added on the column of the EMPLOYEES table. This ensures that only strings containing an symbol are accepted. The constraint is tested. The CHECK constraint is violated because the address does not contain the required symbol. The NOVALIDATE clause ensures that existing data is not checked. Oracle Database 10g: SQL and PL/SQL New Features

168 Using Multilingual Capabilities
CONNECT OE/OE ALTER SESSION SET NLS_LANGUAGE = PORTUGUESE; SELECT REGEXP_SUBSTR(TO_CHAR(translated_name), '^[a-z]+', 1, 1, 'i') FROM product_descriptions WHERE language_id = 'PT' AND translated_name like 'G%' ; Sessão alterada. REGEXP_SUBSTR(TO_CHAR(TRANSLATED_NAME),'^[A-Z]+',1,1,'I') GP Gestão Gráficos 9 linhas seleccionadas. Using Multilingual Capabilities Regular expression functions support multilingual capabilities and can be used in locale-sensitive applications. The slide example uses the OE schema. In the example in the slide, the use of regular expressions is combined with Oracle’s NLS Language feature to display the Product Description in the Portuguese language. Notice the use of the case-insensitive match parameter "i" is switched on. The results will be incomplete if the NLS_LANGUAGE parameter is not set appropriately because the returned strings are being trimmed as soon as a non-English character is encountered. This is because the range [a-z] is sensitive to NLS_LANGUAGE. Therefore, you must set the NLS_LANGUAGE parameter appropriately to return the complete results. Oracle Database 10g: SQL and PL/SQL New Features

169 Using Multilingual Capabilities
SELECT REGEXP_SUBSTR (i.product_name, '^[a-z]+', 1, 1, 'i') || ' = ' || REGEXP_SUBSTR (TO_CHAR(d.translated_name), '^[a-z]+', 1, 1, 'i') AS RESULTS FROM oe.product_descriptions d, oe.product_information i WHERE d.language_id = 'PT' AND d.translated_name like 'G%' AND i.product_id = d.product_id ; RESULTS GP = GP Project = Gestão Graphics = Gráficos 9 linhas seleccionadas. Using Multilingual Capabilities (continued) To ensure that the translation has taken place, the example in the slide displays the results in both English as well as Portuguese. To return your session back to its original NLS setting, use the ALTER SESSION statement as follows: ALTER SESSION SET NLS_LANGUAGE=AMERICAN; Note: This example in the slide uses the OE schema. Oracle Database 10g: SQL and PL/SQL New Features

170 Oracle Database 10g: SQL and PL/SQL New Features 1 - 171
Sorting: Overview Different languages have different sort orders. Sort order can be case sensitive or case insensitive. Sort order can ignore or consider diacritics. Sort order can be phonetic or it can be based on the appearance of the character. Sorting: Overview Different languages have different sort orders. In addition, different cultures or countries that use the same alphabets may sort words differently. For example, in Danish, Æ is after Z, whereas Y and Ü are considered to be variants of the same letter. Sort order can be case sensitive or case insensitive. Case refers to the condition of being uppercase or lowercase. For example, in a Latin alphabet, A is the uppercase glyph for a, the lowercase glyph. Sort order can ignore or consider diacritics. A diacritic is a mark near or through a character or combination of characters that indicates a different sound than the sound of the character without the diacritic. For example, the cedilla (,) in façade is a diacritic. It changes the sound of c. Sort order can be phonetic or it can be based on the appearance of the character. For example, sort order can be based on the number of strokes in East Asian ideographs. Another common sorting issue is combining letters into a single character. For example, in traditional Spanish, ch is a distinct character that comes after c, which means that the correct order is: cerveza, colorado, cheremoya. This means that the letter c cannot be sorted until Oracle Server has checked whether the next letter is an h. Oracle Database 10g: SQL and PL/SQL New Features

171 Oracle’s Sorting Capabilities
Binary sort Linguistic sort Oracle’s Sorting Capabilities Oracle provides the following sorts capabilities that achieve a linguistically correct order for a single language as well as a sort based on the multilingual ISO standard (ISO 14651), which is designed to handle many languages at the same time: Binary Sort Binary sort enables you to sort character data based on the numeric values of the characters defined by the character-encoding scheme. Binary sorts are the fastest type of sort. They produce reasonable results for the English alphabet because the ASCII and EBCDIC standards define the letters A to Z in ascending numeric value. Linguistic Sort To produce a sort sequence that matches the alphabetic sequence of characters, another sort technique must be used that sorts characters independently of their numeric values in the character-encoding scheme. This technique is called a linguistic sort. A linguistic sort operates by replacing characters with numeric values that reflect each character’s proper linguistic order. Oracle offers two kinds of linguistic sorts: monolingual and multilingual. In this lesson, you get an overview of linguistic sorting. Oracle Database 10g: SQL and PL/SQL New Features

172 Oracle Database 10g: SQL and PL/SQL New Features 1 - 173
Using NLS_SORT to Specify a Case-Insensitive or Accent-Insensitive Linguistic Sort You can use the NLS_SORT linguistic sort parameter to specify how to sort character data: Append _CI to an Oracle sort name for a case-insensitive sort. Append _AI to an Oracle sort name for an accent-insensitive and case-insensitive sort. NLS_SORT = BINARY | <NLS_sort_name>[_AI | _CI] Using NLS_SORT to Specify a Case-Insensitive or Accent-Insensitive Linguistic Sort Case-insensitive comparison and sorting is a frequently used feature in the database. In previous releases, you could call functions to make SQL statements case insensitive. This has the following disadvantages: Hard to migrate from other database vendors. Many customers want to have the same SQL behaviors without changing existing code. Performance degradation when you use the LOWER/UPPER function. These functions convert the whole string to lowercase or uppercase, then do the comparison. Less flexibility and reusability for the same SQL query statements with different comparing-level requirements Oracle Database 10g provides the following monolingual and multilingual linguistic sorts: Case-insensitive: Uses information about base letters, diacritics, and punctuation Accent-insensitive: Uses information about base letters only. This is always case-insensitive as well. Use NLS_SORT to specify the type of sort for character data. It overrides the default value that is derived from NLS_LANGUAGE. Use NLS_SORT to specify the linguistic sort name. The default value is derived from the parameter NLS_LANGUAGE. Oracle Database 10g: SQL and PL/SQL New Features

173 Using the NLS_SORT Parameter: Examples
-- Japanese linguistic sort sequence NLS_SORT = JAPANESE_M -- Accent insensitive and case insensitive sort NLS_SORT = FRENCH_M_AI -- Accent sensitive and case insensitive sort NLS_SORT = XGERMAN_CI -- Accent sensitive and case insensitive binary sort NLS_SORT = BINARY_CI -- Accent insensitive and case insensitive binary sort NLS_SORT = BINARY_AI Oracle Database 10g: SQL and PL/SQL New Features

174 Modifying the Default Value of NLS_SORT
You can alter the default value of NLS_SORT by doing one of the following: Changing its value in the initialization parameter file and then restarting the instance Using an ALTER SESSION statement ALTER SESSION SET NLS_SORT = BINARY |<NLS_sort_name>[_AI|_CI] Oracle Database 10g: SQL and PL/SQL New Features

175 Using the NLS_COMP Initialization Parameter
NLS_COMP = BINARY | LINGUISTIC | ANSI Use NLS_COMP instead of the NLSSORT function in SQL statements to perform a linguistic comparison. The value of NLS_COMP affects the comparison behavior of SQL operations. When NLS_COMP is set to LINGUISTIC, SQL operations perform a linguistic comparison based on the value of NLS_SORT. Alter the default value of NLS_COMP as follows: Using the NLS_COMP Initialization Parameter When performing SQL comparison operations, characters are compared according to their binary values. A character is greater than another if it has a higher binary value. Because the binary sequences rarely match the linguistic sequences for most languages, such comparisons may not be meaningful for a typical user. To achieve a meaningful comparison, you can specify behavior by using the session parameters NLS_COMP and NLS_SORT. The way you set these two parameters determines the rules by which characters are sorted and compared. Use NLS_COMP instead of the NLSSORT function in SQL statements to perform a linguistic comparison. The value of NLS_COMP affects the comparison behavior of SQL operations. When NLS_COMP is set to LINGUISTIC, SQL operations perform a linguistic comparison based on the value of NLS_SORT. In addition, when NLS_COMP is set to LINGUISTIC, a linguistic index improves the performance of the linguistic comparison. Create a linguistic index as follows: CREATE INDEX i ON t(NLSSORT(col, 'NLS_SORT=FRENCH')); Note: A setting of ANSI is for backward compatibility. In general, you should set NLS_COMP to LINGUISTIC when you want to perform a linguistic comparison. ALTER SESSION SET NLS_COMP = LINGUISTIC Oracle Database 10g: SQL and PL/SQL New Features

176 Linguistic Comparison Behavior with NLS_COMP Set to Linguistic
SQL Expression Uses NLS_SORT? =, !=, >, <, >=, <= Yes BETWEEN, NOT BETWEEN, IN, NOT IN CASE DISTINCT GROUP, GROUP BY HAVING ORDER BY LIKE START WITH Linguistic Comparison Behavior with NLS_COMP Settings All SQL sorting and comparison are based on the linguistic rule specified by NLS_SORT. For example, NLS_COMP=LINGUISTIC and NLS_SORT=BINARY_CI means the collation-sensitive SQL operations use binary value for sorting and comparison but ignore character case. The table in the slide shows how different SQL operations behave with these different settings. Note: For additional information about how Oracle handles sorting if NLS_COMP is set to either BINARY or ANSI, see “Table 5-2 Linguistic Comparison Behavior with NLS_COMP Settings” in Oracle Database Globalization Support Guide 10g Release 2. Oracle Database 10g: SQL and PL/SQL New Features

177 The NLSSORT Function: Case-Insensitive and Accent-Insensitive Support
NLSSORT(<col_name>, 'NLS_SORT=NLS_sort_name>[_AI|_CI]') ALTER SESSION SET NLS_SORT = generic_m; -- Search for all occurrences of 'De Niro', regardless -- of the case and accent. SELECT cust_last_name FROM customers WHERE NLSSORT(cust_last_name, 'NLS_SORT = generic_m_ai') = NLSSORT('De Niro', 'NLS_SORT=generic_m_ai'); CUST_LAST_NAME de Niro De Niro dë Nirõ The NLSSORT Function: Case-Insensitive and Accent-Insensitive Support The NLSSORT function is extended to support case-insensitive and accent-insensitive functionality. The NLSSORT function enables you to use any linguistic sort for an ORDER BY clause. It replaces a character string with the equivalent sort string used by the linguistic sort mechanism so that sorting the replacement strings produces the desired sorting sequence. For a binary sort, the sort string is the same as the input string. The kind of linguistic sort used by an ORDER BY clause is determined by the NLS_SORT session parameter, but it can be overridden by explicitly using the NLSSORT function. If you frequently use NLSSORT in comparison operations with the same linguistic sort sequence, then consider this more efficient alternative: Set the NLS_COMP parameter (for either the database or the current session) to LINGUISTIC, and set the NLS_SORT parameter for the session to the desired sort sequence. Oracle Database uses that sort sequence by default for all sorting and comparison operations during the current session. You typically use the NLSSORT function in an ORDER BY or WHERE clause when the linguistic setting of the session parameter NLS_SORT is different from the linguistic setting in the SQL statement. Oracle Database 10g: SQL and PL/SQL New Features

178 Working with the NLSSORT Function
NLSSORT(<col_name>, 'NLS_LANGUAGE=<Language_name>') NLSSORT(<col_name>, 'NLS_LANG==<Language_abbrev>') -- Example 1: Generic_M sort, accent sensitive, & -- case insensitive is used on the item_name column. NLSSORT(item_name, 'NLS_SORT=Generic_M_CI') -- Example 2: Accent sensitive & case sensitive sort. NLSSORT(item_name, 'NLS_LANGUAGE=French') -- Example 3: 'F' is the abbreviation for French. NLSSORT(item_name, 'NLS_LANG=F') Working with the NLSSORT Function The NLSSORT function takes a parameter value for NLS_LANG (or NLS_LANGUAGE as an alternative). Examples In the first example in the slide, the original Generic_M sort with accent-sensitive and case-insensitive feature is used on the item_name column. In the second example, accent-sensitive and case-sensitive sort is used. The default sort of French is defined in the French language definition file. In the third example, 'F' is the abbreviation for French. Oracle Database 10g: SQL and PL/SQL New Features

179 Oracle Database 10g: SQL and PL/SQL New Features 1 - 180
Summary In this lesson, you should have learned how to: Use regular expressions to search for, match, and replace strings Use linguistic sort and comparison Summary In this lesson you have learned to use the regular expression support features that have been introduced in Oracle Database 10g. Regular expression support is available in both SQL and PL/SQL. Oracle Database 10g: SQL and PL/SQL New Features

180 Oracle Database 10g: SQL and PL/SQL New Features 1 - 181
Practice 6: Overview This practice covers using regular expressions functions to do the following: Searching for, replacing, and manipulating data Creating a new CONTACTS table and adding a CHECK constraint to the p_number column to ensure that phone numbers are entered into the database in a specific standard format Testing the adding of some phone numbers into the p_number column by using various formats Practice 6: Overview In this practice, you use regular expressions functions to search for, replace, and manipulate data. You also create a new CONTACTS table and add a CHECK constraint to the p_number column to ensure that phone numbers are entered into the database in a specific standard format. Oracle Database 10g: SQL and PL/SQL New Features

181 Using the New PL/SQL Compiler

182 Oracle Database 10g: SQL and PL/SQL New Features 1 - 183
Objectives After completing this lesson, you should be able to do the following:Describe the new PL/SQL compiler and features Describe the new PL/SQL compiler and features Use the new PL/SQL compiler initialization parameters Use the new PL/SQL compile time warnings Oracle Database 10g: SQL and PL/SQL New Features

183 Oracle Database 10g: SQL and PL/SQL New Features 1 - 184
Lesson Agenda Describing the new PL/SQL compiler and features Using the New PLSQL_CODE_TYPE, PLSQL_DEBUG, and PLSQL_OPTIMIZE_LEVEL PL/SQL Compilation Initialization Parameters Using the New PL/SQL Compile Time Warnings: Using the PLSQL_WARNING Initialization Parameter Using the DBMS_WARNING Package Routines Oracle Database 10g: SQL and PL/SQL New Features

184 Using the New PL/SQL Compiler in Oracle Database 10g
PL/SQL uses a new optimizing compiler that can rearrange code for better performance. PL/SQL performance is improved across the board. Most improvements are automatic. The default optimization level improves performance for a broad range of PL/SQL operations. Using the New PL/SQL Compiler in Oracle Database 10g Oracle Database 10g has a completely redesigned and reimplemented PL/SQL compiler back end that features code optimization. The new PL/SQL compiler replaces the old compiler and all modern and current industry compiler techniques have been incorporated. It has the following purposes: An immediate improvement in the quality of the code generated by the PL/SQL compiler and thus improvement in the execution performance of PL/SQL programs A foundation for global optimization to improve PL/SQL execution What Is New for PL/SQL Performance in Oracle Database 10g? PL/SQL performance is improved across the board. Most improvements are automatic. The new PL/SQL compiler ensures optimized code generation. Global optimization of PL/SQL code is controlled by the PLSQL_OPTIMIZE_LEVEL initialization parameter. The default optimization level improves performance for a broad range of PL/SQL operations. Oracle Database 10g: SQL and PL/SQL New Features

185 Changes in the PL/SQL Compiler
Elimination of compiler-generated temporary operands Computation of some operations during compilation Reuse of some expression values Simplification or elimination of some branches and dead code elimination Avoidance of library calls by direct execution in the PL/SQL virtual machine of some operations All cursors correctly finalized upon exit from a cursor loop or a declare block Elimination of computations whose only effect is, as a side effect, to raise an exception Changes in the PL/SQL Compiler The new PL/SQL compiler provides the same execution for PL/SQL programs as the previous PL/SQL compiler. The behavior of a program is intended to remain the same. Some of the implicit changes that may happen to compiled code are the following: Elimination of temporary operands generated by the PL/SQL compiler. Such elimination causes less storage to be used and speeds up the process of initializing temporary values. Computation of some operations during compilation rather that during execution Reuse of some expression values. For example, if the expression A + B occurs twice and the values of A and B are not changed, the second occurrence may be removed by the optimizer. Simplification or elimination of some branches Avoidance of library calls by direct execution in the PL/SQL virtual machine of some operations All cursors correctly finalized upon exit from a cursor loop or a declare block Elimination of computations whose only effect is, as a side effect, to raise an exception. If there are no other side effects of the conditional expression besides the possible exception, the PL/SQL compiler optimization eliminates the entire computation. Oracle Database 10g: SQL and PL/SQL New Features

186 Oracle Database 10g: SQL and PL/SQL New Features 1 - 187
Lesson Agenda Describing the new PL/SQL compiler and features Using the New PLSQL_CODE_TYPE, PLSQL_DEBUG, and PLSQL_OPTIMIZE_LEVEL PL/SQL Compilation Initialization Parameters Using the New PL/SQL Compile Time Warnings: Using the PLSQL_WARNING Initialization Parameter Using the DBMS_WARNING Package Routines Oracle Database 10g: SQL and PL/SQL New Features

187 Initialization Parameters for PL/SQL Compilation
PLSQL_CODE_TYPE PLSQL_DEBUG PLSQL_OPTIMIZE_LEVEL PLSQL_CCFLAGS PLSQL_WARNINGS Initialization Parameters for PL/SQL Compilation In releases before Oracle Database 10g, the PL/SQL compiler translated your code to machine code without applying many changes for performance. Now, PL/SQL uses an optimizing compiler that can rearrange code for better performance. You do not need to do anything to get the benefits of this new optimizer; it is enabled by default. Note The PLSQL_CCFLAGS initialization parameter is covered in the lesson titled “Programming with PL/SQL Enhancements.” The PLSQL_WARNINGS initialization parameter is covered later in this lesson. Oracle Database 10g: SQL and PL/SQL New Features

188 Using the Initialization Parameters for PL/SQL Compilation
PLSQL_CODE_TYPE: Specifies the compilation mode for PL/SQL library units PLSQL_DEBUG: Specifies whether or not to compile PL/SQL library units for debugging PLSQL_OPTIMIZE_LEVEL: Specifies the optimization level to be used to compile PL/SQL library units PLSQL_CODE_TYPE = { INTERPRETED | NATIVE } PLSQL_DEBUG = { TRUE | FALSE } Using the PL/SQL Initialization Parameters The PLSQL_CODE_TYPE Parameter Specifies the compilation mode for PL/SQL library units. If you choose INTERPRETED, PL/SQL library units will be compiled to PL/SQL bytecode format. Such modules are executed by the PL/SQL interpreter engine. If you choose NATIVE, PL/SQL library units (with the possible exception of top-level anonymous PL/SQL blocks) will be compiled to native (machine) code. Such modules will be executed natively without incurring any interpreter overhead. When the value of this parameter is changed, it has no effect on PL/SQL library units that have already been compiled. The value of this parameter is stored persistently with each library unit. If a PL/SQL library unit is compiled natively, all subsequent automatic recompilations of that library unit will use native compilation. In Oracle Database 10g, native compilation is easier and more integrated, with fewer initialization parameters to set. In rare cases, if the overhead of the optimizer makes compilation of very large applications take too long, you might lower the optimization level by setting the initialization parameter PLSQL_OPTIMIZE_LEVEL to 1 instead of its default value 2. In even rarer cases, you might see a change in exception behavior—either an exception that is not raised at all or one that is raised earlier than expected. Setting PLSQL_OPTIMIZE_LEVEL to 0 prevents the code from being rearranged at all. PLSQL_OPTIMIZE_LEVEL = { 0 | 1 | 2 } Oracle Database 10g: SQL and PL/SQL New Features

189 The New Compiler Settings in Oracle 10g
Compiler Option In Oracle 9i? In Oracle 10g? PLSQL_CODE_TYPE No Yes PLSQL_DEBUG PLSQL_OPTIMIZE_LEVEL PLSQL_WARNINGS PLSQL_CCFLAGS In general, for the fastest performance, use the following setting: The Compiler Settings The new compiler increases the performance of PL/SQL code and allows it to execute approximately two times faster than an Oracle8i database and 1.5 times to 1.75 times as fast as Oracle9i Database Release 2. In earlier releases, the compiler options were combinations of DEBUG or NON_DEBUG and INTERPRETED or NATIVE. In Oracle Database 10g, there is a third choice for compiler settings: PLSQL_OPTIMIZE_LEVEL. To get the fastest performance, the compiler setting must be: PLSQL_DEBUG = FALSE PLSQL_CODE_TYPE = NATIVE PLSQL_OPTIMIZE_LEVEL = 2 PLSQL_DEBUG = FALSE PLSQL_CODE_TYPE = NATIVE PLSQL_OPTIMIZE_LEVEL = 2 Oracle Database 10g: SQL and PL/SQL New Features

190 Displaying the PL/SQL Initialization Parameters
Use the USER|ALL|DBA_PLSQL_OBJECT_SETTINGS data dictionary views to display the settings for a PL/SQL object: DESCRIBE USER_PLSQL_OBJECT_SETTINGS Name Null? Type NAME NOT NULL VARCHAR2(30) TYPE VARCHAR2(12) PLSQL_OPTIMIZE_LEVEL NUMBER PLSQL_CODE_TYPE VARCHAR2(4000) PLSQL_DEBUG VARCHAR2(4000) PLSQL_WARNINGS VARCHAR2(4000) NLS_LENGTH_SEMANTICS VARCHAR2(4000) PLSQL_CCFLAGS VARCHAR2(4000) Displaying the PL/SQL Initialization Parameters The following is the description of the columns in the USER_PLSQL_OBJECTS_SETTINGS data dictionary view: Owner: The owner of the object. This column is not displayed in the USER_PLSQL_OBJECTS_SETTINGS view. Name: The name of the object Type: The available choices are: PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY, TRIGGER, TYPE, or TYPE BODY. PLSQL_OPTIMIZE_LEVEL: The optimization level that was used to compile the object PLSQL_CODE_TYPE: The compilation mode for the object PLSQL_DEBUG: Specifies whether or not the object was compiled for debugging PLSQL_WARNINGS: The compiler warning settings used to compile the object NLS_LENGTH_SEMANTICS: The NLS length semantics used to compile the object PLSQL_CCFLAGSNLS: The conditional compilation flag used to compile the object Oracle Database 10g: SQL and PL/SQL New Features

191 Displaying and Setting the PL/SQL Initialization Parameters
SELECT name, type, plsql_debug, plsql_code_type AS CODE_TYPE, plsql_optimize_level AS OPT_LVL FROM user_plsql_object_settings; NAME TYPE DEBUG CODE_TYPE OPT_LVL SECURE_DML PROCEDURE FALSE INTERPRETED SECURE_EMPLOYEES TRIGGER FALSE INTERPRETED ADD_JOB_HISTORY PROCEDURE FALSE INTERPRETED UPDATE_JOB_HISTORY TRIGGER FALSE INTERPRETED Set the compiler initialization parameter’s value using the ALTER SYSTEM or ALTER SESSION statements. The parameters’ values are accessed when the CREATE OR REPLACE statement is executed. Note For additional information on the ALTER SYSTEM or ALTER SESSION statements, see the Oracle Database SQL Reference 10g Release 2 (10.2) Guide. The DBA_STORED_SETTINGS data dictionary view family is deprecated in Oracle Database 10g and is replaced with the DBA_PLSQL_OBJECT_SETTINGS data dictionary view family. Oracle Database 10g: SQL and PL/SQL New Features

192 Changing the PL/SQL Initialization Parameters: Example
ALTER SESSION SET PLSQL_DEBUG = true; Session altered. ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 1; ALTER SESSION SET PLSQL_CODE_TYPE = 'NATIVE'; CREATE OR REPLACE PROCEDURE add_job_history . . . NAME TYPE DEBUG CODE_TYPE OPT_LVL SECURE_DML PROCEDURE FALSE INTERPRETED SECURE_EMPLOYEES TRIGGER FALSE INTERPRETED ADD_JOB_HISTORY PROCEDURE TRUE NATIVE UPDATE_JOB_HISTORY TRIGGER FALSE INTERPRETED Changing a PL/SQL Initialization Parameters: Example To change a compiled PL/SQL object from interpreted code type to native code type, you must first set the PLSQL_CODE_TYPE parameter to NATIVE (optionally set the other parameters) and then, recompile the program. To enforce native compilation to all PL/SQL code, you must recompile each one. Scripts (in the rdmbs/admin directory) are provided for you to achieve conversion to full native compilation (dbmsupgnv.sql) or full interpreted compilation (dbmsupgin.sql). The add_job_history procedure is created as follows: CREATE OR REPLACE PROCEDURE add_job_history ( p_emp_id job_history.employee_id%type , p_start_date job_history.start_date%type , p_end_date job_history.end_date%type , p_job_id job_history.job_id%type , p_department_id job_history.department_id%type ) IS BEGIN INSERT INTO job_history (employee_id, start_date, end_date, job_id, department_id) VALUES(p_emp_id, p_start_date, p_end_date, p_job_id, p_department_id); END add_job_history; / Oracle Database 10g: SQL and PL/SQL New Features

193 Oracle Database 10g: SQL and PL/SQL New Features 1 - 194
Lesson Agenda Describing the new PL/SQL compiler and features Using the New PLSQL_CODE_TYPE, PLSQL_DEBUG, and PLSQL_OPTIMIZE_LEVEL PL/SQL Compilation Initialization Parameters Using the New PL/SQL Compile Time Warnings: Using the PLSQL_WARNING Initialization Parameter Using the DBMS_WARNING Package Routines Oracle Database 10g: SQL and PL/SQL New Features

194 Overview of PL/SQL Compile-Time Warnings for Subprograms
The PL/SQL compiler in Oracle Database 10g has been enhanced to produce warnings for subprograms. Enable warnings Compile program View warnings Overview of PL/SQL Compile-Time Warnings for Subprograms To make your programs more robust and avoid problems at run time, you can turn on checking for certain warning conditions. These conditions are not serious enough to produce an error and keep you from compiling a subprogram. They may point out something in the subprogram that produces an undefined result or might create a performance problem. In releases before Oracle Database 10g, compiling a PL/SQL program had two possible outcomes: Success, producing a valid compiled unit Failure, with compilation errors indicating that the program had either syntax or semantic errors However, even when compilation of a program was successful, the program may have violated recommended best practices or could have been coded to be more efficient. Oracle Database 10g introduces a new ease-of-use feature that allows the PL/SQL compiler to communicate warning messages in these situations. Compiler warnings allow developers to avoid common coding pitfalls improving productivity. Oracle Database 10g: SQL and PL/SQL New Features

195 The Benefits of the Compiler Warnings
Make programs more robust and avoid problems at run time Identify potential performance problems Identify factors that produce undefined results The Benefits of Compiler Warnings Using compiler warnings can help you to: Make your programs more robust and avoid problems at run time Identify potential performance problems Identify factors that produce undefined results Note You can enable checking for certain warning conditions when these conditions are not serious enough to produce an error and keep you from compiling a subprogram. Warning messages can be issued during compilation of PL/SQL subprograms; anonymous blocks do not produce any warnings. All PL/SQL warning messages use the prefix PLW. Oracle Database 10g: SQL and PL/SQL New Features

196 The PL/SQL Compile-Time Warning Messages Categories
PERFORMANCE SEVERE ALL INFORMATIONAL The PL/SQL Compile-Time Warning Messages Categories PL/SQL warning messages are divided into categories, so that you can suppress or display groups of similar warnings during compilation. The categories are: SEVERE: Messages for conditions that may cause unexpected behavior or wrong results, such as aliasing problems with parameters PERFORMANCE: Messages for conditions that may cause performance problems, such as passing a VARCHAR2 value to a NUMBER column in an INSERT statement INFORMATIONAL: Messages for conditions that do not have an effect on performance or correctness, but that you may want to change to make the code more maintainable, such as unreachable code that can never be executed Oracle Database 10g: SQL and PL/SQL New Features

197 Setting the Warning Messages Levels
You can set warning levels using one of the following methods: Declaratively: Using the PLSQL_WARNINGS initialization parameter Programmatically: Using the DBMS_WARNING package Setting the Warning Messages Levels You can set the compiler warning messages levels using one of the following methods: Using the PLSQL_WARNINGS Initialization Parameter The PLSQL_WARNINGS setting enables or disables the reporting of warning messages by the PL/SQL compiler, and specifies which warning messages to show as errors. The settings for the PLSQL_WARNINGS parameter are stored along with each compiled subprogram. You can use the PLSQL_WARNINGS initialization parameter to do the following: Enable or disable the reporting of all warnings, warnings of a selected category, or specific warning messages. Treat all warnings, a selected category of warning, or specific warning messages as errors. Any valid combination of the above The keyword All is a shorthand way to refer to all warning messages: SEVERE, PERFORMANCE, and INFORMATIONAL. Using the DBMS_WARNING Package The DBMS_WARNING package provides a way to manipulate the behavior of PL/SQL warning messages, in particular by reading and changing the setting of the PLSQL_WARNINGS initialization parameter to control what kinds of warnings are suppressed, displayed, or treated as errors. This package provides the interface to query, modify, and delete current system or session settings. This package is covered later in this lesson. PLSQL_WARNINGS initialization parameter DBMS_WARNING package Oracle Database 10g: SQL and PL/SQL New Features

198 Setting Compiler Warning Levels: Using PLSQL_WARNINGS
ALTER [SESSION|SYSTEM] PLSQL_WARNINGS = 'value_clause1'[ ,'value_clause2']... value_clause = Qualifier Value : Modifier Value Qualifier Value = { ENABLE | DISABLE | ERROR } Modifier Value = { ALL | SEVERE | INFORMATIONAL | PERFORMANCE | { integer | (integer [, integer ] ...) } } Modifying Compiler Warning Settings The parameter value comprises a comma-separated list of quoted qualifier and modifier keywords, where the keywords are separated by colons. The qualifier values are: ENABLE, DISABLE, and ERROR. The modifier value ALL applies to all warning messages. SEVERE, INFORMATIONAL, and PERFORMANCE apply to messages in their own category, and an integer list for specific warning messages. Possible values for ENABLE, DISABLE, and ERROR: ALL SEVERE INFORMATIONAL PERFORMANCE numeric_value Values for numeric_value are in: Range for severe Range for informational Range for performance Oracle Database 10g: SQL and PL/SQL New Features

199 Setting Compiler Warning Levels: Using PLSQL_WARNINGS, Examples
ALTER SESSION SET plsql_warnings = 'enable:severe', 'enable:performance', 'disable:informational'; Session altered. ALTER SESSION SET plsql_warnings = 'enable:severe'; Session altered. ALTER SESSION SET PLSQL_WARNINGS='ENABLE:SEVERE', 'DISABLE:PERFORMANCE' , 'ERROR:05003'; Session altered. Setting Compiler Warning Levels: Using PLSQL_WARNINGS, Examples You can use the ALTER SESSION or ALTER SYSTEM command to change the PLSQL_WARNINGS initialization parameter. The graphic in the slide shows the various examples of enabling and disabling compiler warnings. Example 1 In this example, you are enabling SEVERE and PERFORMANCE warnings and disabling INFORMATIONAL warnings. Example 2 In the second example, you are enabling only SEVERE warnings. Example 3 You can also treat particular messages as errors instead of warnings. In this example, if you know that the warning message PLW represents a serious problem in your code, including 'ERROR:05003' in the PLSQL_WARNINGS setting makes that condition trigger an error message (PLS_05003) instead of a warning message. An error message causes the compilation to fail. In this example, you are also disabling PERFORMANCE warnings. Oracle Database 10g: SQL and PL/SQL New Features

200 Viewing the Current Setting of PLSQL_WARNINGS
V$PARAMETER view DBMS_WARNING package function USER|DBA|ALL_PLSQL_ OBJECT_SETTINGS views Viewing the Current Value of the PLSQL_WARNINGS Parameter You can examine the current setting for the PLSQL_WARNINGS parameter by issuing a SELECT statement on the V$PARAMETER view. For example: ALTER SESSION SET plsql_warnings = 'enable:severe', 'enable:performance','enable:informational'; Session altered. SELECT value FROM v$parameter WHERE name='plsql_warnings'; VALUE ENABLE:ALL Alternatively, you can use the DBMS_WARNING.GET_WARNING_SETTING_STRING package and method to retrieve the current settings for the PLSQL_WARNINGS parameter: DECLARE s VARCHAR2(1000); BEGIN s := dbms_warning.get_warning_setting_string(); dbms_output.put_line (s); END; / ENABLE:ALL PL/SQL procedure successfully completed. PLSQL_WARNINGS initialization parameter Oracle Database 10g: SQL and PL/SQL New Features

201 Viewing the Compiler Warnings: Using SQL*Plus or Data Dictionary Views
Use SHOW ERRORS command in SQL*Plus. View warnings Enable warnings Compile program Viewing the Compiler Warnings You can use SQL*Plus to see any warnings raised as a result of the compilation of a PL/SQL block. SQL*Plus indicates that a compilation warning has occurred. The “SP2-08xx: <object> created with compilation warnings.” message is displayed for objects compiled with the PERFORMANCE, INFORMATIONAL, or SEVERE modifiers. There is no differentiation between the three. You must enable the compiler warnings before compiling the program. You can display the compiler warning messages using one of the following methods: Using the SQL*Plus SHOW ERRORS Command This command displays any compiler errors including the new compiler warnings and informational messages. This command is invoked immediately after a CREATE [PROGEDURE|FUNCTION|PACKAGE] command is used. The SHOW ERRORS command displays warnings and compiler errors. New compiler warnings and informational messages are “interleaved” with compiler errors when SHOW ERRORS is invoked. Using the Data Dictionary Views You can select from the USER_|ALL_|DBA_ERRORS data dictionary views to display PL/SQL compiler warnings. The ATTRIBUTES column of these views has a new attribute called WARNING and the warning message displays in the TEXT column. Use USER_ERRORS, ALL_ERRORS, or DBA_ERRORS views Oracle Database 10g: SQL and PL/SQL New Features

202 SQL*Plus Warning Messages: Example
CREATE OR REPLACE PROCEDURE bad_proc(p_out …) IS BEGIN . . .; END; / SP2-0804: Procedure created with compilation warnings. SHOW ERRORS; Errors for PROCEDURE BAD_PROC: LINE/COL ERROR 6/24 PLW-07203: parameter 'p_out' may benefit from use of the NOCOPY compiler hint SQL*Plus Warning Messages: Example Use the SHOW ERRORS command in SQL*Plus to display the compilation errors of a stored procedure. When you specify this option with no arguments, SQL*Plus displays the compilation errors for the most recently created or altered stored procedure. If SQL*Plus displays a compilation warnings message after you create or alter a stored procedure, you can use SHOW ERRORS commands to obtain more information. With the introduction of the support for PL/SQL warnings, the range of feedback messages is expanded to include a third message as follows: SP2-08xx: <object> created with compilation warnings. This enables you to differentiate between the occurrence of a compilation warning and a compilation error. You must correct an error if you want to use the stored procedure, whereas a warning is for informational purposes only. The SP2 prefix is included with the warning message, as this provides you with the ability to look up the corresponding message number in the SQL*Plus User’s Guide and Reference to determine the cause and action for the particular message. Oracle Database 10g: SQL and PL/SQL New Features

203 Guidelines for Using PLSQL_WARNINGS
The settings for the PLSQL_WARNINGS parameter are stored along with each compiled subprogram. The PLSQL_WARNINGS setting can be set to DEFERRED at the system level. If you recompile the subprogram using one of the following statements, the current settings for that session are used: CREATE OR REPLACE ALTER ... COMPILE If you recompile the subprogram using the ALTER ... COMPILE statement with the REUSE SETTINGS clause, the original setting stored with the program is used. Guidelines for Using PLSQL_WARNINGS As already stated, the PLSQL_WARNINGS parameter can be set at the session level or the system level. When setting it at the system level, you can include the value DEFERRED so that it applies to future sessions but not the current one. The settings for the PLSQL_WARNINGS parameter are stored along with each compiled subprogram. If you recompile the subprogram with a CREATE OR REPLACE statement, the current settings for that session are used. If you recompile the subprogram with an ALTER...COMPILE statement, then the current session setting is used unless you specify the REUSE SETTINGS clause in the statement, which uses the original setting that is stored with the subprogram. Oracle Database 10g: SQL and PL/SQL New Features

204 Oracle Database 10g: SQL and PL/SQL New Features 1 - 205
Lesson Agenda Describing the new PL/SQL compiler and features Using the New PLSQL_CODE_TYPE, PLSQL_DEBUG, and PLSQL_OPTIMIZE_LEVEL PL/SQL Compilation Initialization Parameters Using the New PL/SQL Compile Time Warnings: Using the PLSQL_WARNING Initialization Parameter Using the DBMS_WARNING Package Routines Oracle Database 10g: SQL and PL/SQL New Features

205 Setting Compiler Warning Levels: Using the DBMS_WARNING Package
Query settings Modify settings DBMS_WARNINGS. GET_WARNING_ SETTING_STRING procedure Setting Compiler Warning Levels: Using the DBMS_WARNING Package Use the DBMS_WARNING package to programmatically manipulate the behavior of current system or session PL/SQL warning settings. The DBMS_WARNING package provides a way to manipulate the behavior of PL/SQL warning messages, in particular by reading and changing the setting of the PLSQL_WARNINGS initialization parameter to control what kinds of warnings are suppressed, displayed, or treated as errors. This package provides the interface to query, modify, and delete current system or session settings. The DBMS_WARNING package is valuable if you are writing a development environment that compiles PL/SQL subprograms. Using the package interface routines, you can control PL/SQL warning messages programmatically to suit your requirements. Restore settings Delete settings Oracle Database 10g: SQL and PL/SQL New Features

206 Using the DBMS_WARNING Package Subprograms
Scenario Subprograms to Use Set warnings ADD_WARNING_SETTING_CAT (procedure) ADD_WARNING_SETTING_NUM (procedure) Query warnings GET_WARNING_SETTING_CAT (function) GET_WARNING_SETTING_NUM (function) GET_WARNING_SETTING_STRING (function) Replace warnings SET_WARNING_SETTING_STRING (procedure) Get the warnings’ categories names GET_CATEGORY (function) Using the DBMS_WARNING Subprograms The following is a list of the DBMS_WARNING subprograms: ADD_WARNING_SETTING_CAT: Modifies the current session or system warning settings of the warning_category previously supplied ADD_WARNING_SETTING_NUM: Modifies the current session or system warning settings of the warning_number previously supplied GET_CATEGORY: Returns the category name, given the message number GET_WARNING_SETTING_CAT: Returns the specific warning category in the session GET_WARNING_SETTING_NUM: Returns the specific warning number in the session GET_WARNING_SETTING_STRING: Returns the entire warning string for the current session SET_WARNING_SETTING_STRING: Replaces previous settings with the new value Note: For additional information on the above subprograms, see the Oracle Database PL/SQL Packages and Types Reference 10g Release 2 (10.2). Oracle Database 10g: SQL and PL/SQL New Features

207 The DBMS_WARNING Procedures: Syntax, Parameters, and Allowed Values
EXECUTE DBMS_WARNING.ADD_WARNING_SETTING_CAT (- warning_category IN VARCHAR2, warning_value IN VARCHAR2, scope IN VARCAHR2); EXECUTE DBMS_WARNING.ADD_WARNING_SETTING_NUM (- warning_number IN NUMBER, warning_value IN VARCHAR2, scope IN VARCAHR2); EXECUTE DBMS_WARNING.SET_WARNING_SETTING_STRING (- warning_value IN VARCHAR2, scope IN VARCHAR2); The DBMS_WARNING Procedures: Syntax, Parameters, and Allowed Values warning_category is the name of the category. The allowed values are: ALL, INFORMATIONAL, SEVERE, or PERFORMANCE. warning_value is the value for the category. The allowed values are: ENABLE, DISABLE, or ERROR. warning_number is the warning message number. The allowed values are all valid warning numbers. scope specifies whether the changes are being performed in the session context or the system context. The allowed values are SESSION or SYSTEM. Using SYSTEM requires the ALTER SYTSTEM privilege. Oracle Database 10g: SQL and PL/SQL New Features

208 The DBMS_WARNING Procedures: Example
-- Establish the following warning setting string in the -- current session: -- ENABLE:INFORMATIONAL, -- DISABLE:PERFORMANCE, -- ENABLE:SEVERE EXECUTE DBMS_WARNING.SET_WARNING_SETTING_STRING(- 'ENABLE:ALL', 'SESSION'); EXECUTE DBMS_WARNING.ADD_WARNING_SETTING_CAT(- 'PERFORMANCE','DISABLE', 'SESSION'); Using DBMS_WARNING Procedures: Example Using the SET_WARNING_SETTING_STRING procedure, you can set one warning setting. If you have multiple warning settings, you should perform the following steps: 1. Call SET_WARNING_SETTING_STRING to set the initial warning setting string. 2. Call ADD_WARNING_SETTING_CAT (or ADD_WARNING_SETTING_NUM) repeatedly to add additional settings to the initial string. The example in the slide establishes the following warning setting string in the current session: ENABLE:INFORMATIONAL,DISABLE:PERFORMANCE,ENABLE:SEVERE Oracle Database 10g: SQL and PL/SQL New Features

209 The DBMS_WARNING Functions: Syntax, Parameters, and Allowed Values
DBMS_WARNING.GET_WARNING_SETTING_CAT (- warning_category IN VARCHAR2) RETURN warning_value; DBMS_WARNING.GET_WARNING_SETTING_NUM (- warning_number IN NUMBER) RETURN warning_value; DBMS_WARNING.GET_WARNING_SETTING_STRING RETURN pls_integer; The DBMS_WARNING Functions: Syntax, Parameters, and Allowed Values warning_category is the name of the category. The allowed values are: ALL, INFORMATIONAL, SEVERE, or PERFORMANCE. warning_number is the warning message number. The allowed values are all valid warning numbers. scope specifies whether the changes are being performed in the session context or the system context. The allowed values are SESSION or SYSTEM. Using SYSTEM requires the ALTER SYTSTEM privilege. Note: Use the GET_WARNING_SETTING_STRING function when you do not have the SELECT privilege on v$parameter or v$paramater2 fixed tables, or if you want to parse the warning string yourself and then modify and set the new value using SET_WARNING_SETTING_STRING. DBMS_WARNING.GET_CATEGORY (- warning_number IN pls_integer) RETURN VARCHAR2; Oracle Database 10g: SQL and PL/SQL New Features

210 The DBMS_WARNING Functions: Example
-- Determine the current session warning settings EXECUTE DBMS_OUTPUT.PUT_LINE( - DBMS_WARNING.GET_WARNING_SETTING_STRING); ENABLE:INFORMATIONAL,DISABLE:PERFORMANCE, ENABLE:SEVERE PL/SQL Procedure Successfully Completed. -- Determine the category for warning message number -- PLW-07203 EXECUTE DBMS_OUTPUT.PUT_LINE( - DBMS_WARNING.GET_CATEGORY(7203)); PERFORMANCE PL/SQL Procedure Successfully Completed. Note The message numbers must be specified as positive integers, because the data type for the GET_CATEGORY parameter is PLS_INTEGER (allowing positive integer values). Oracle Database 10g: SQL and PL/SQL New Features

211 Using DBMS_WARNING: Example
CREATE OR REPLACE PROCEDURE compile_code(pkg_name VARCHAR2) IS warn_value VARCHAR2(200); compile_stmt VARCHAR2(200) := 'ALTER PACKAGE '|| pkg_name ||' COMPILE'; BEGIN warn_value := DBMS_WARNING.GET_WARNING_SETTING_STRING; DBMS_OUTPUT.PUT_LINE('Current warning settings: '|| warn_value); DBMS_WARNING.ADD_WARNING_SETTING_CAT( 'PERFORMANCE', 'DISABLE', 'SESSION'); DBMS_OUTPUT.PUT_LINE('Modified warning settings: '|| DBMS_WARNING.GET_WARNING_SETTING_STRING); EXECUTE IMMEDIATE compile_stmt; DBMS_WARNING.SET_WARNING_SETTING_STRING(warn_value, 'SESSION'); DBMS_OUTPUT.PUT_LINE('Restored warning settings: '|| END; / Using DBMS_WARNING: Example Note: Before you run the code provided in the example in the slide, you must create the MY_PKG script found in the demo_07_33.sql. This demo script creates the MY_PKG package. In the example in the slide, the compile_code procedure is designed to compile a named PL/SQL package. The code suppresses the PERFORMANCE category warnings. The calling environment’s warning settings must be restored after the compilation is performed. The code does not know what the calling environment warning settings are; it uses the GET_WARNING_SETTING_STRING function to save the current setting. This value is used to restore the calling environment setting using the DBMS_WARNING.SET_WARNING_SETTING_STRING procedure in the last line of the example code. Before compiling the package using Native Dynamic SQL, the compile_code procedure alters the current session-warning level by disabling warnings for the PERFORMANCE category. The code also prints the original, modified, and the restored warning settings. Oracle Database 10g: SQL and PL/SQL New Features

212 Using DBMS_WARNING: Example
EXECUTE DBMS_WARNING.SET_WARNING_SETTING_STRING(- 'ENABLE:ALL', 'SESSION'); PL/SQL procedure successfully completed. @code07_33_s.sql Procedure created. @demo_07_33.sql – creates the MY_PKG package EXECUTE compile_code('MY_PKG'); Current warning settings: ENABLE:ALL Modified warning settings: ENABLE:INFORMATIONAL,DISABLE:PERFORMANCE,ENABLE:SEVERE Restored warning settings: ENABLE:ALL PL/SQL procedure successfully completed. Using DBMS_WARNING: Example (continued) In the example in the slide, the example provided in the previous slide is tested. First, enable all compiler warnings. Next, run the script on the previous page. Finally, call the compile_code procedure and pass it an existing package name, MY_PKG, as a parameter. Oracle Database 10g: SQL and PL/SQL New Features

213 Oracle Database 10g: SQL and PL/SQL New Features 1 - 214
Practice 7: Overview This practice covers the following topics: Displaying the compiler initialization parameters Enabling native compilation for your session and compiling a procedure Suppressing and enabling the compiler warnings and restoring the original session-warning settings Identifying the categories for some compiler-warning message numbers Practice 7: Overview In this practice, you display the compiler initialization parameters. You then enable native compilation for your session and compile a procedure. You then suppress all compiler warnings categories and then restore the original session-warning settings. Finally, you identify the categories for some compiler-warning message numbers. Oracle Database 10g: SQL and PL/SQL New Features

214 Programming with PL/SQL Enhancements

215 Oracle Database 10g: SQL and PL/SQL New Features 1 - 216
Objectives After completing this lesson, you should be able to: Describe and use conditional compilation Hide PL/SQL source code using dynamic obfuscation Use bulk-bind enhancements for applications Minimize invalidations to dependent PL/SQL program units and views when redefining table synonyms Oracle Database 10g: SQL and PL/SQL New Features

216 Oracle Database 10g: SQL and PL/SQL New Features 1 - 217
Lesson Agenda Using conditional compilation Obfuscating PL/SQL code Using bulk binding Using synonym repointing to reduce cascading invalidation Oracle Database 10g: SQL and PL/SQL New Features

217 What Is Conditional Compilation?
Enables you to customize the functionality in a PL/SQL application without removing any source code: Utilize the latest functionality with the latest database release or disable the new features to run the application against an older release of the database. Activate debugging or tracing functionality in the development environment and hide that functionality in the application while it runs at a production site. $IF, $THEN, $ELSE, $ELSIF, $END, $$, $ERROR What Is Conditional Compilation? Conditional compilation enables you to selectively include code, depending on the values of the conditions evaluated during compilation. For example, conditional compilation enables you to determine which PL/SQL features in a PL/SQL application are used for specific database releases. The latest PL/SQL features in an application can be run on a new database release and at the same time those features can be conditional so that the same application is compatible with a previous database release. Conditional compilation is also useful when you want to execute debugging procedures in a development environment, but want to turn off the debugging routines in a production environment. Benefits of Conditional Compilation Support for multiple versions of the same program in one source code Easy maintenance and debugging of code Easy migration of code to a different release of the database Reserved preprocessor control tokens Oracle Database 10g: SQL and PL/SQL New Features

218 How Does Conditional Compilation Work?
Selection directives: Use the $IF token. Inquiry directives: Use the $$ token. Error directives: Use the $ERROR token. How Does Conditional Compilation Work? You can use conditional compilation by embedding directives in your PL/SQL source programs. When the PL/SQL program is submitted for compilation, a preprocessor evaluates these directives and selects parts of the program to be compiled. The selected program source is then handed off to the compiler for compilation. Inquiry directives use the $$ token to make inquiries about the compilation environment such as the value of a PL/SQL compiler initialization parameters PLSQL_CCFLAGS or PLSQL_OPTIMIZE_LEVEL for the unit being compiled. This directive can be used in conjunction with the conditional selection directive to select the parts of the program to compile. Selection directives can test inquiry directives or static package constants by using the $IF construct to branch sections of code for possible compilation if a condition is satisfied. Error directives issue a compilation error if an unexpected condition is encountered during conditional compilation using the $ERROR token. The DBMS_DB_VERSION package provides database version and release constants that can be used for conditional compilation. The DBMS_PREPROCESSOR package provides subprograms for accessing the postprocessed source text that is selected by conditional compilation directives in a PL/SQL unit. DBMS_PREPROCESSOR package DBMS_DB_VERSION package Oracle Database 10g: SQL and PL/SQL New Features

219 Using Selection Directives
$IF <Boolean-expression> $THEN Text $ELSEIF <Boolean-expression> $THEN Text . . . $ELSE Text $END DECLARE CURSOR cur IS SELECT employee_id FROM employees WHERE $IF myapp_tax_package.new_tax_code $THEN salary > 20000; $ELSE salary > 50000; $END BEGIN OPEN cur; . . . END; Using Selection Directives The conditional selection directive looks like and operates like the IF-THEN-ELSE mechanism in PL/SQL proper. When the preprocessor encounters $THEN, it verifies that the text between $IF and $THEN is a static expression. If the check succeeds and the result of the evaluation is TRUE, then the PL/SQL program text between $THEN and $ELSE (or $ELSIF) is selected for compilation. The selection condition (the expression between $IF and $THEN) can be constructed by referring to constants defined in another package or an inquiry directive or some combination of the two. In the example in the slide, conditional selection directive chooses between two versions of the cursor, cur, on the basis of the value of MYAPP_TAX_PACKAGE.NEW_TAX_CODE. If the value is TRUE, then employees with salary > are selected, else employees with salary > are selected. Oracle Database 10g: SQL and PL/SQL New Features

220 Using Predefined and User-Defined Inquiry Directives
PLSQL_CCFLAGS PLSQL_CODE_TYPE PLSQL_DEBUG PLSQL_OPTIMIZE_LEVEL PLSQL_WARNINGS NLS_LENGTH_SEMANTICS PLSQL_LINE PLSQL_UNIT Predefined inquiry directives PLSQL_CCFLAGS = 'plsql_ccflags:true,debug:true,debug:0'; Using Predefined and User-Defined Inquiry Directives An inquiry directive can be predefined or be user-defined. The following describes the order of the processing flow when conditional compilation attempts to resolve an inquiry directive: The ID is used as an inquiry directive in the form $$id for the search key. 2. The two-pass algorithm proceeds as follows: a. The string in the PLSQL_CCFLAGS initialization parameter is scanned from right to left, searching with ID for a matching name (case insensitive); done if found. b. The predefined inquiry directives are searched; done if found. 3. If the $$ID cannot be resolved to a value, then the PLW-6003 warning message is reported if the source text is not wrapped. The literal NULL is substituted as the value for undefined inquiry directives. Note that if the PL/SQL code is wrapped, then the warning message is disabled so that the undefined inquiry directive is not revealed. In the example in the slide, the value of $$debug is 0 and the value of $$plsql_ccflags is TRUE. Note that the value of $$plsql_ccflags resolves to the user-defined plsql_ccflags inside the value of the PLSQL_CCFLAGS compiler parameter. This occurs because a user-defined directive overrides the predefined one. User-defined inquiry directives Oracle Database 10g: SQL and PL/SQL New Features

221 The PLSQL_CCFLAGS Parameter and the Inquiry Directive
Use the PLSQL_CCFLAGS parameter to control conditional compilation of each PL/SQL library unit independently. PLSQL_CCFLAGS = '<v1>:<c1>,<v2>:<c2>,...,<vn>:<cn>' ALTER SESSION SET PLSQL_CCFLAGS = 'plsql_ccflags:true, debug:true, debug:0'; The PLSQL_CCFLAGS Parameter and the Inquiry Directive Oracle Database 10g Release 2 introduces a new Oracle initialization parameter PLSQL_CCFLAGS for use with conditional compilation. This dynamic parameter enables you to set up name value pairs. The names (called flag names) can then be referenced in inquiry directives. PLSQL_CCFLAGS provides a mechanism that allows PL/SQL programmers to control conditional compilation of each PL/SQL library unit independently. Values vi: Has the form of an unquoted PL/SQL identifier. It is unrestricted and can be a reserved word or a keyword. The text is case insensitive. Each one is known as a flag or flag name. Each vi can occur more than once in the string, each occurrence can have a different flag value, and the flag values can be of different kinds. ci: Can be any of the following: A PL/SQL Boolean literal A PLS_INTEGER literal The literal NULL (default). The text is insensitive to case. Each one is known as a flag value and corresponds to a flag name. PLSQL_CCFLAGS initialization parameter Inquiry directive Oracle Database 10g: SQL and PL/SQL New Features

222 Displaying the PLSQL_CCFLAGS Initialization Parameter Setting
SELECT name, type, plsql_ccflags FROM user_plsql_object_settings NAME TYPE PLSQL_CCFLAGS SECURE_DML PROCEDURE SECURE_EMPLOYEES TRIGGER ADD_JOB_HISTORY PROCEDURE UPDATE_JOB_HISTORY TRIGGER MY_DEBUG PACKAGE plsql_ccflags:true, debug:true,debug:0 MY_PROC PROCEDURE plsql_ccflags:true, debug:true, debug:0 MY_PROC PROCEDURE plsql_ccflags:true, Displaying the PLSQL_CCFLAGS Initialization Parameter Setting Use the USER|ALL|DBA_PLSQL_OBJECTS data dictionary views to display the settings for a PL/SQL object. You can define any allowable value for PLSQL_CCFLAGS. However, Oracle recommends that this parameter be used for controlling the conditional compilation of debugging or tracing code. The flag names can be set to any identifier, including reserved words and keywords. The values must be the literals TRUE, FALSE, or NULL, or a PLS_INTEGER literal. The flag names and values are not case sensitive. The PLSQL_CCFLAGS parameter is a PL/SQL compiler parameter (like other compiler parameters) and is stored with the PL/SQL program unit. Consequently, if the PL/SQL program gets recompiled later with the REUSE SETTINGS clause (example, ALTER PACKAGE …REUSE SETTINGS), then the same value of PLSQL_CCFLAGS is used for the recompilation. Because the PLSQL_CCFLAGS parameter can be set to a different value for each PL/SQL unit, it provides a convenient method for controlling conditional compilation on a per unit basis. Oracle Database 10g: SQL and PL/SQL New Features

223 The PLSQL_CCFLAGS Parameter and the Inquiry Directive: Example
ALTER SESSION SET PLSQL_CCFLAGS = 'Tracing:true'; CREATE OR REPLACE PROCEDURE P IS BEGIN $IF $$TRACING $THEN DBMS_OUTPUT.PUT_LINE ('TRACING'); $END END P; Session altered. Procedure created. SELECT name, plsql_ccflags FROM USER_PLSQL_OBJECT_SETTINGS WHERE name = 'P'; NAME PLSQL_CCFLAGS P Tracing:true The PLSQL_CCFLAGS Parameter and the Inquiry Directive: Example In the example in the slide, the parameter is set and then the procedure is created. The setting is stored with each PL/SQL unit. Oracle Database 10g: SQL and PL/SQL New Features

224 Oracle Database 10g: SQL and PL/SQL New Features 1 - 225
Using Conditional Compilation Error Directives to Raise User-Defined Errors $ERROR varchar2_static_expression $END ALTER SESSION SET Plsql_CCFlags = ' Trace_Level:3 ' / CREATE PROCEDURE P IS BEGIN $IF $$Trace_Level = 0 $THEN ...; $ELSIF $$Trace_Level = 1 $THEN ...; $ELSIF $$Trace_Level = 2 $THEN ...; $else $error 'Bad: '||$$Trace_Level $END $END END P; / SHOW ERRORS Errors for PROCEDURE P: LINE/COL ERROR 6/ PLS-00179: $ERROR: Bad: 3 Using Conditional Compilation Error Directives to Raise User-Defined Errors The $ERROR error directive raises a user-defined error and is of the form: $ERROR varchar2_static_expression $END Note: varchar2_static_expression must be a VARCHAR2 static expression. Oracle Database 10g: SQL and PL/SQL New Features

225 Using Static Expressions with Conditional Compilation
Boolean static expressions: TRUE, FALSE, NULL, IS NULL, IS NOT NULL > , < , >= , <= , = , <>, NOT, AND, OR PLS_INTEGER static expressions: to , NULL VARCHAR2 static expressions include: ||, NULL, TO_CHAR Static constants: static_constant CONSTANT datatype := static_expression; Using Static Expressions with Conditional Compilation As described earlier, a preprocessor processes conditional directives before proper compilation begins. Consequently, only expressions that can be fully evaluated at compile time are permitted in conditional compilation directives. Any expression that contains references to variables or functions that require the execution of the PL/SQL are not available during compilation and cannot be evaluated. This subset of PL/SQL expressions allowed in conditional compilation directives is referred to as static expressions. Static expressions are carefully defined to guarantee that if a unit is automatically recompiled without any changes to the values it depends on, the expressions evaluate in the same way and the same source is compiled. Generally, static expressions are composed from three sources: Inquiry directives marked with $$ Constants defined in PL/SQL packages such as DBMS_DB_VERSION. These values can be combined and compared using the ordinary operations of PL/SQL. Literals such as TRUE, FALSE, 'CA', 123, NULL Static expressions can also contain operations that include comparisons, logical Boolean operations (such as OR and AND), or concatenations of static character expression. Oracle Database 10g: SQL and PL/SQL New Features

226 The DBMS_DB_VERSION Package: Boolean Constants
VER_LE_9 VER_LE_9_1 VER_LE_9_2 VER_LE_10 VER_LE_10_1 VER_LE_10_2 TRUE? DBMS_DB_VERSION Package DBMS_DB_VERSION Boolean constants The DBMS_DB_VERSION Package Oracle Database 10g Release 2 introduces the DBMS_DB_VERSION package. This package specifies the Oracle database version and release numbers that are useful when making simple selections for conditional compilation. The constants represent a Boolean condition that evaluates to less than or equal to the version and the release, if present. Example VER_LE_10 indicates that the database version <= 10. The values of the constants are either TRUE or FALSE. For example, in an Oracle Database 10g Release 2 database, VER_LE_10 and VER_LE_10_2 are TRUE and all other constants are FALSE. Oracle 10g Release 2 Oracle Database 10g: SQL and PL/SQL New Features

227 Using Conditional Compilation with Database Versions: Example
ALTER SESSION SET PLSQL_CCFLAGS = 'my_debug:FALSE, my_tracing:FALSE'; CREATE PACKAGE my_pkg AS SUBTYPE my_real IS -- Check the database version, if >= 10g, use BINARY_DOUBLE data type, -- else use NUMBER data type $IF DBMS_DB_VERSION.VERSION < 10 $THEN NUMBER; $ELSE BINARY_DOUBLE; $END my_pi my_real; my_e my_real; END my_pkg; / CREATE PACKAGE BODY my_pkg AS BEGIN $IF DBMS_DB_VERSION.VERSION < 10 $THEN my_pi := ; my_e := ; $ELSE my_pi := d; my_e := d; Using Conditional Compilation with Database Versions: Example This example also shows the use of the PLSQL_CCFLAGS parameter. First, you set the PLSQL_CCFLAGS parameter flag for displaying debugging code and tracing information. In the example in the slide on this page and the next page, conditional compilation is used to specify code for database versions. Conditional compilation is used to determine whether the BINARY_DOUBLE data type can be utilized in the calculations for PL/SQL units in the database. The BINARY_DOUBLE data type can only be used in Oracle Database 10g or later. If you are using Oracle Database 10g, then the data type for my_real is BINARY_DOUBLE; otherwise, the data type for my_real is NUMBER. In the specification of the new package, my_pkg, conditional compilation is used to check for the database version. In the body definition of the package, conditional compilation is used again to set the values of my_pi and my_e for future calculations based on the database version. Oracle Database 10g: SQL and PL/SQL New Features

228 Using Conditional Compilation with Database Versions: Example
CREATE OR REPLACE PROCEDURE circle_area(radius my_pkg.my_real) IS my_area my_pkg.my_real; my_datatype VARCHAR2(30); BEGIN my_area := my_pkg.my_pi * radius; DBMS_OUTPUT.PUT_LINE('Radius: ' || TO_CHAR(radius) || ' Area: ' || TO_CHAR(my_area) ); $IF $$my_debug $THEN -- if my_debug is TRUE, run some debugging code SELECT DATA_TYPE INTO my_datatype FROM USER_ARGUMENTS WHERE OBJECT_NAME = 'CIRCLE_AREA' AND ARGUMENT_NAME = 'RADIUS'; DBMS_OUTPUT.PUT_LINE('Datatype of the RADIUS argument is: ' || my_datatype); $END END; / Using Conditional Compilation with Database Versions: Example (continued) In the example in the slide, a new procedure called circle_area is defined. This procedure calculates the area of a circle based on the values of the variables in the my_pkg package defined on the previous page. The procedure has one IN formal parameter, radius. The procedure declares a couple of variables: my_area, which is the same data type as my_real in the my_pkg, and my_datatype, which is a VARCHAR2(30). In the procedure’s body, my_area becomes equal to the value of my_pi set in my_pkg multiplied by the value that is passed to the procedure as a radius. A message is printed displaying the radius and the area of the circle as shown in the second code example in the slide. Note: If you want to set my_debug to TRUE, you can make this change only for the circle_area procedure with the REUSE SETTINGS clause as follows: ALTER PROCEDURE circle_area COMPILE PLSQL_CCFLAGS = 'my_debug:TRUE' REUSE SETTINGS; CALL circle_area(50); -- Using Oracle Database 10g Release 2 Radius: 5.0E+001 Area: E+002 Call completed. Oracle Database 10g: SQL and PL/SQL New Features

229 Using DBMS_PREPROCESSOR Procedures to Print or Retrieve Source Text
CALL DBMS_PREPROCESSOR.PRINT_POST_PROCESSED_SOURCE('PACKAGE', 'HR', 'MY_PKG'); PACKAGE my_pkg AS SUBTYPE my_real IS BINARY_DOUBLE; my_pi my_real; my_e my_real; END my_pkg; Call completed. Using DBMS_PREPROCESSOR Procedures to Print or Retrieve Source Text DBMS_PREPROCESSOR subprograms print or retrieve the postprocessed source text of a PL/SQL unit after processing the conditional compilation directives. This postprocessed text is the actual source used to compile a valid PL/SQL unit. The example in the slide shows how to print the postprocessed form of my_pkg using the PRINT_POST_PROCESSED_SOURCE procedure. When my_pkg is compiled on an Oracle Database 10g release or later database using the HR account, the output of the first example in the slide is shown in the example in the slide. The PRINT_POST_PROCESSED_SOURCE removes unselected text. The lines of code that are not included in the postprocessed text are removed. The arguments for the PRINT_POST_PROCESSED_SOURCE procedure are: object type, schema name, and object name. Note: For additional information about the DBMS_PREPROCESSOR package, see Oracle Database PL/SQL Packages and Types Reference 10g Release 2 (10.2) guide. Oracle Database 10g: SQL and PL/SQL New Features

230 Oracle Database 10g: SQL and PL/SQL New Features 1 - 231
Lesson Agenda Using conditional compilation Obfuscating PL/SQL code Using bulk binding Using synonym repointing to reduce cascading invalidation Oracle Database 10g: SQL and PL/SQL New Features

231 Oracle Database 10g: SQL and PL/SQL New Features 1 - 232
What Is Obfuscation? Obfuscation (or wrapping) of a PL/SQL unit is the process of hiding the PL/SQL source code. Wrapping can be done with the wrap utility and DBMS_DDL subprograms. The wrap utility is run from the command line and it processes an input SQL file, such as a SQL*Plus installation script. The DBMS_DDL subprograms wrap a single PL/SQL unit, such as a single CREATE PROCEDURE command, that has been generated dynamically. Note For additional information about obfuscation, see the Oracle Database PL/SQL User’s Guide and Reference 10g Release 2 (10.2) guide. Oracle Database 10g: SQL and PL/SQL New Features

232 The Benefits of Obfuscating
It prevents others from seeing your source code. Your source code is not visible through the USER_SOURCE, ALL_SOURCE, or DBA_SOURCE data dictionary views. SQL*Plus can process the obfuscated source files. The Import and Export utilities accept wrapped files. Oracle Database 10g: SQL and PL/SQL New Features

233 What’s New in Dynamic Obfuscating in Oracle 10g
Provides the same functionality as the CREATE_WRAPPED procedure but allows for larger inputs DBMS_DDL.WRAP function DBMS_DDL package Wraps the text and creates the PL/SQL unit What’s New in Dynamic Obfuscating in Oracle 10g The CREATE_WRAPPED Procedure It takes as input a single CREATE OR REPLACE statement that specifies creation of a PL/SQL package specification, package body, function, procedure, type specification, or type body, generates a CREATE OR REPLACE statement with the PL/SQL source text obfuscated, and executes the generated statement. The WRAP Function It takes as input a CREATE OR REPLACE statement that specifies creation of a PL/SQL package specification, package body, function, procedure, type specification, or type body and returns a CREATE OR REPLACE statement, where the text of the PL/SQL unit has been obfuscated. CREATE_WRAPPED procedure Oracle Database 10g: SQL and PL/SQL New Features

234 Nonobfuscated PL/SQL Code: Example
BEGIN -- The ALL_SOURCE view family shows source code EXECUTE IMMEDIATE q'{ CREATE OR REPLACE PROCEDURE P1 IS BEGIN DBMS_OUTPUT.PUT_LINE (q'[I'm not wrapped]'); END P1; }'; END; CALL p1(); PL/SQL procedure successfully completed. I'm not wrapped Call completed. SELECT text FROM user_source WHERE name = 'P1' ORDER BY line; TEXT PROCEDURE P1 IS BEGIN DBMS_OUTPUT.PUT_LINE (q'[I'm not wrapped]'); END P1; Nonobfuscated PL/SQL Code: Example In the first example in the slide, the EXECUTE IMMEDIATE statement is used to create the procedure P1. The code in the created procedure is not wrapped. The code is not hidden when you use any of the views from the ALL_SOURCE view family to display the procedure’s code as shown in the slide. Note: The q quote operator is used in the example in the slide. It eliminates the need to use escape characters for single quotation marks in text literals. The value used in the example in the slide is the paired “[ ]”. Oracle Database 10g: SQL and PL/SQL New Features

235 Obfuscated PL/SQL Code: Example
BEGIN -- ALL_SOURCE view family obfuscates source code DBMS_DDL.CREATE_WRAPPED ( q'{ CREATE OR REPLACE PROCEDURE P1 IS BEGIN DBMS_OUTPUT.PUT_LINE (q'[I am wrapped now]'); END P1; }' ); END; CALL p1(); PL/SQL procedure successfully completed. I am wrapped now Call completed. SELECT text FROM user_source WHERE name = 'P1' ORDER BY line; TEXT PROCEDURE P1 wrapped a000000 b2 Abcd ... Obfuscated PL/SQL Code: Example In the example in the slide, the DBMS_DDL.CREATE_WRAPPED package procedure is used to create the procedure P1. The code is obfuscated when you use any of the views from the ALL_SOURCE view family to display the procedure’s code as shown on the next page. When you check the *_SOURCE views, the source is wrapped, or hidden, so that others cannot view the code details as shown in the output of the command in the slide. Oracle Database 10g: SQL and PL/SQL New Features

236 DBMS_DDL Versus Wrap Utility
Functionality DBMS_DLL Wrap Utility Code obfuscation Yes Dynamic Obfuscation No Obfuscate multiple programs at a time DBMS_DDL Versus Wrap Utility Both the wrap utility and the DBMS_DDL package have distinct uses: The wrap utility is useful for obfuscating multiple programs with one execution of the utility. In essence, a complete application may be wrapped. However, the wrap utility cannot be used to obfuscate dynamically generated code at run time. The wrap utility processes an input SQL file and obfuscates only the PL/SQL units in the file, such as: Package specification and body Function and procedure Type specification and body The wrap utility does not obfuscate PL/SQL content in: Anonymous blocks Triggers Non-PL/SQL code The DBMS_DDL package is intended to obfuscate a dynamically generated program unit from within another program unit. The DBMS_DDL package methods cannot obfuscate multiple program units at one execution. Each execution of these methods accepts only one CREATE OR REPLACE statement at a time as argument. Oracle Database 10g: SQL and PL/SQL New Features

237 Dynamic Obfuscation: Example
SET SERVEROUTPUT ON DECLARE code CONSTANT VARCHAR2(32767) := ' CREATE OR REPLACE PROCEDURE new_proc AS VDATE DATE; BEGIN VDATE := SYSDATE; DBMS_OUTPUT.PUT_LINE(VDATE) ; END; ' ; DBMS_DDL.CREATE_WRAPPED (CODE); END; / Dynamic Obfuscation: Example The example in the slide displays the creation of a dynamically obfuscated procedure called NEW_PROC. To verify that the code for NEW_PROC is obfuscated, you can query from the DBA|ALL|USER_SOURCE dictionary views as shown below: SELECT text FROM user_source WHERE name = 'NEW_PROC'; TEXT procedure new_proc wrapped a000000 2 abcd Oracle Database 10g: SQL and PL/SQL New Features

238 Oracle Database 10g: SQL and PL/SQL New Features 1 - 239
Lesson Agenda Using conditional compilation Obfuscating PL/SQL code Using bulk binding Using synonym repointing to reduce cascading invalidation Oracle Database 10g: SQL and PL/SQL New Features

239 Bulk Binding Binds whole arrays of values in a single operation, rather than using a loop to perform a FETCH, INSERT, UPDATE, and DELETE operation multiple times PL/SQL run-time engine SQL engine Procedural statement executor PL/SQL block FORALL j IN INSERT (id, dates) VALUES (ids(j), dates(j)); ... SQL statement executor Bulk Binding The Oracle server uses two engines to run PL/SQL blocks and subprograms: The PL/SQL run-time engine, which runs procedural statements but passes the SQL statements to the SQL engine The SQL engine, which parses and executes the SQL statement and, in some cases, returns data to the PL/SQL engine During execution, every SQL statement causes a context switch between the two engines, which results in a performance penalty for excessive amounts of SQL processing. This is typical of applications that have a SQL statement in a loop that uses values from indexed collections. Collections include nested tables, varying arrays, index-by tables, and host arrays. Performance can be substantially improved by minimizing the number of context switches through the use of bulk binding. Bulk binding causes an entire collection to be bound in one call, a context switch, to the SQL engine. That is, a bulk bind process passes the entire collection of values back and forth between the two engines in a single context switch, compared with incurring a context switch for each collection element in an iteration of a loop. The more rows affected by a SQL statement, the greater the performance gain with bulk binding. Oracle Database 10g: SQL and PL/SQL New Features

240 Using Bulk Binding: Syntax and Keywords
The FORALL keyword instructs the PL/SQL engine to bulk bind input collections before sending them to the SQL engine. The BULK COLLECT keyword instructs the SQL engine to bulk bind output collections before returning them to the PL/SQL engine. FORALL index IN lower_bound .. upper_bound [SAVE EXCEPTIONS] sql_statement; ... BULK COLLECT INTO collection_name[,collection_name] ... Using Bulk Binding Use bulk binds to improve the performance of: DML statements that reference collection elements SELECT statements that reference collection elements Cursor FOR loops that reference collections and the RETURNING INTO clause The FORALL keyword instructs the PL/SQL engine to bulk bind input collections before sending them to the SQL engine. Although the FORALL statement contains an iteration scheme, it is not a FOR loop. The BULK COLLECT keyword instructs the SQL engine to bulk bind output collections, before returning them to the PL/SQL engine. This enables you to bind locations into which SQL can return the retrieved values in bulk. Thus, you can use these keywords in the SELECT INTO, FETCH INTO, and RETURNING INTO clauses. The SAVE EXCEPTIONS keyword is optional. However, if some of the DML operations succeed and some fail, you would want to track or report on those that fail. Using the SAVE EXCEPTIONS keyword causes failed operations to be stored in a cursor attribute called %BULK_EXCEPTIONS, which is a collection of records indicating the bulk DML iteration number and corresponding error code. Oracle Database 10g: SQL and PL/SQL New Features

241 Bulk Binding FORALL: Example
CONNECT HR/HR CREATE PROCEDURE raise_salary(percent NUMBER) IS TYPE numlist IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; id numlist; BEGIN id(1):= 100; id(2):= 102; id(3):= 104; id(4) := 110; -- bulk-bind the PL/SQL table FORALL i IN id.FIRST .. id.LAST UPDATE employees SET salary = (1 + percent/100) * salary WHERE employee_id = id(i); END;/ Bulk Binding FORALL: Example Note: Before you can run the example in the slide, you must disable the update_job_history trigger as follows: ALTER TRIGGER update_job_history DISBALE; In the example in the slide, the PL/SQL block increases the salary for employees with IDs 100, 102, 104, or 110. It uses the FORALL keyword to bulk bind the collection. Without bulk binding, the PL/SQL block would have sent a SQL statement to the SQL engine for each employee record that is updated. If there are many employee records to update, then the large number of context switches between the PL/SQL engine and the SQL engine can affect performance. However, the FORALL keyword bulk binds the collection to improve performance. Note: A looping construct is no longer required when using this feature. EXECUTE raise_salary(10) PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

242 FORALL Support for Sparse Collections
-- The new INDICES OF syntax allows the bound arrays -- themselves to be sparse. FORALL index_name IN INDICES OF sparse_array_name BETWEEN LOWER_BOUND AND UPPER_BOUND -- optional SAVE EXCEPTIONS -- optional, but recommended INSERT INTO table_name VALUES sparse_array(index_name); -- The new VALUES OF syntax lets you indicate a subset -- of the binding arrays. FORALL index_name IN VALUES OF index_array_name SAVE EXCEPTIONS -- optional,but recommended INSERT INTO table_name VALUES binding_array_name(index_name); FORALL Support for Sparse Collections In earlier releases, PL/SQL did not allow sparse collections to be used with the FORALL statement. If SAVE EXCEPTIONS was not specified, the statement was terminated when the first deleted element was encountered. Even when SAVE EXCEPTION was used, the PL/SQL engine tried to iterate over all elements (existing and nonexisting). This substantially degraded the performance of the DML operation if the relative percentage of the deleted elements was high. In Oracle Database 10g, a new syntax has been introduced with the keyword INDICES to allow sparse collection to be used with the FORALL statement. This syntax binds sparse collections more efficiently. The new syntax also supports a more general approach where an index array can be specified to iterate over the collections. Using sparse collection and index arrays in bulk operations improves performance. You use the new INDICES OF and VALUES OF syntax with the FORALL statement. The bulk bind for sparse array syntax can be used in all DML syntaxes. In the syntax, the index array must be dense, and the binding arrays may be dense or sparse and the indicated elements must exist. Oracle Database 10g: SQL and PL/SQL New Features

243 Using Bulk Binds in Sparse Collections
The typical application for this feature is an order entry and order processing system where: Users enter orders through the Web Orders are placed in a staging table before validation Data is later validated based on complex business rules (usually implemented programmatically using PL/SQL) Invalid orders are separated from valid ones Valid orders are inserted into a permanent table for processing Using Bulk Binds in Sparse Collections This feature can be used in any application, which starts with a dense PL/SQL table of records or table of scalar that are populated using a bulk collect. This is used as the binding array. A dense array (pointer), whose elements denote the indices of the binding array, are made sparse based on the application logic. This pointer array is then be used in the FORALL statement to perform bulk DML with the binding arrays. Any exceptions encountered can be saved and further processed in the exception-handling section, perhaps by using another FORALL statement. Oracle Database 10g: SQL and PL/SQL New Features

244 Using Bulk Bind with Index Array
CREATE OR REPLACE PROCEDURE ins_emp2 AS TYPE emptab IS TABLE OF employees%ROWTYPE; v_emp emptab; TYPE values_of_tab_t IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER; v_num values_of_tab_t; BEGIN FORALL k IN VALUES OF v_num INSERT INTO new_employees VALUES v_emp(k); END; Using Bulk Bind with Index Array In Oracle Database 10g, you can use an index collection of PLS_INTEGER or BINARY_INTEGER (or one of its subtypes) whose values are the indexes of the collections involved in the bulk-bind DML operation using FORALL. These index collections can then be used in a FORALL statement to process bulk DML using the VALUES OF clause. In the example on the next page, V_NUM is a collection whose type is PLS_INTEGER. In the example, you are creating a procedure INS_EMP2, which identifies only one employee for each occurrence of the first letter of the last name. This procedure then inserts into the NEW_EMPLOYEES table created earlier using the FORALL..IN VALUES OF syntax. Oracle Database 10g: SQL and PL/SQL New Features

245 Oracle Database 10g: SQL and PL/SQL New Features 1 - 246
Lesson Agenda Using conditional compilation Obfuscating PL/SQL code Using bulk binding Using synonym repointing to reduce cascading invalidation Oracle Database 10g: SQL and PL/SQL New Features

246 Impact of Redefining Synonyms Before Oracle Database 10g
EMPLOYEES CREATE OR REPLACE SYNONYM emp_hist INVALID status Impact of Redefining Synonyms You can use synonyms to achieve data independence and location transparency. However, you must be careful when you reassign a synonym from one table to another. In many cases, this invalidates dependent objects such as PL/SQL program units, views, or object types. Before the introduction of this feature, when you redefined a synonym, the status of any dependent PL/SQL program unit was set to INVALID. If you did not recompile the PL/SQL program units manually, they would recompile automatically the next time they were invoked, causing run-time performance overhead. EMPLOYEES_HIST Oracle Database 10g: SQL and PL/SQL New Features

247 Changes to Synonym Dependencies in Oracle Database 10g
VALID status CREATE OR REPLACE SYNONYM Changes to Synonym Dependencies Oracle Database 10g minimizes down time during code upgrades or schema merges. When certain conditions on columns, privileges, partitions, and so on are met, a table or object type is considered equivalent and dependent objects are no longer invalidated. For detailed information, refer to the Oracle Database 10g: Maximize Availability - General Enhancements eStudy. In Oracle Database 10g, the CREATE OR REPLACE SYNONYM command has been enhanced to minimize the invalidations to dependent PL/SQL program units and views that reference it. This eliminates the need for time-consuming recompilation of the program units after redefinition of the synonyms or during execution. You do not have to set any parameters or issue any special commands to enable this functionality; invalidations are minimized automatically. Note: This enhancement applies only to synonyms pointing to tables. VALID status Oracle Database 10g: SQL and PL/SQL New Features

248 Oracle Database 10g: SQL and PL/SQL New Features 1 - 249
Maintaining Valid PL/SQL Program Units and Views in Oracle Database 10g EMPLOYEES CREATE OR REPLACE SYNONYM emp_hist Maintaining Valid PL/SQL Program Units You can change the definition of a synonym, and the dependent PL/SQL program units are not invalidated under the following conditions: The column order, column names, and column data types of the tables are identical. The privileges on the newly referenced table and its columns are a superset of the set of privileges on the original table. These privileges must not be derived through roles alone. The names and types of partitions and subpartitions are identical. The tables are of the same organization type. Object type columns are of the same type. Maintaining Valid Views As with dependent PL/SQL program units, you can change the definition of a synonym, and the dependent views are not invalidated under the conditions listed above. In addition, the following must be true to preserve the VALID status of dependent views, but not of dependent PL/SQL program units, when you redefine a synonym: Columns and order of columns defined for primary key and unique indexes, NOT NULL constraints, and primary key and unique constraints must be identical. The dependent view cannot have any referential constraints. VALID status EMPLOYEES_HIST Oracle Database 10g: SQL and PL/SQL New Features

249 Maintaining Valid Program Units: Example
CREATE OR REPLACE SYNONYM employees_syn FOR employees_hist; Create table EMPLOYEES_HIST. Create EMPLOYEES_SYN synonym for EMPLOYEES_HIST. Create PL/SQL procedure REMOVE_EMP that uses EMPLOYEES_SYN. Validate REMOVE_EMP. CREATE OR REPLACE SYNONYM employees_syn FOR employees_hist_new; Maintaining Valid Program Units: Example 1. Create a new table named EMPLOYEES_HIST: CREATE TABLE employees_hist AS SELECT * from hr.employees; Table created. 2. Create a synonym named EMPLOYEES_SYN for the EMPLOYEES_HIST table: CREATE OR REPLACE SYNONYM employees_syn FOR employees_hist; Synonym created. SELECT owner, synonym_name, table_owner, table_name FROM dba_synonyms WHERE synonym_name LIKE 'EMP%'; OWNER SYNONYM_NAME TABLE TABLE_NAM OE EMPLOYEES HR EMPLOYEES SYSTEM EMPLOYEES_SYN HR EMPLOYEES SYS EMPLOYEES_SYN SYS EMPLOYEES_HIST Redefine EMPLOYEES_SYN to reference EMPLOYEES_HIST_NEW and validate. Create table EMPLOYEES_HIST_NEW. Validate REMOVE_EMP. Oracle Database 10g: SQL and PL/SQL New Features

250 Oracle Database 10g: SQL and PL/SQL New Features 1 - 251
Summary In this lesson, you should have learned how to: Describe and use conditional compilation Hide PL/SQL source code using dynamic obfuscation Use bulk-bind enhancements for applications Minimize invalidations to dependent PL/SQL program units and views when redefining table synonyms Oracle Database 10g: SQL and PL/SQL New Features

251 Oracle Database 10g: SQL and PL/SQL New Features 1 - 252
Practice 8-1: Overview This practice covers the following topics: Creating a package and a procedure that uses conditional compilation Using the appropriate package to retrieve the postprocessed source text of the PL/SQL unit Obfuscating some PL/SQL code Replacing the regular loop PL/SQL code with the more efficient bulk-binding method by using the FORALL statement Practice 8-1: Overview In this practice, you run a script to create a package and a procedure that uses conditional compilation. In addition, you use the appropriate package to retrieve the postprocessed source text of the PL/SQL unit. You obfuscate some PL/SQL code. Finally, you replace the regular FOR loop in a PL/SQL code with the more efficient bulk-binding method by using the FORALL statement. Oracle Database 10g: SQL and PL/SQL New Features

252 Using the SQL MODEL Clause

253 Oracle Database 10g: SQL and PL/SQL New Features 1 - 254
Objectives After completing this lesson, you should be able to perform interrow calculations with the SQL MODEL clause Use symbolic and positional references to identify cells Use UPDATE, UPSERT, and UPSERT ALL options Describe FOR loop enhancements Write SQL statements with the MODEL clause by using incremental loops Include the analytic functions within the MODEL clause Objectives In this lesson, you learn about the SQL MODEL clause. With the SQL MODEL clause, you can treat a query result as a multidimensional array and then apply formulas on the array to calculate new values. The formulas can be sophisticated interdependent calculations. By integrating advanced calculations into the database, performance, scalability, and manageability are enhanced significantly when compared to external solutions. You can use these computations on relational tables as well as Oracle online analytical processing (OLAP) workspaces. Rather than copying data into separate applications or PC spreadsheets, users can keep their data within the Oracle environment. Oracle Database 10g: SQL and PL/SQL New Features

254 Integrating Interrow Calculations in SQL
Offer analytical capabilities Use the MODEL clause to integrate interrow functionality into the Oracle server Enhance SQL by directly providing spreadsheet-like computations Benefits Spreadsheets are a terrific personal productivity tool and can be used to build complex models. However, a significant scalability problem exists when the number of formulas and amount of data become large. Desktop spreadsheets have no access to the parallel processing abilities of advanced servers. In a collaborative enterprise setting with many spreadsheets, consolidation is difficult, and analyzing a business by querying multiple spreadsheets involves hard work. The Oracle server solves these problems by introducing spreadsheet-like array computations into SQL. You use the MODEL clause to integrate interrow functionality into the Oracle server. The MODEL clause enhances SQL by directly providing spreadsheet-like computations. Oracle Database 10g: SQL and PL/SQL New Features

255 Oracle Database 10g: SQL and PL/SQL New Features 1 - 256
The SQL MODEL Clause The MODEL clause offers the flexibility of: Symbolic cell addressing Symbolic array computation UPSERT and UPDATE per rule Looping constructs Ordered computations Reference models Automatic rule ordering Recursive model solving Materialized view support The SQL MODEL Clause Features With the SQL MODEL clause, you can perform interrow calculations within SQL. You can view the selected rows as a multidimensional array and randomly access cells within that array. Using the MODEL clause, you can specify a series of assignment statements (referred to as rules) that invoke calculations on individual cells and ranges of cells. These rules operate on the results of a query and do not update any database tables. You can use the SQL MODEL clause to perform spreadsheet computations directly in the SQL language. Oracle Database 10g: SQL and PL/SQL New Features

256 Partitions, Measures, and Dimensions
Logical blocks Facts such as sales Identify measure cells Country Year Sales Concepts and Terminology The MODEL clause defines a multidimensional array by mapping the columns of a query into three groups: partition, dimension, and measure columns. These elements perform the following tasks: Partitions define logical blocks of the result set in a way similar to the partitions of the analytic functions (described in the Data Warehousing Guide). Model formulas are applied to the cells of each partition. Measures are analogous to the measures of a fact table in a star schema. They typically contain numeric values such as sales units or cost. Each cell is accessed within its partition by specifying its full combination of dimensions. Dimensions identify each measure cell within a partition. These columns identify characteristics such as date, region, and product name. To create formulas on these multidimensional arrays, you define computation rules expressed in terms of the dimension values. The rules are flexible and concise, and can use s and FOR loops for maximum expressiveness. Product Oracle Database 10g: SQL and PL/SQL New Features

257 Oracle Database 10g: SQL and PL/SQL New Features 1 - 258
Learning the Concepts MODEL DIMENSION BY (prod, year) MEASURES (sales s) RULES UPSERT (s[ANY, 2000]=s[CV(prod), CV(year) - 1]*2, --Rule 1 s[vcr, 2002]=s[vcr, 2001]+s[vcr, 2000], Rule 2 s[dvd, 2002]=AVG(s)[CV (prod), year<2001]) --Rule 3 Concepts The figure shows the flow of processing within a simple MODEL clause. In this case, follow the data through a MODEL clause that includes three formulas. One of the formulas updates an existing value, whereas the other two create new values for a forecast. The figure shows that the rows of data retrieved by a query are fed into the MODEL clause and rearranged into an array. After the array is defined, formulas are applied one by one to the data. Finally, the data, including both its updated values and newly created values, is rearranged into row form and presented as the results of the query. Oracle Database 10g: SQL and PL/SQL New Features

258 Oracle Database 10g: SQL and PL/SQL New Features 1 - 259
Learning the Concepts Country Product Year Sales Partition Dimension Measure 1 Rules: sales('prod1', 2002) = sales('prod1', 2000) + sales('prod1', 2001) sales('prod2', 2002) = sales('prod2', 2000) + sales('prod2', 2001) 2 Output: COUNTRY PRODUCT YEAR SALES Partition Dimension Dimension Measure A prod A prod A prod A prod B prod B prod B prod B prod A prod A prod B prod B prod Concepts (continued) The figure shown gives a conceptual overview of the model feature using a hypothetical sales table. The table has columns for country, product, year, and sales amount. The figure has three parts. The first segment shows the concept of dividing the table into partition, dimension, and measure columns. The second segment shows two rules that forecast the value of Prod1 and Prod2 for the year 2002. The third part shows the output of a query applying the rules to such a table with hypothetical data. The first eight rows of output are of data retrieved from the database, whereas the last four rows of output shows rows that are calculated from rules. Note that the rules are applied within each partition. In the third segment, the first several rows are the original data. The outlined content is the new rule data results. Note that the MODEL clause does not update existing data in tables nor does it insert new data into tables. To change values in a table, the results of executing the MODEL clause must be supplied to an INSERT, UPDATE, or MERGE statement. 3 Oracle Database 10g: SQL and PL/SQL New Features

259 Reviewing the Sample Data
CREATE VIEW sales_view AS SELECT country_name country, prod_name prod, calendar_year year, SUM(amount_sold) sale, COUNT(amount_sold) cnt FROM sales, times, customers, countries, products WHERE sales.time_id = times.time_id AND sales.prod_id = products.prod_id AND sales.cust_id = customers.cust_id AND customers.country_id = countries.country_id GROUP BY country_name, prod_name, calendar_year; View created. SELECT COUNT(*) FROM sales_view; COUNT(*) 3219 Sample Data This sample data set is based on tables in the Sales History (sh) schema. The Sales History division tracks business statistics to facilitate business decisions. To format the data for the examples shown in this lesson, the SQL*Plus FORMAT command is used: COLUMN sales FORMAT Oracle Database 10g: SQL and PL/SQL New Features

260 Oracle Database 10g: SQL and PL/SQL New Features 1 - 261
MODEL Syntax: Example SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year, sales FROM sales_view WHERE country IN ('Italy','Japan') MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Bounce', 2002] = sales['Bounce', 2001] + sales['Bounce', 2000], sales['Y Box', 2002] = sales['Y Box', 2001], sales['2_Products', 2002] = sales['Bounce', 2002] + sales['Y Box', 2002]) ORDER BY country, prod, year; Basic MODEL Syntax: Example This statement partitions by country, so the formulas are applied to the data of one country at a time. Note that the data ends with 2001, so any rules defining values for 2002 or later inserts new cells in the output. The first rule defines the sales of Bounce in 2002 as the sum of sales in 2000 and The second rule defines the sales for Y Box in 2002 as being the same value as they were for The third rule defines a category called 2_Products, which is simply the sum of the 2002 Bounce and Y Box values. Note that the values for 2_Products are derived from the results of the first two rules, so those rules must be executed before the 2_Products rule. Results COUNTRY PROD YEAR SALES Italy _Products Italy Bounce Italy Y Box Japan _Products Japan Bounce Japan Y Box Oracle Database 10g: SQL and PL/SQL New Features

261 Oracle Database 10g: SQL and PL/SQL New Features 1 - 262
Cell References Must qualify all dimensions in the partition Consist of two types: Positional: A dimension is implied by its position in the DIMENSION BY clause. Symbolic: A dimension is qualified using a Boolean condition. MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Bounce', 2000] = 10 ) Cell References A reference to a cell must qualify all dimensions that are listed in the DIMENSION BY clause. You can use either a symbolic reference or a positional reference. In a positional reference, each value provided in the brackets is matched to the dimension in the equivalent position of the DIMENSION BY clause. When you use a symbolic reference, a single dimension value is qualified by a Boolean condition. You must include as many conditions inside the brackets as there are dimensions in the DIMENSION BY clause. A single condition can qualify only one dimension and must be any single-column predicate. You can use either single or multiple cell references. A single cell reference is qualified by using an equality predicate, d=<value>. References other than equality predicates are multiple cell references. The symbolic and positional references handle nulls differently. With a symbolic reference such as sales[prod=null, year=2000], this does not qualify any cell because NULL=NULL is never true. If you use the positional reference sales[null, 2000], this qualifies a cell where prod is null and year = 2000. The positional reference is a notation shortcut. Internally, it is interpreted as an equal predicate unless a value of null is present. If a null is present, it uses the IS NULL predicate. sales[prod = 'Bounce', year > 1999] = 10 Oracle Database 10g: SQL and PL/SQL New Features

262 Oracle Database 10g: SQL and PL/SQL New Features 1 - 263
Cell References Positional: Dimension implied by its position in the DIMENSION BY clause Allows inserts and updates Symbolic: Allows updates only sales['Bounce', 2000] = 10 sales[prod = 'Bounce', year > 1999] = 10 Cell References (continued) When you use the symbolic notation, updates to existing rows are allowed. This means that if the row representing the left of an assignment is present in the table, then the indicated cell is updated. With the positional notation, both updates to existing rows and the insertion of new rows can occur. If the row representing the left of an assignment is present in the table, then the indicated cell is updated; otherwise, it is inserted into the result set. Oracle Database 10g: SQL and PL/SQL New Features

263 Using Cell Reference: Example
Output: SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year, sales FROM sales_view WHERE country='Italy' MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Bounce', 2005] = 20 ) ORDER BY country, prod, year; 1 COUNTRY PROD YEAR SALES Italy Bounce Using Cell Reference: Example 1. If you want to create a forecast value of SALES for the Bounce product in the year 2005 in Italy and set it to 20, then you can use a formula in the SELECT statement that sets the year value to 2005 and thus creates a new cell in the array. 2. The SQL statement generates the result set shown. Note: If you want to create new cells, such as values for future years, then you must use positional references or FOR loops (discussed later in this lesson). Positional references permit both updates and inserts into the array. This is called the UPSERT process. Symbolic references do not perform inserts; they can perform updates only. 2 Oracle Database 10g: SQL and PL/SQL New Features

264 Oracle Database 10g: SQL and PL/SQL New Features 1 - 265
Range References Are references to a set of cells on the right of a rule, and apply an aggregate operation to that set Loop over existing rows MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES (sales['Bounce', 2005] = 100 + max(sales) ['Bounce', year BETWEEN 1998 AND 2002] ) Range References In the example shown, you want to forecast the sales of Bounce in Italy for the year 2005 to be 100 more than the maximum sales in the period 1998 to To do so, you must use the BETWEEN clause to specify multiple cells on the right of the formula, and these are aggregated to a single value with the MAX() function. IS ANY and ANY Predicates The IS ANY predicate can provide an open range on both the left and right of a rule, looping over all values of a dimension. sum(sales)[prod='Bounce', year IS ANY] -- symbolic sum(sales)['Bounce', 'ANY'] –- positional This sums up all years in the partition where the products are Bounce. Note: You can have any kind of Boolean expressions on dimension keys in cell references. Oracle Database 10g: SQL and PL/SQL New Features

265 The Complete Query: Example
Results: SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year, sales FROM sales_view WHERE country='Italy' MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Bounce', 2005] = 100 + max(sales) ['Bounce', year BETWEEN 1998 AND 2002] ) ORDER BY country, prod, year; Results The results of the sales of Bounce in Italy for the year 2005 being 100 more than the maximum sales in the period 1998–2002 are shown in the slide. COUNTRY PROD YEAR SALES Italy Bounce Oracle Database 10g: SQL and PL/SQL New Features

266 Oracle Database 10g: SQL and PL/SQL New Features 1 - 267
The CV()Function Returns the current value (CV) of a dimension from the left of an assignment Performs relative indexing with respect to the left sales['Bounce', year BETWEEN 1995 AND 2002] = sales['Mouse Pad', CV(year)] + 0.2 * sales['Y Box', CV(year)]) The CV() Function The CV()function is a very powerful tool used on the right side of formulas to copy the left-side specifications that refer to multiple cells. This allows for very compact and flexible multicell formulas. CV()allows for very flexible expressions. For instance, by subtracting from the CV(year)value, you can refer to other rows in the data set. If you have the expression CV(year) -2 in a cell reference, then you can access data pertaining to two consecutive years preceding the year of the date specified. Oracle Database 10g: SQL and PL/SQL New Features

267 The CV()Function: Example
Results: MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Bounce', year BETWEEN 1995 AND 2002] = sales['Mouse Pad', CV(year)] + 0.2 * sales['Y Box', CV(year)]) COUNTRY PROD YEAR SALES Italy Bounce Italy Bounce Italy Bounce The CV() Function: Example You can use it to update the sales values for Bounce in Italy for multiple years by using a formula where each year’s sales is the sum of Mouse Pad sales for that year and 20 percent of the Y Box sales for that year as shown in the slide above. Note that in the above results, you see values for the years 1999 through 2001 only, although any year in the range of 1995 through 2002 is accepted. This is because the table has data for only those years. The CV()function provides the current value of a DIMENSION BY key of the cell currently referenced on the left. When the left of the formula in the slide references the cells Bounce and 1999, the expression on the right resolves to: sales['Mouse Pad', 1999] * sales['Y Box', 1999] Similarly, when the left side references the cells Bounce and 2000, the expression on the right side evaluates to: sales['Mouse Pad', 2000] * sales['Y Box', 2000] The CV()function takes a dimension key as its argument. It is also possible to use CV() without any argument as in CV()and, in which case, positional referencing is implied. The above formula can also be written as: s['Bounce', year BETWEEN 1995 AND 2002] = s['Mouse Pad', CV()] * s['Y Box', CV()] CV()functions can be used only in the right-side cell references. Oracle Database 10g: SQL and PL/SQL New Features

268 Using the FOR Construct with IN List Operator
Without using a FOR construct to build a query: Using a FOR construct to express computations more concisely: RULES ( sales['Mouse Pad', 2005] = 1.3 * sales['Mouse Pad', 2001], sales['Bounce', 2005] = 1.3 * sales['Bounce', 2001], sales['Y Box', 2005] = 1.3 * sales['Y Box', 2001] ) 1 RULES (sales[FOR prod IN ('Mouse Pad', 'Bounce', 'Y Box'), 2005] = 1.3 * sales[CV(prod), 2001] ) 2 Using the FOR Construct The MODEL clause provides a FOR construct, which can be used inside formulas to express computations more concisely. The FOR construct is allowed on both sides of formulas. If the cell reference on the right has discrete values on each of the dimensions, then you may improve performance by using the FOR construct. When the FOR construct is evaluated, the process is called unfolding the FOR loop. There is a 10,000-rule limit in the MODEL clause. Depending on the type of expressions used in the FOR construct, the FOR construct may generate virtual rules during processing. These rules are counted toward the 10,000-rule limit imposed on models. For more details about rules and the FOR loop, refer to the Oracle Database 10g Release 2: Data Warehousing Guide (see chapter about SQL for Modeling). Oracle Database 10g: SQL and PL/SQL New Features

269 Using the FOR Construct with Incremental Values
SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year, sales FROM sales_view WHERE country='Italy' MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES ( sales['Mouse Pad', FOR year FROM 2005 TO 2012 INCREMENT 1] = 1.2 * sales[CV(prod), 2001] ) ORDER BY country, prod, year; Using the FOR Construct (continued) Use the example shown if you want to specify the projection sales values of mouse pad for the years 2005 to 2012 so that they are equal to 120% of the value in 2001. This kind of FOR construct can be used for dimensions of numeric, date, and datetime data types. The increment or decrement expression value should be numeric for numeric dimensions and can be numeric or interval for dimensions of date or datetime types. There are other methods of using the FOR construct, and they are described in detail in the Data Warehousing Guide. Results COUNTRY PROD YEAR SALES Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Italy Mouse Pad Oracle Database 10g: SQL and PL/SQL New Features

270 Using the FOR Construct with a Subquery
You can use a subquery to loop over a dimension with the FOR construct. Follow these guidelines: The subquery cannot be correlated. The subquery cannot be a query defined in the WITH clause. FOR loops may be unfolded at query plan creation or query execution. sales[FOR year IN (SELECT yr FROM time_tbl), FOR prod IN (SELECT product FROM prod_tbl)] Using the FOR Construct (continued) You can use a subquery within the FOR construct to loop over a dimension. This is useful for densification of data, such as a procedure that guarantees that all values of a dimension are represented in the output of a query. In the example shown, if the query on the TIME_TBL table returns 10 rows and the query on the PROD_TBL returns 100 rows, then 1,000 rules are generated. Evaluation of Formulas with FOR Loops FOR loops may be unfolded at either of the two stages of query processing: query plan creation or query execution. Query plan creation is the stage where certain rule references are resolved to create an efficient query execution plan. Query execution is the stage where all remaining unresolved references must be determined. When FOR loops are unfolded at query execution, the models can be larger and include more powerful rule expressions. Additionally, you can avoid the 10,000-rule limit by the careful construction of unfolding FOR loops. For more details about the rules for unfolding FOR loops, refer to the Oracle Database 10g Release 2: Data Warehousing Guide (see chapter about SQL for Modeling). Oracle Database 10g: SQL and PL/SQL New Features

271 Using Analytic Functions in the SQL MODEL Clause
SELECT country, year, quarter, sale, csum FROM sales_rollup_time MODEL DIMENSION BY (country, year, quarter) MEASURES (sale, gid, 0 csum) ( csum[any, any, any] = sum(sale) OVER (PARTITION BY country, decode(gid,0,year,null) ORDER BY year, quarter ROWS UNBOUNDED PRECEDING) ) ORDER BY country, gid, year, quarter; COUNTRY YEAR QUARTER SALE CSUM Japan Q Japan Q Japan Q ... Japan 20 rows selected. Using Analytic Functions in the SQL MODEL Clause You can use analytic functions in the right side of rules, as of Oracle Database 10g Release 2. The ability to use analytic functions adds expressive power and flexibility to the MODEL clause. The example in the slide combines an analytic function with the MODEL clause. First, you create a SALES_ROLLUP_TIME view that uses the GROUPING_ID() function to calculate an identifier for different levels of aggregations. Then you use the view in a query that calculates cumulative sum of sales at both the quarter and year levels. The syntax to create the view is as follows: CREATE OR REPLACE VIEW sales_rollup_time AS SELECT country_name country, calendar_year year, calendar_quarter_desc quarter, GROUPING_ID(calendar_year, calendar_quarter_desc) gid, SUM(amount_sold) sale, COUNT(amount_sold) cnt FROM sh.sales, sh.times, sh.customers, sh.countries WHERE sales.time_id = times.time_id AND sales.cust_id = customers.cust_id AND customers.country_id = countries.country_id AND Country_name ='Japan' GROUP BY country_name, calendar_year, ROLLUP(calendar_quarter_desc) ORDER BY gid, country, year, quarter; Oracle Database 10g: SQL and PL/SQL New Features

272 NULLs and Missing Values
The two types of undetermined values are: NULL in an existing cell Nondetermined value from a missing cell The positional reference s[NULL, NULL] qualifies a cell whose two dimension values are NULL. The missing values are treated as NULLs in direct cell references. The missing values are treated as nonexisting values in aggregates. The IS PRESENT predicate is used to distinguish an existing NULL from a missing value. NULLs and Missing Values There are two types of undetermined values: a NULL in an existing cell and a nondetermined value from a missing cell. A missing cell is one for which there was no corresponding input row (no matching combination of dimension values) from the query. By default, NULLs are treated as everywhere else in SQL except for positional references, such as s[null, null], which indicates a cell whose two-dimension values are null. Missing values are treated as NULLs in direct cell references and as nonexisting values in aggregates. With the IS PRESENT predicate, you can distinguish between an existing cell (a row returned in the query result) and a missing cell. Because NULL values cause many formulas to return nulls, it may be more useful for you to treat nulls and missing values as 0 values. In this way, nulls are not propagated through a set of calculations. You can use the IGNORE NAV option (NAV stands for nonavailable values) to default nulls and missing cells to the following values: 0 for numeric data Empty string for character/string data 01-JAN-2001 for date-type data NULL for all other data types Oracle Database 10g: SQL and PL/SQL New Features

273 NULLs and Missing Values
To influence the treatment of NULLs and missing values, use the following: The IS PRESENT predicate The PRESENTV function The PRESENTNNV function The IGNORE NAV clause The KEEP NAV clause Available only within the MODEL clause SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year FROM sales_view WHERE country='Italy' MODEL PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) ( sales['Bounce', 2001] = CASE WHEN sales['Bounce', 2000] IS PRESENT THEN sales['Bounce', 1999] ELSE END); Nulls and Missing Values (continued) The IS PRESENT predicate returns true if the row indicated by the cell reference existed before the execution of the MODEL clause. The query shown checks whether the row with ['Bounce', 2000] exists, and if so, it assigns sales of Bounce in 1999 to sales of Bounce in If sales of Bounce in 2000 is not present, then it assigns 0 to the sales of Bounce in 2001. The PRESENTV function works similarly to the IS PRESENT predicate. The function accepts three arguments, a cell, followed by two expressions. If the row containing the cell exists, then it returns the first expression; otherwise, it returns the second expression. sales['Bounce', 2001] = PRESENTV(sales['Bounce', 2000], sales['Bounce', 1999], 0) The PRESENTNNV (present and not null) function checks whether the cell is present and is not null. If the cell exists and is not null, then it is assigned the first expression; otherwise, the cell is assigned the second expression. sales['Bounce', 2001] = PRESENTNNV(sales['Bounce', 2000], sales['Bounce', 1999], 0) Oracle Database 10g: SQL and PL/SQL New Features

274 Using the UPDATE, UPSERT, and UPSERT ALL Options
Three choices for RULES behavior: UPDATE: Updates existing cells UPSERT: Updates existing cells and inserts new ones UPSERT ALL: Allows a broader set of ruled notation Example of UPDATE: SELECT country, prod, year, sales FROM sales_view MODEL PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) IGNORE NAV RULES UPDATE (sales[FOR prod IN('Bounce', 'Y Box'), 2002] = sales[CV(prod),2001] + sales[CV(prod), 2000] ); Using the UPDATE Option You can determine how cells in rules behave by choosing whether to have UPDATE, UPSERT, or UPSERT ALL semantics. By default, the rules in the MODEL clause have UPSERT semantics. You can change the default behavior by using the UPDATE or UPSERT ALL options. In the example shown in the illustration, the UPDATE option applies to all rules. The rule shown assigns a value to the cells for the products Bounce and Y Box in the year 2002 to the sum of sales in 2001 and 2000 for the current product—either Bounce or Y Box. If a cell does not exist, then no new cell is created. Oracle Database 10g: SQL and PL/SQL New Features

275 Using the UPDATE Option
This example uses the per-rule basis: SELECT country, prod, year, sales FROM sales_view MODEL PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) IGNORE NAV RULES UPDATE ( UPDATE sales['Bounce', 2002] = sales['Bounce', 2001] + sales['Bounce', 2000], UPSERT sales['Y Box', 2002] = sales['Y Box', 2001] + sales['Y Box', 2000], sales['Mouse Pad', 2002] = sales['Mouse Pad', 2001] + sales['Mouse Pad', 2000] ); Using the UPDATE Option (continued) You can specify the UPDATE option either at the MODEL clause or on a per-rule basis. If the UPDATE or UPSERT option is left off a rule, then the UPDATE OR UPSERT option specified at the clause level is used. If no option is specified at the clause level, then it defaults to the UPSERT behavior. In the example shown in the illustration, the UPDATE option is used in the assignment for Bounce for the year If a row with ['Bounce', 2002] does not exist, then the assignment is ignored. The default UPSERT option is used for Y Box for the year A row is either updated if it exists, or created if it does not exist. The rules using UPSERT require positional notation for the cell reference or they will not insert new cells, and the behavior matches that of UPDATE rules. Oracle Database 10g: SQL and PL/SQL New Features

276 Using the UPSERT and UPSERT ALL Options
Positional Upsert: UPSERT sales['Bounce', 2004] = 1.1 * sales['Bounce', 2002] Symbolic Upsert: Use the UPSERT option to update a cell that exists, or insert a new cell if it does not exist: UPSERT sales['Bounce', year = 2004] = 1.1 * sales['Bounce', 2002]; UPSERT and UPSERT ALL Options With the MODEL clause, you can update a cell that exists or insert a new cell. This is called “upsert” (update or insert). The UPSERT Option When you use the UPSERT option, a new cell is created corresponding to the one referenced on the left of the rule when the cell is missing, and the cell reference contains only positional references qualified by constants. For example, the rule shown in the graphic would not create any new cell because of the symbolic reference year = However, this would create a new cell for product Bounce for the year 2004 if that cell did not already exist UPSERT sales['Bounce', 2004] = 1.1 * sales['Bounce', 2002]; This would create a new cell for product Bounce for the year 2004 if that cell did not already exist. On a related note, new cells will not be created if any of the references is ANY. This is because ANY is a predicate that qualifies all dimensional values including NULL. If there is an ANY reference for a dimension d, then it means the same thing as the predicate (d IS NOT NULL OR d IS NULL). The UPSERT ALL Option This is available with Oracle Database 10g, Release 2. It allows you to specify a broader set of ruled notation to insert new cells. Oracle Database 10g: SQL and PL/SQL New Features

277 Understanding the Order of Evaluation of Rules
MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES AUTOMATIC ORDER ( sales['2_Products', 2002] = sales['Bounce', 2002] + sales['Y Box', 2002], sales['Bounce', 2002] = sales['Bounce', 2001] + sales['Bounce', 2000], sales['Y Box', 2002] = sales['Y Box', 2001] ) COUNTRY PROD YEAR SALES Italy _Products Italy Bounce Italy Y Box Japan _Products Japan Bounce Japan Y Box Order of Evaluation By default, formulas are evaluated in the order in which they appear in the MODEL clause. You can use the keyword SEQUENTIAL ORDER to make such an evaluation order explicit. SQL Models with sequential formula order of evaluation are called “Sequential Order” models. When you specify SEQUENTIAL ORDER, the Oracle server evaluates the rules in the order in which they appear. In this case, a cell can be assigned a value more than once. SEQUENTIAL ORDER is the default. When you specify AUTOMATIC ORDER, the Oracle server evaluates the rules based on their dependency order. In this case, a cell can be assigned a value only once. In the example shown, a model with three formulas creates new product values based on other products. To ensure that the formulas are executed in correct sequence so that no dependencies are missed, the AUTOMATIC ORDER keywords are used. This query returns the results for the newly created 2_Products product and calculates the values for Bounce and Y Box before 2_Products: You can force the specified order of evaluation by providing the SEQUENTIAL ORDER keyword in the RULES clause. Ordered Rule Evaluation This allows the specification of an ORDER BY clause for a rule so that the cells that qualify on the left of a rule are processed (that is, the rule is applied to them) in the specified order. Oracle Database 10g: SQL and PL/SQL New Features

278 Understanding the Order of Evaluation of Rules
SELECT SUBSTR(country,1,20) country, SUBSTR(prod,1,15) prod, year, sales FROM sales_view WHERE country IN ('Italy','Japan') MODEL RETURN UPDATED ROWS PARTITION BY (country) DIMENSION BY (prod, year) MEASURES (sale sales) RULES SEQUENTIAL ORDER ( sales['2_Products', 2002] = sales['Bounce', 2002] + sales['Y Box', 2002], sales['Bounce', 2002] = sales['Bounce', 2001] + sales['Bounce', 2000], sales['Y Box', 2002] = sales['Y Box', 2001] ) ORDER BY country, prod, year; Order of Evaluation (continued) This query uses sequential order and it should not calculate the values for Bounce and Y Box before 2_Products. Therefore, 2_Products is assigned null values. COUNTRY PROD YEAR SALES Italy _Products Italy Bounce Italy Y Box Japan _Products Japan Bounce Japan Y Box Oracle Database 10g: SQL and PL/SQL New Features

279 Nested Cell References
Only one level of nesting is supported. Nested references can appear on the right of a rule for sequential and automatic order models. In automatic order models, nested references can appear on the left side of rules with some restrictions. Nested references can appear on the left side of rules in sequential order models. Nested cell references must be single cell references; aggregates are not supported. Nested Cell References In addition to simple cell references, you can use nested cell references. Cell references providing dimension values can be used within a cell reference. Assume that BEST_YEAR is a measure. The following demonstrates a nested reference: sales[product='Bounce', year = best_year['Bounce', 2003]] Here, the nested cell reference best_year['Bounce', 2003] provides the value for the dimension key year and is used in the symbolic reference for year. The best_year and worst_year measures give, for each year (y) and product (p) combination, the year for which sales of product p were the highest or lowest. sales[product='Bounce', year = best_year['Bounce', 2003]] Oracle Database 10g: SQL and PL/SQL New Features

280 Oracle Database 10g: SQL and PL/SQL New Features 1 - 281
Reference Models Similar to VARRAY() and other lookup functions in Excel Very useful for looking up factors such as currency conversion and tax rates Guidelines: The query in a reference model cannot be correlated to any outer query. Reference models cannot be updated. Reference models cannot have a partition clause. There can be multiple reference models per query block; in which case, they must have different names. f() Reference Models In a single MODEL clause, you can reference multiple arrays with different dimensions. This is analogous to VARRAY()and other lookup functions in Excel and it enables you to relate models with different dimensionality. For more information, see the Oracle10g: Data Warehousing Guide, Release 2 (10.2) and Oracle Database 10g: SQL Reference, Release 2 (10.2) reference material. Oracle Database 10g: SQL and PL/SQL New Features

281 Oracle Database 10g: SQL and PL/SQL New Features 1 - 282
Reference Models Syntax: A reference model is created by the REFERENCE subclause of the MODEL clause. Reference models can be used only on the right side of formulas. Reference models have no rules. REFERENCE model_name ON (query) DIMENSION BY (cols) MEASURES (cols) [reference options] Reference Models (continued) Using reference models, you can relate objects of different dimensionality. Like a main SQL model, a reference model is defined over a query block and has the DIMENSION BY and MEASURE clauses to indicate its dimensions and measures, respectively. For example, you want to convert projected sales figures of different countries, each in their own currency, into the U.S. currency and show both figures. Oracle Database 10g: SQL and PL/SQL New Features

282 Oracle Database 10g: SQL and PL/SQL New Features 1 - 283
Reference Models SELECT country, year, sales, dollar_sales FROM sales_view GROUP BY country, year MODEL REFERENCE conv_ref ON (SELECT country, exchange_rate FROM dollar_conv_tbl) DIMENSION BY (country) MEASURES (exchange_rate) IGNORE NAV MAIN conversion DIMENSION BY (country, year) MEASURES (SUM(sale) sales, SUM(sale) dollar_sales) IGNORE NAV RULES -- assuming that sales in France grows by 2% (dollar_sales['France', 2003] = sales[CV(country), 2002] * 1.02 * conv_ref.exchange_rate['France'], -- assuming that sales in Poland grows by 5% dollar_sales['Poland', 2003] = sales['Poland', 2002] * 1.05 * exchange_rate['Poland'] ...- could have more code to show Canada and Brazil ); Reference Models (continued) The example is using a currency conversion table as a reference model: CREATE TABLE dollar_conv_tbl(country VARCHAR2(30), exchange_rate NUMBER); INSERT INTO dollar_conv_tbl VALUES('Poland', 0.25); INSERT INTO dollar_conv_tbl VALUES('France', 0.14); INSERT INTO dollar_conv_tbl VALUES('Canada', 0.75); INSERT INTO dollar_conv_tbl VALUES('Brazil', 0.13); ... Now, to convert the projected sales for 2003 to the U.S. dollar, you can use the dollar conversion table as a reference model. Oracle Database 10g: SQL and PL/SQL New Features

283 Oracle Database 10g: SQL and PL/SQL New Features 1 - 284
Reference Models Based on the previous example, your formulas are much more flexible if they could work with growth values that are looked up from a separate table of growth rates. Such a table could cover many years and countries. You can create such a table defined as: CREATE TABLE growth_rate( country VARCHAR2(30), year NUMBER, growth_rate NUMBER); INSERT INTO growth_rate VALUES('Poland', 2002, 2.5); INSERT INTO growth_rate VALUES('Poland', 2003, 5); INSERT INTO growth_rate VALUES('France', 2002, 3); INSERT INTO growth_rate VALUES('France', 2003, 2.5); INSERT INTO growth_rate VALUES('Canada', 2002, 2.5); INSERT INTO growth_rate VALUES('Canada', 2003, 3.2); INSERT INTO growth_rate VALUES('Brazil', 2002, 1.8); INSERT INTO growth_rate VALUES('Brazil', 2003, 2.8); Reference Models (continued) How to write a query that calculates sales for Poland, France, Canada, and Brazil, by applying the 2002 growth figures and converting the values to dollars, is shown on the next page. Oracle Database 10g: SQL and PL/SQL New Features

284 Oracle Database 10g: SQL and PL/SQL New Features 1 - 285
Cyclic Rules in Models A cyclic dependency spanning two rules: A self-cyclic rule: sales['Bounce', 2002] = 1.5 * sales['Y Box', 2002], sales['Y Box', 2002] = / sales['Bounce', 2002] sales['Bounce', 2002] = / sales['Bounce', 2002] Cyclic Rules in Models Rules can be specified in ways where one rule’s left side is referred to on the right side of that rule or some other rule. Whenever this happens, the rules have circular references (the rules are recursive). These rules have cyclic dependencies. A cyclic dependency can involve multiple rules. It could have the form “rule A depends on B and rule B depends on rule A.” Alternatively, you may find a self-cyclic “rule depending on itself” form. When rules have cyclic dependencies, the calculation is an endless loop. You can halt such calculations so that your models can complete their processing. The MODEL clause can deal with cyclic dependencies in two ways: You can specify that the MODEL clause should run its rules in SEQUENTIAL ORDER and repeat the rule calculations for a specific number of iterations. The MODEL clause checks for cyclic dependencies. If it finds any, and SEQUENTIAL ORDER is not specified, then it gives an error message. Oracle Database 10g: SQL and PL/SQL New Features

285 Cyclic References and Iterations
The ITERATE subclause is used to handle computations that do not have a convergence point. The ITERATE clause identifies how many iterations to perform. Iterative evaluation stops either after finishing the specified number of iterations or when the termination condition evaluates to TRUE, whichever comes first. You can access the current iteration number by using the system variable ITERATION_NUMBER. ITERATION_NUMBER starts at value 0 and is incremented after each iteration. By using PREVIOUS and ITERATION_NUMBER, you can construct complex termination conditions. ... MODEL DIMENSION BY (x) MEASURES (s) RULES UPDATE ITERATE(4) (... Cyclic References and Iterations Using the ITERATE option of the MODEL clause, you can evaluate formulas iteratively for a specified number of times. The number of iterations is specified as an argument to the ITERATE clause. ITERATE can be specified only for SEQUENTIAL ORDER models. Use iterative models to calculate models where the formulas are interdependent. The syntax of the ITERATE clause is: ITERATE (number_of_iterations) [ UNTIL (condition) ] The number_of_iterations argument to ITERATE clause is a positive integer constant. Optionally, you can specify an early termination condition to stop formula evaluation before reaching the maximum iteration. This condition is specified in the UNTIL subclause of ITERATE and is checked at the end of an iteration. Therefore, you always have at least one iteration when ITERATE is specified. In some cases, you may want the termination condition to be based on the change, across iterations, in the value of a cell. Oracle Database 10g provides a mechanism to specify such conditions by allowing you to access cell values as they existed before and after the current iteration in the UNTIL condition. Use the PREVIOUS function, which takes a single cell reference as argument and returns the measure value of the cell as it existed after the previous iteration. Oracle Database 10g: SQL and PL/SQL New Features

286 Cycles and Simultaneous Equations
CREATE TABLE ledger (account VARCHAR2(20), balance NUMBER(10,2)); 1 INSERT INTO ledger VALUES ('Salary', ); INSERT INTO ledger VALUES ('Capital_gains', 15000); INSERT INTO ledger VALUES ('Net', 0); INSERT INTO ledger VALUES ('Tax', 0); INSERT INTO ledger VALUES ('Interest', 0); 2 SELECT * FROM ledger MODEL IGNORE NAV DIMENSION BY (account) MEASURES (balance b) RULES ITERATE (100) ( b['Net'] = b['Salary'] - b['Interest'] - b['Tax'], b['Tax'] = (b['Salary'] - b['Interest']) * b['Capital_gains'] *0.28, b['Interest'] = b['Net'] * 0.30 ) 3 Cycles and Simultaneous Equations You want to do financial planning for a person who earns a salary of $100,000 and has a capital gain of $15,000. His net income is calculated as salary minus interest payments minus taxes. He pays tax-deductible interest on a loan. He also pays taxes at two rates: 28% for the salary income after interest expense is deducted, and 38% on capital gains. This person wants his interest expense to represent exactly 30% of his income. How can you calculate the taxes, interest expense, and the net income that results? All values of this scenario are stored in a table called LEDGER. 1. Create a table called LEDGER. 2. Insert rows into the LEDGER table. 3. Use the ITERATE option to have the calculations repeated as many times as desired. The first pass inserts the values stored in the LEDGER table onto the right side of the formulas and creates a new set of values for NET, TAX, and INTEREST. The second pass calculates a new set of values for NET, TAX, and INTEREST using the TAX and INTEREST values calculated in the previous pass. This cycle is repeated a total of 100 times. Oracle Database 10g: SQL and PL/SQL New Features

287 Cycles and Simultaneous Equations
Results: B ACCOUNT Salary 15000 Capital_gains Net Tax Interest Cycles and Simultaneous Equations (continued) The results are displayed for the query shown on the previous page. Oracle Database 10g: SQL and PL/SQL New Features

288 Materialized Views with a MODEL Clause
Materialized views with a MODEL clause can be refreshed only by using a complete refresh. Only a text-based rewrite is applied when a materialized view uses the MODEL clause. It is recommended that materialized views generally do not use the MODEL clause. Materialized Views with a MODEL Clause Materialized views with a MODEL clause can be refreshed only by using a complete refresh. Recommended Usage with Materialized Views It is anticipated that the SELECT query of the MODEL clause is an aggregation over a large set (millions of rows). The result may be a relatively small set (up to tens of thousands of rows). This result is partitioned into smaller sets (hundreds of rows), and those rows are subject to the MODEL clause where up to 80% of them are changed. Given this situation, materialized views can be used effectively if a self-recomputable model is needed. This enables you to store and recompute models, including simultaneous models. Use the materialized views scenarios where refresh is more important than rewrite. Oracle Database 10g: SQL and PL/SQL New Features

289 Oracle Database 10g: SQL and PL/SQL New Features 1 - 290
Summary In this lesson, you should have learned how to: Perform interrow calculations with the SQL MODEL clause Use symbolic and positional references to identify cells Write SQL statements with the MODEL clause using incremental loops Use UPDATE, UPSERT, and UPSERT ALL options Describe the FOR loop enhancements Include the analytic functions within the MODEL clause Summary In this lesson, you learned about the SQL MODEL clause. The SQL MODEL clause is a powerful enhancement that enables you to perform spreadsheet-like computations on relational data. Oracle Database 10g: SQL and PL/SQL New Features

290 Practice 9-1 Overview: Using the MODEL Clause
This practice covers the following topics: Using the MODEL clause to perform interrow calculations: Identifying positional cell references Using the CV() function Handling NULL values Practice 9-1 Overview: Using the MODEL Clause In this practice, you use the SH schema and write SQL SELECT statements that include the MODEL clause. Oracle Database 10g: SQL and PL/SQL New Features

291 Using SQL Enhancements for Data Warehousing

292 Oracle Database 10g: SQL and PL/SQL New Features 1 - 293
Objectives After completing this lesson, you should be able to: Write MERGE statements using: The MERGE syntax Conditional inserts and updates The new DELETE condition Using the time series enhancements: Densified data Period-to-period comparison on one time level Period-to-period comparison for multiple time levels Oracle Database 10g: SQL and PL/SQL New Features

293 Oracle Database 10g: SQL and PL/SQL New Features 1 - 294
Lesson Agenda Writing MERGE statements using the new capabilities Using the time series enhancements: Densified data Period-to-period comparison on one time level Period-to-period comparison for multiple time levels Oracle Database 10g: SQL and PL/SQL New Features

294 Review of the MERGE Statement
Provides the ability to conditionally update or insert data into a database table Performs an UPDATE if the row exists, and an INSERT if it is a new row Syntax: MERGE INTO table_name table_alias USING (table|view|sub_query) alias ON (join condition) WHEN MATCHED THEN UPDATE SET col1 = col_val1, col2 = col2_val WHEN NOT MATCHED THEN INSERT (column_list) VALUES (column_values); Review of the MERGE Statement The Oracle server supports the MERGE statement for INSERT, UPDATE, and DELETE operations. Using this statement, you can update, insert, or delete a row in a table conditionally, thus avoiding multiple data manipulation language (DML) statements. The decision whether to update, insert, or delete in the target table is based on a condition in the ON clause. The MERGE statement is suitable in a number of data warehousing applications. For example, in a data warehousing application you may need to work with data coming from multiple sources, some of which may be duplicates. With the MERGE statement, you can conditionally add or modify rows. Oracle Database 10g: SQL and PL/SQL New Features

295 Oracle Database 10g: SQL and PL/SQL New Features 1 - 296
Basic MERGE: Example MERGE INTO cust_archive ca USING customers c ON (ca.cust_id = c.cust_id) WHEN MATCHED THEN UPDATE SET ca.cust_first_name = c.cust_first_name, ca.cust_last_name = c.cust_last_name, ... ca.valid = c.valid WHEN NOT MATCHED THEN INSERT VALUES(c.cust_id, c.cust_first_name, c.cust_last_name, c.cust_gender, c.cust_year_of_birth, c.cust_marital_status, c.cust_street_address, c.cust_postal_code, c.cust_city, c.cust_city_id, c.cust_state_province, c.cust_state_province_id, c.country_id, c.cust_main_phone_number, c.cust_income_level, c.cust_credit_limit, c.cust_ , c.cust_total, c.cust_total_id, c.cust_src_id, c.cust_eff_from, c.cust_eff_to, c.cust_valid ); Basic MERGE: Example In the example shown, data is inserted or updated into the CUST_ARCHIVE table to match the data in the CUSTOMERS table. The CUST_ARCHIVE table is created as follows: CREATE TABLE cust_archive AS SELECT * FROM customers WHERE 1=2; The example above matches the CUST_ID in the CUST_ARCHIVE table to the CUST_ID in the CUSTOMERS table. If a match is found, the row in the CUST_ARCHIVE table is updated to match the row in the CUSTOMERS table. If the row is not found, it is inserted into the CUST_ARCHIVE table. The condition ca.cust_id = c.cust_id is evaluated. Because the CUST_ARCHIVE table is initially empty, the condition returns false—there are no matches. The logic falls into the WHEN NOT MATCHED clause, and the MERGE command inserts the rows of the CUSTOMERS table into the CUST_ARCHIVE table. If rows existed in the CUST_ARCHIVE table and customer IDs matched in both tables, then the existing rows in the CUST_ARCHIVE table would be updated to match the CUSTOMERS table. The results of the MERGE statement above are: 55500 rows merged. Oracle Database 10g: SQL and PL/SQL New Features

296 Oracle Database 10g: SQL and PL/SQL New Features 1 - 297
MERGE Improvements New conditional clauses and extensions to the standard MERGE statement An optional DELETE clause to the MERGE statement MERGE Improvements Oracle’s data warehousing extraction, transformation, and loading capabilities are improved with several MERGE enhancements. The MERGE statement has two new improvements that allow you to: Specify either the update operation or the insert operation, or both. These new conditional clauses and extensions to the standard MERGE statement make it easier to use and faster to execute: Optional UPDATE or INSERT clauses Conditional UPDATE for a MERGE Compile time recognition and evaluation of ON clause predicates Delete rows from the target table during the update operation with an optional DELETE clause Oracle Database 10g: SQL and PL/SQL New Features

297 Oracle Database 10g: SQL and PL/SQL New Features 1 - 298
MERGE Extensions With the MERGE extensions, you have the option to: Omit the UPDATE or INSERT clauses Allow conditional updates Recognize special ON conditions Perform conditional inserts Use the DELETE clause MERGE INTO cust_archive ca USING customers c ON (ca.cust_id = c.cust_id) WHEN MATCHED THEN UPDATE SET ca.cust_total = c.cust_total; Option to Omit UPDATE or INSERT Clauses You may want to have only UPDATE or INSERT operations on certain tables. To do so, you can omit the UPDATE or INSERT of a MERGE statement. For example, there may be a change to the source table that you want to MERGE into the destination table. If the CUSTOMERS table changes as follows: UPDATE customers SET cust_total = 'Excellent' WHERE cust_credit_limit > 10000; You may want to reflect the updated CUST_TOTAL values in the destination (CUST_ARCHIVE) table. In the example, the INSERT statement is omitted. You can have an INSERT statement present and omit the UPDATE statement too. However, because there is no WHERE clause, 55,000 rows are merged (which is the count of rows in the CUSTOMERS table). Oracle Database 10g: SQL and PL/SQL New Features

298 Allowing Conditional Updates
Use the WHERE clause to conditionally update: -- return environment back to original state ROLLBACK; MERGE INTO cust_archive ca USING customers c ON (ca.cust_id = c.cust_id) WHEN MATCHED THEN UPDATE SET ca.cust_total = c.cust_total WHERE c.cust_total = 'Excellent'; 4805 rows merged. Allowing Conditional Updates You can add a WHERE clause to the UPDATE operation to test a condition when it is desirable to skip the UPDATE operation. For example, when merging information into a customer archive table, you may want to add information on excellent customers. The statement shown in the slide includes a WHERE clause that causes the UPDATE statement to occur only for excellent customers. Oracle Database 10g: SQL and PL/SQL New Features

299 Using Conditional Updates
Create the sample tables and turn the timing on: CREATE TABLE c1 AS SELECT cust_id, cust_first_name, cust_last_name FROM customers; CREATE TABLE c2 AS SELECT cust_id, cust_first_name, cust_last_name FROM customers; SET TIMING ON Using Conditional Updates Using the conditional UPDATE, you can suppress all updates where the data has not changed. This minimizes the DML operations and associated REDO tasks and increases performance. The example shown is in an extreme case, using the two tables shown. The SQL*Plus SET TIMING command is turned on to show the differences in performance. In the following slides, these two tables are used for conditional updates to show the impact on efficiency. Oracle Database 10g: SQL and PL/SQL New Features

300 Using Conditional Updates
First example: conditional update is not used. MERGE INTO c1 USING c2 ON (c1.cust_id = c2.cust_id) WHEN MATCHED THEN UPDATE SET c1.cust_first_name = c2.cust_first_name, c1.cust_last_name = c2.cust_last_name WHEN NOT MATCHED THEN INSERT VALUES(c2.cust_id, c2.cust_first_name, c2.cust_last_name); 55500 rows merged. Elapsed: 00:00:22.91 -- return environment back to original state ROLLBACK; Using Conditional Updates (continued) This first example does not use conditional updates: 55,500 rows are updated so that first and last names of c1 are set to c2, taking over 22 seconds. On the next slide, conditional updates are used and you see significant performance improvements. Oracle Database 10g: SQL and PL/SQL New Features

301 Using Conditional Updates
Second example: conditional update is used. MERGE INTO c1 USING c2 ON (c1.cust_id = c2.cust_id) WHEN MATCHED THEN UPDATE SET c1.cust_first_name = c2.cust_first_name, c1.cust_last_name = c2.cust_last_name WHERE (c1.cust_first_name <> c2.cust_first_name OR c1.cust_last_name <> c2.cust_last_name) WHEN NOT MATCHED THEN INSERT VALUES(c2.cust_id, c2.cust_first_name, c2.cust_last_name); 0 rows merged. Elapsed: 00:00:04.93 ROLLBACK; Using Conditional Updates (continued) In the example shown in the slide, an optional WHERE clause is added to the UPDATE statement. The statement is checked to see whether there is a difference between the names in c1 and c2 tables. This results in no rows being merged. The elapsed time is much shorter because no DML operation is taking place and thus no REDO is generated. Oracle Database 10g: SQL and PL/SQL New Features

302 Using the DELETE Clause to Cleanse Data
MERGE INTO cust_archive ca USING customers c ON (ca.cust_id = c.cust_id) WHEN MATCHED THEN UPDATE SET ca.cust_total = c.cust_total WHERE c.cust_total = 'Excellent' DELETE WHERE (ca.cust_total = 'Customer total') WHEN NOT MATCHED THEN INSERT VALUES(c.cust_id, c.cust_first_name, c.cust_last_name, c.cust_gender, c.cust_year_of_birth, ... c.cust_valid ); 4805 rows merged. Cleanse Data with the DELETE Clause To cleanse the tables while populating or updating them, you can use the optional DELETE clause in the MERGE statement. The statement shown uses the DELETE clause to remove rows whose product status is obsolete while performing the UPDATE operation. This results in cleansing of the data in the destination tables. Oracle Database 10g: SQL and PL/SQL New Features

303 Oracle Database 10g: SQL and PL/SQL New Features 1 - 304
Lesson Agenda Writing MERGE statements using the new capabilities Using the time series enhancements: Densified data Period-to-period comparison on one time level Period-to-period comparison for multiple time levels Oracle Database 10g: SQL and PL/SQL New Features

304 Densifying Data with Partitioned Outer Joins
The new outer join syntax provides high performance and enables you to fill in the gaps in sparse data: Requirement Consistent set of dimension values To specify comparison calculations and format reports reliably, it is best to return a consistent set of dimension values in query results with “dense” data. Reality Sparse data Data is normally stored in a sparse form (that is nonevents, such as snowshoes sold in Florida, are not stored). Problem Current SQL lacking Complex and slow SQL is needed to add back rows for nonexistent cases into the query output. Introduction to Partitioned Outer Joins Data is normally stored in sparse form—that is, if no value exists for a given combination of dimensions, then no row exists in the fact table. However, some calculations and report formatting can be performed most easily when there is a row for each combination of dimensions. This is called dense data. Dense data returns a consistent number of rows for each group of dimensions, which makes it simple to use the SQL analytic functions with physical offsets such as LAG()and LEAD(). You can use a PARTITION OUTER JOIN clause to make sparse data dense. Oracle Database 10g: SQL and PL/SQL New Features

305 Densifying Data with Partitioned Outer Joins
Solution? You add a simple extension to the Outer Join syntax: Just add the phrase "PARTITION BY (...)" to the join clause. What does it do? It is similar to a regular outer join, except that the outer join is applied to each partition. Where to use it? It is most frequently used to replace missing values along the time dimension, but it can be useful for any dimension. Is it a standard? It is accepted by ANSI and ISO for SQL standard. Introduction to Partitioned Outer Joins (continued) To overcome the problem of sparsity, you can use a partitioned outer join to fill the gaps in a dimension. Such a join extends the conventional outer join syntax by applying the outer join to each logical partition defined in a query. The Oracle database logically partitions the rows in your query based on the expression that you specify in the PARTITION BY clause. The result of a partitioned outer join is a UNION of the outer joins of each of the groups in the logically partitioned table with the table on the other side of the join. Oracle Database 10g: SQL and PL/SQL New Features

306 Partitioned Outer Join Syntax
Two forms are available: SELECT select_expression FROM table_reference PARTITION BY (expr [, expr ]... ) RIGHT OUTER JOIN table_reference SELECT select_expression FROM table_reference LEFT OUTER JOIN table_reference PARTITION BY {expr [,expr ]...) Partitioned Outer Join Syntax You can use either of the two forms available to perform a partitioned outer join. Oracle Database 10g: SQL and PL/SQL New Features

307 Oracle Database 10g: SQL and PL/SQL New Features 1 - 308
Sparse Data Sample NAME YEAR WEEK SALES Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce 18 rows selected. Data is missing for weeks 25 and 26. Data is missing for weeks 26 and 28. Example of Sparse Data The query below produces the data shown in the slide. The query requests data for one product in a time range of 11 weeks in two different years. In this example, you would expect 22 rows of data (11 weeks each from two years) if the data were dense. However, you see only 18 rows because weeks 25 and 26 are missing in 2000, and weeks 26 and 28 are missing in 2001. SELECT SUBSTR(p.Prod_Name,1,15) Product_Name, t.Calendar_Year Year, t.Calendar_Week_Number Week, SUM(Amount_Sold) Sales FROM Sales s, Times t, Products p WHERE s.Time_id = t.Time_id AND s.Prod_id = p.Prod_id AND p.Prod_name IN ('Bounce') AND t.Calendar_Year IN (2000,2001) AND t.Calendar_Week_Number BETWEEN 20 AND 30 GROUP BY p.Prod_Name, t.Calendar_Year, t.Calendar_Week_Number ORDER BY week; Oracle Database 10g: SQL and PL/SQL New Features

308 Densifying Data: Example
SELECT Product_Name, t.Year, t.Week, sales, NVL(Sales,0) dense_sales FROM ( SELECT SUBSTR(p.Prod_Name,1,15) Product_Name, t.Calendar_Year Year, t.Calendar_Week_Number Week, SUM(Amount_Sold) Sales FROM Sales s, Times t, Products p WHERE s.Time_id = t.Time_id AND s.Prod_id = p.Prod_id AND p.Prod_name IN ('Bounce') AND t.Calendar_Year IN (2000,2001) AND t.Calendar_Week_Number BETWEEN 20 AND 30 GROUP BY p.Prod_Name, t.Calendar_Year, t.Calendar_Week_Number ) v PARTITION BY (v.Product_Name) RIGHT OUTER JOIN (SELECT DISTINCT Calendar_Week_Number Week, Calendar_Year Year FROM Times WHERE Calendar_Year in (2000, 2001) AND Calendar_Week_Number BETWEEN 20 AND 30 ) t ON (v.week = t.week AND v.Year = t.Year) ORDER BY t.year, t.week; Densifying Data: Example To fill in the gaps in the preceding sample data shown, you can use the partitioned outer join shown in the slide. You can take the sparse data of the query and perform a partitioned outer join with a dense set of time data. In the query shown in the slide, the original query is aliased as v and the data retrieved from the times table is aliased as t. Note that in the query above, a WHERE condition for weeks between 20 and 30 is placed in the inline view for the time dimension. This step reduces the number of rows handled by the outer join, thereby saving processing time. Oracle Database 10g: SQL and PL/SQL New Features

309 Densifying Data: Example
PRODUCT_NAME YEAR WEEK SALES DENSE_SALES Bounce Bounce Bounce ... Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce 22 rows selected. Densifying Data: Example (continued) Notice that partitioned outer join returns NULLs for nonpartitioning columns of the newly added rows (in this case, YEAR, WEEK, and DENSE_SALES). In this example, the NULLs for DENSE_SALES are replaced with 0 using the NVL function. However, your calculation requirement may be more demanding than replacing NULLs with 0. This is where the analytic functions (introduced in Oracle8i, release 2) and SQL MODEL clause (introduced in Oracle Database 10g) are useful. In the following examples, you learn how to use partitioned outer joins in combination with analytic functions to create even more powerful analytic queries. For details about analytic functions, refer to the Oracle Data Warehousing Guide. It is important to understand the LAST_VALUE and LAG functions and the sliding window concept for the material that follows. Oracle Database 10g: SQL and PL/SQL New Features

310 Repeating Data Values to Fill Gaps
The following is a sample INVENTORY table: Note Inventory tables are naturally sparse. A change in quantity results in a row. To make the time dimension dense in an inventory table, you need a quantity value for each day. The value to show is the most recent non-null number. TIME_ID PRODUCT QUANT 01-APR-01 bottle 06-APR-01 bottle 01-APR-01 can 04-APR-01 can Filling Gaps in an Inventory Table Inventory tables are naturally sparse. Similar to sales tables, they need to only store a row for a product when there is an event. For a sales table, the event is a sale and for the inventory table, the event is a change in quantity available for a product. There are two requirements to create dense data for an INVENTORY table: 1. The TIME dimension must be made dense. 2. The QUANT column should hold the most recent non-null value in the series. If you make the inventory’s time dimension dense, you want to see a quantity value for each day. The value to output is the most recent non-null value. A partitioned outer join can be used to satisfy the first requirement. However, a partitioned outer join alone is not sufficient to satisfy the second requirement too. The analytic functions can be used to satisfy the second requirement. Oracle Database 10g: SQL and PL/SQL New Features

311 Repeating Data Values to Fill Gaps
Use a partitioned outer join. Use the LAST_VALUE analytic function. WITH v1 AS (SELECT time_id FROM times WHERE times.time_id BETWEEN TO_DATE('01/04/01', 'DD/MM/YY') AND TO_DATE('07/04/01', 'DD/MM/YY')) SELECT product, time_id, quant quantity, LAST_VALUE(quant IGNORE NULLS) OVER (PARTITION BY product ORDER BY time_id) repeated_quantity FROM (SELECT product, v1.time_id, quant FROM inventory PARTITION BY (product) RIGHT OUTER JOIN v1 ON (v1.time_id = inventory.time_id)) ORDER BY 1, 2; 2 Filling Gaps in an Inventory Table (continued) The query shown in the slide performs the operations that are needed to densify the inventory data. The WITH clause is used to choose a one-week subset of the time dimension. Using the WITH clause, you define a query block before using it in the query. This enables you to reuse the same query block in a SELECT statement when it occurs more than once within a complex query. In step 1, the inner query computes a partitioned outer join on time within each product. The inner query densifies the data on the time dimension (that is, the query results will now show all the days for each product). However, the QUANTITY measure column will have NULLs for the newly added rows (see the output of the QUANTITY column in the output below). In step 2, the outer query computes the LAST_VALUE analytic function. The expression partitions the data by product and orders each partitioned data on the time dimension column (TIME_ID). For each row, the expression finds the last non-null value in its window (due to the IGNORE NULLS option). This function returns the desired output for the QUANTITY column. The results are shown in the next slide. 1 Oracle Database 10g: SQL and PL/SQL New Features

312 Repeating Data Values to Fill Gaps Results
The results from the query in the previous slide are: PRODUCT TIME_ID QUANTITY REPEATED_QUANTITY bottle APR bottle APR bottle APR bottle APR bottle APR bottle APR bottle APR can APR can APR can APR can APR can APR can APR can APR 14 rows selected. Oracle Database 10g: SQL and PL/SQL New Features

313 Computing Data Values to Fill Gaps
Use a partitioned outer join. Use the AVG analytic function. WITH v AS (SELECT p.prod_name, calendar_month_desc, SUM(quantity_sold) units, SUM(amount_sold) sales FROM sales s, products p, times t WHERE s.prod_id in (122, 136) AND calendar_year = 2000 AND t.time_id = s.time_id AND p.prod_id = s.prod_id GROUP BY p.prod_name, calendar_month_desc) SELECT v.prod_name, calendar_month_desc, units, sales, NVL(units, AVG(units) OVER (PARTITION BY v.prod_name)) AS computed_units, NVL(sales, AVG(sales) OVER (PARTITION BY v.prod_name)) AS computed_sales FROM (SELECT DISTINCT calendar_month_desc FROM times WHERE calendar_year = 2000) t LEFT OUTER JOIN v PARTITION BY (prod_name) USING (calendar_month_desc); 2 Computing Data Values to Fill Gaps Here is another example that combines a partitioned outer join with analytic functions. You may want to obtain the monthly totals for product IDs 122 and 136 (64 MB memory card and DVD-R discs) for the year For the months that are missing, you want to assume the sales to be the average of the other months when products were sold. This query can be computed by using the following two steps: 1. The inner query uses the partitioned outer join to fill in the missing months. 2. The outer query uses the AVG analytic function to compute average sales and units. The NVL function replaces the NULLs produced by the partitioned outer join with the AVG value computed using the analytic function. 1 Oracle Database 10g: SQL and PL/SQL New Features

314 Computing Data Values to Fill Gaps
PROD_NAME CALENDAR UNITS SALES COMPUTED_UNITS COMPUTED_SALES ... 64MB Memory Card 64MB Memory Card 64MB Memory Card 64MB Memory Card 64MB Memory Card 64MB Memory Card 64MB Memory Card 64MB Memory Card DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, DVD-R Discs, 24 rows selected. Computing Data Values to Fill Gaps (continued) These are the results from the partitioned outer join shown in the previous slide. The rows that are highlighted are the rows generated from the partitioned outer join for the missing months. Oracle Database 10g: SQL and PL/SQL New Features

315 Oracle Database 10g: SQL and PL/SQL New Features 1 - 316
Lesson Agenda Writing MERGE statements using the new capabilities Using the time series enhancements: Densified data Period-to-period comparison on one time level Period-to-period comparison for multiple time levels Oracle Database 10g: SQL and PL/SQL New Features

316 Time Series Calculations on Densified Data
SELECT Product_Name, t.Year, t.Week, Sales, NVL(Sales,0) Current_sales, SUM(Sales) OVER (PARTITION BY Product_Name, t.year ORDER BY t.week) AS Cumulative_sales FROM (SELECT SUBSTR(p.Prod_Name,1,15) Product_Name, t.Calendar_Year Year, t.Calendar_Week_Number Week, SUM(Amount_Sold) Sales FROM Sales s, Times t, Products p WHERE s.Time_id = t.Time_id AND s.Prod_id = p.Prod_id AND p.Prod_name IN ('Bounce') AND t.Calendar_Year IN (2000,2001) AND t.Calendar_Week_Number BETWEEN 20 AND 30 GROUP BY p.Prod_Name, t.Calendar_Year, t.Calendar_Week_Number) v PARTITION BY (v.Product_Name) RIGHT OUTER JOIN (SELECT DISTINCT Calendar_Week_Number Week, Calendar_Year Year FROM Times WHERE Calendar_Year in (2000, 2001) AND Calendar_Week_Number BETWEEN 20 AND 30) t ON (v.week = t.week AND v.Year = t.Year) ORDER BY t.year, t.week; Time Series Calculations on Densified Data Time series calculations are easier when data is dense along the time dimension. Dense data has a consistent number of rows for each time period, which in turn makes it simple to use analytic window functions with physical offsets. The example shown calculates weekly year-to-date sales alongside the weekly sales. The NULL values that the partitioned outer join inserts in making the time series dense are handled in the usual way; the SUM function treats them as zeros. Oracle Database 10g: SQL and PL/SQL New Features

317 Time Series Calculations: Results
PRODUCT_NAME YEAR WEEK SALES CURRENT_SALES CUMULATIVE_SALES Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce ... Bounce Bounce Bounce Bounce Bounce Bounce Bounce Bounce 22 rows selected. Time Series Calculations: Results These are the results from the partitioned outer join shown in the previous slide. The highlighted rows show the NULL values that the partitioned outer join inserted. In the CURRENT_SALES column, the NVL function converts NULL to zero. Oracle Database 10g: SQL and PL/SQL New Features

318 Period-to-Period Comparison of One Time Level
Calculating a year-over-year sales comparison at the week level results in the following: WEEKLY_YTD_SALES PROD YEAR WEEK SALES WEEKLY_YTD_SALES PRIOR_YEAR Y Box Y Box Y Box Y Box Y Box Y Box Y Box Y Box Y Box Y Box Y Box 11 rows selected. Period-to-Period Comparison Suppose you are interested in calculating a year-over-year Year-To-Date (YTD) sales comparison at the week level for the Y Box product for the years 2001 versus This is done in three steps: 1. Using a partitioned outer join, data can be densified along the time dimension (in this case, at the week level). 2. The SUM()analytic function can be used to compute Year-To-Date Totals at the week level. 3. The LAG analytic function can be used to reach over and obtain the Year-To-Date Totals for the same week of the prior year. Because data has been densified on the time dimension (at the week level), the LAG function easily gets the sales for the prior year even though it uses physical offsets. See the query on the next page for details. To improve readability of the query and focus on the partitioned outer join, a WITH clause is used to start the query. Oracle Database 10g: SQL and PL/SQL New Features

319 Period-to-Period Comparison for Multiple Time Levels: Example
Goal: Create a single query with comparisons at the day, week, month, quarter, and year level. Approach: View of the TIME dimension View of SALES aggregated over TIME and PRODUCT Materialized view of SALES aggregated over TIME and PRODUCT (for performance) Period-to-Period Comparison for Multiple Time Levels Although the earlier example showed you a way to create comparisons for a single time level, it is even more useful to handle multiple time levels in a single query. For instance, you can compare sales versus the prior period at the year, quarter, month, and day levels. One approach is to use the three steps shown. The goal is a single query with comparisons at the day, week, month, quarter, and year level. 1. You create a view of the time dimension to use as an edge of the cube. The time edge will be partition outer joined to the sparse data in the CUBE_PROD_TIME view to densify the data. 2. You create a view called CUBE_PROD_TIME that holds a hierarchical cube of sales aggregated across TIMES and PRODUCTS. 3. For optimal performance, you create a materialized view called MV_PROD_TIME. This materialized view matches the view defined in step 1. Note: To learn about the hierarchical cube concept, refer to the Data Warehousing Reference Guide (chapter titled “SQL for Aggregation”). Oracle Database 10g: SQL and PL/SQL New Features

320 View of the TIME Dimension
CREATE OR REPLACE VIEW edge_time AS SELECT (CASE WHEN ((GROUPING(calendar_year)=0 )AND (GROUPING(calendar_quarter_desc)=1 )) THEN (TO_CHAR(calendar_year) || '_0') WHEN ((GROUPING(calendar_quarter_desc)=0) AND (GROUPING(calendar_month_desc)=1 )) THEN (TO_CHAR(calendar_quarter_desc) || '_1') WHEN ((GROUPING(calendar_month_desc)=0 )AND (GROUPING(time_id)=1 )) THEN (TO_CHAR(calendar_month_desc) || '_2') ELSE (TO_CHAR(time_id) || '_3') END) Hierarchical_Time, calendar_year yr, calendar_quarter_number qtr_num, calendar_quarter_desc qtr, calendar_month_number mon_num, calendar_month_desc mon, time_id – TRUNC(time_id, 'YEAR') + 1 day_num, time_id day, GROUPING_ID(calendar_year, calendar_quarter_desc, calendar_month_desc, time_id) gid_t FROM TIMES GROUP BY ROLLUP (calendar_year, (calendar_quarter_desc, calendar_quarter_number), (calendar_month_desc, calendar_month_number), time_id); View of the TIME Dimension The CREATE VIEW statement shown in the slide defines a view of the TIME table that will be used in a partitioned outer join with sales data. Note that the HIERARCHICAL_TIME column contains string representations of time from all levels of the time hierarchy. This is analogous to creating a primary key in a single column across all levels of time. The CASE expression used for the HIERARCHICAL_TIME column appends a marker (_0, _1, ...) to each date string to denote the time level of the value. A _0 represents the year level, _1 represents quarters, _2 represents months, and _3 represents day. Note that the GROUP BY ROLLUP clause is a rollup hierarchy for the time dimension. Oracle Database 10g: SQL and PL/SQL New Features

321 Oracle Database 10g: SQL and PL/SQL New Features 1 - 322
View of the SALES Cube CREATE OR REPLACE VIEW cube_prod_time AS SELECT (CASE WHEN ((GROUPING(calendar_year)=0 ) AND (GROUPING(calendar_quarter_desc)=1 )) THEN (TO_CHAR(calendar_year) || '_0') WHEN ((GROUPING(calendar_quarter_desc)=0 ) AND (GROUPING(calendar_month_desc)=1 )) THEN (TO_CHAR(calendar_quarter_desc) || '_1') WHEN ((GROUPING(calendar_month_desc)=0 ) AND (GROUPING(t.time_id)=1 )) THEN (TO_CHAR(calendar_month_desc) || '_2') ELSE (TO_CHAR(t.time_id) || '_3') END) Hierarchical_Time, calendar_year year, calendar_quarter_desc quarter, calendar_month_desc month, t.time_id day, prod_category cat, prod_subcategory subcat, p.prod_id prod, GROUPING_ID(prod_category, prod_subcategory, p.prod_id, calendar_year, calendar_quarter_desc, calendar_month_desc, t.time_id) gid, GROUPING_ID(prod_category, prod_subcategory, p.prod_id) gid_p, GROUPING_ID(calendar_year, calendar_quarter_desc, calendar_month_desc, t.time_id) gid_t, SUM(amount_sold) s_sold, COUNT(amount_sold) c_sold, COUNT(*) cnt FROM SALES s, TIMES t, PRODUCTS p WHERE s.time_id = t.time_id AND p.prod_name IN ('Bounce', 'Y Box') AND s.prod_id = p.prod_id GROUP BY ROLLUP(calendar_year, calendar_quarter_desc, calendar_month_desc, t.time_id), ROLLUP(prod_category, prod_subcategory, p.prod_id); View of the SALES Cube The view in the slide creates a sparsely populated hierarchical cube of sales data. Note that the HIERARCHICAL_TIME column contains string representations of time from all levels of the time hierarchy. The CASE expression used for the Hierarchical_Time column appends a marker (_0, _1, ...) to each date string to denote the time level of the value. A _0 represents the year level, _1 represents quarters, _2 represents months, and _3 represents day. Note that the GROUP BY clause is a concatenated ROLLUP that specifies the rollup hierarchy for the TIME and PRODUCT dimensions. The GROUP BY clause determines the hierarchical cube contents. Note that the GROUPING_ID function is used to create three sets of groups: gid covers the full product and time hierarchy. gid_p covers the product hierarchy. gid_t covers the time hierarchy. In this example, the gid_t is used in the partitioned outer join. Oracle Database 10g: SQL and PL/SQL New Features

322 Materialized View of SALES
CREATE MATERIALIZED VIEW mv_prod_time REFRESH COMPLETE ON DEMAND AS SELECT (CASE WHEN ((GROUPING(calendar_year)=0 ) AND (GROUPING(calendar_quarter_desc)=1 )) THEN (TO_CHAR(calendar_year) || '_0') WHEN ((GROUPING(calendar_quarter_desc)=0 ) AND (GROUPING(calendar_month_desc)=1 )) THEN (TO_CHAR(calendar_quarter_desc) || '_1') WHEN ((GROUPING(calendar_month_desc)=0 ) AND (GROUPING(t.time_id)=1 )) THEN (TO_CHAR(calendar_month_desc) || '_2') ELSE (TO_CHAR(t.time_id) || '_3') END) Hierarchical_Time, calendar_year year, calendar_quarter_desc quarter, calendar_month_desc month, t.time_id day, prod_category cat, prod_subcategory subcat, p.prod_id prod, GROUPING_ID(prod_category, prod_subcategory, p.prod_id, calendar_year, calendar_quarter_desc, calendar_month_desc,t.time_id) gid, GROUPING_ID(prod_category, prod_subcategory, p.prod_id) gid_p, GROUPING_ID(calendar_year, calendar_quarter_desc, calendar_month_desc, t.time_id) gid_t, SUM(amount_sold) s_sold, COUNT(amount_sold) c_sold, COUNT(*) cnt FROM SALES s, TIMES t, PRODUCTS p WHERE s.time_id = t.time_id AND p.prod_name in ('Bounce', 'Y Box') AND s.prod_id = p.prod_id GROUP BY ROLLUP(calendar_year, calendar_quarter_desc, calendar_month_desc, t.time_id), ROLLUP(prod_category, prod_subcategory, p.prod_id); Materialized View of SALES The MV_PROD_TIME materialized view is created with the same definition as the CUBE_PROD_TIME view. Note: The materialized view is created purely for performance. Oracle Database 10g: SQL and PL/SQL New Features

323 Period-to-Period Query
SELECT substr(prod,1,4) prod, substr(Hierarchical_Time,1,12) ht, sales, sales_prior_period, sales - sales_prior_period variance_prior_period, sales_same_period_prior_year, sales - sales_same_period_prior_year variance_same_period_p_year FROM ( SELECT cat, subcat, prod, gid_p, gid_t, Hierarchical_Time, yr, qtr, mon, day, sales, LAG(sales, 1) OVER (PARTITION BY gid_p, cat, subcat, prod, gid_t ORDER BY yr, qtr, mon, day) sales_prior_period, LAG(sales, 1 ) OVER (PARTITION BY gid_p, cat, subcat, prod, gid_t, qtr_num, mon_num, day_num ORDER BY yr) sales_same_period_prior_year FROM ( SELECT c.gid, c.cat, c.subcat, c.prod, c.gid_p, t.gid_t, t.yr, t.qtr, t.qtr_num, t.mon, t.mon_num, t.day, t.day_num, t.Hierarchical_Time, NVL(s_sold,0) sales FROM cube_prod_time c PARTITION BY (gid_p, cat, subcat, prod) RIGHT OUTER JOIN edge_time t ON ( c.gid_t = t.gid_t AND c.Hierarchical_Time = t.Hierarchical_Time) ) dense_cube_prod_time ) -- side by side current,prior and prior year WHERE prod IN (139) AND gid_p=0 AND prod and prod level data ( (mon IN (' ' ) AND gid_t IN (0, 1) ) OR -- day and month data ( qtr IN (' ' ) AND gid_t IN (3) ) ) quarter level data ORDER BY day; 3 2 1 Period-to-Period Query You now have the required elements for the comparison query. You can obtain period-to-period comparison calculations at all time levels. It requires applying analytic functions to a hierarchical cube with dense data along the time dimension. Some of the calculations that you can achieve for each time level are the following: Sum of sales for the prior period at all levels of time Variance in sales over the prior period Sum of sales in the same period a year ago at all levels of time Variance in sales over the same period last year The query in the slide performs all four of these calculations. It uses a partitioned outer join of the CUBE_PROD_TIME and EDGE_TIME views to create an inline view of dense data called DENSE_CUBE_PROD_TIME (1). The query then uses the LAG function in the same way as the earlier single-level example. The outer WHERE clause specifies time at three levels: the days of August 2001, the entire month, and the entire third quarter of 2001. Note that the last two rows of the results contain the month-level and quarter-level aggregations. Oracle Database 10g: SQL and PL/SQL New Features

324 Period-to-Period Query Results
variance sales_same variance sales_prior _prior _period_prior _same_period PROD HT SALES _period _period _year _prior_year AUG-01_ AUG-01_ ... AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ AUG-01_ _ _ 33 rows selected. Period-to-Period Query Results Note: To make the results easier to read, the SQL*Plus column headings are adjusted with the commands below. The commands fold the column headings to reduce line length: col sales_prior_period heading 'sales_prior|_period' col variance_prior_period heading 'variance|_prior|_period' col sales_same_period_prior_year – heading 'sales_same|_period_prior|_year' col variance_same_period_p_year – heading 'variance|_same_period|_prior_year' Oracle Database 10g: SQL and PL/SQL New Features

325 Oracle Database 10g: SQL and PL/SQL New Features 1 - 326
Summary In this lesson, you should have learned how to: Use the MERGE enhancements to: Omit the UPDATE or INSERT clauses Perform conditional updates and inserts Use the DELETE clause Densify data with partitioned outer joins Use the time series calculations on densified data Summary In this lesson, you learned about the enhancements to the MERGE statement. You learned that the MERGE statement can have either an UPDATE clause or an INSERT clause, or both. You also learned that you can perform conditional updates and inserts to reduce the number of rows processed. With the DELETE clause, you can cleanse the data by removing unnecessary rows. You also learned about the enhancements on partitioned outer joins. These enhancements enable you to write statements that densify data and perform period-to-period analysis. Oracle Database 10g: SQL and PL/SQL New Features

326 Practice 10-1 Overview: Using the MERGE Enhancements
This practice covers the following topics: Using the MERGE enhancements to perform a conditional update Using the MERGE enhancements to conditionally perform a delete Practice 10-1 Overview: Using the MERGE Enhancements In this practice, you use the MERGE enhancements to perform a conditional update and a conditional delete. You use the OE schema for this exercise. Oracle Database 10g: SQL and PL/SQL New Features

327 Practice 10-2 Overview: Densifying Data
This practice covers the following topics: Examining sparse data Densifying the sparse data so that a value of “0” results Practice 10-2 Overview: Densifying Data In this practice, you examine sparse data and then use partitioned outer joins to densify the sparse data so that a value of “0” results. You use the SH schema for this exercise. Oracle Database 10g: SQL and PL/SQL New Features

328 Using SQL Developer

329 Oracle Database 10g: SQL and PL/SQL New Features 1 - 330
Objectives After completing this appendix, you should be able to do the following: List the key features of Oracle SQL Developer Install Oracle SQL Developer Identify menu items of Oracle SQL Developer Create a database connection Manage database objects Use the SQL Worksheet Execute SQL statements and SQL scripts Edit and debug PL/SQL statements Create and save reports Objectives This appendix introduces the graphical tool, SQL Developer, which simplifies your database development tasks. You learn how to use SQL Worksheet to execute SQL statements and SQL scripts. You also learn how to edit and debug PL/SQL. Oracle Database 10g: SQL and PL/SQL New Features

330 What Is Oracle SQL Developer?
Oracle SQL Developer is a graphical tool that enhances productivity and simplifies database development tasks. You can connect to any target Oracle database schema by using standard Oracle database authentication. What Is Oracle SQL Developer? Oracle SQL Developer is a free graphical tool designed to improve your productivity and simplify the development of everyday database tasks. With just a few clicks, you can easily create and debug stored procedures, test SQL statements, and view optimizer plans. SQL Developer, the visual tool for database development, simplifies the following tasks: Browsing and managing database objects Executing SQL statements and scripts Editing and debugging PL/SQL statements Creating reports You can connect to any target Oracle database schema by using standard Oracle database authentication. When connected, you can perform operations on objects in the database. SQL Developer Oracle Database 10g: SQL and PL/SQL New Features

331 Oracle Database 10g: SQL and PL/SQL New Features 1 - 332
Key Features Is developed in Java Supports Windows, Linux, and Mac OS X platforms Provides default connectivity by using the JDBC Thin driver Does not require an installer Connects to any Oracle Database version and later Is bundled with JRE 1.5 Key Features of SQL Developer Oracle SQL Developer is developed in Java by leveraging the Oracle JDeveloper integrated development environment (IDE). The tool runs on Windows, Linux, and Mac operating system (OS) X platforms. You can install SQL Developer on the Database Server and connect remotely from your desktop, thus avoiding client/server network traffic. Default connectivity to the database is through the Java Database Connectivity (JDBC) Thin driver, so no Oracle home is required. SQL Developer does not require an installer and you need to simply unzip the downloaded file. With SQL Developer, users can connect to Oracle Databases and later, and all Oracle database editions including Express Edition. SQL Developer is bundled with Java Runtime Environment (JRE) 1.5, with an additional tools.jar to support Windows clients. Non-Windows clients need only Java Development Kit (JDK) 1.5. Oracle Database 10g: SQL and PL/SQL New Features

332 Installing SQL Developer
Download the Oracle SQL Developer kit and unzip it into any directory on your machine. Installing SQL Developer Oracle SQL Developer does not require an installer. To install SQL Developer, you need an unzip tool. To install SQL Developer, perform the following steps: 1. Create a folder as <local drive>:\SQL Developer. 2. Download the SQL Developer kit from: 3. Unzip the downloaded SQL Developer kit into the folder created in step 1. To start SQL Developer, go to <local drive>:\SQL Developer, and double-click sqldeveloper.exe. Oracle Database 10g: SQL and PL/SQL New Features

333 Menus for SQL Developer
4 2 6 1 3 5 Menus for SQL Developer SQL Developer has two main navigation tabs: Connections: By using this tab, you can browse database objects and users to which you have access. Reports: By using this tab, you can run predefined reports or create and add your own reports. SQL Developer uses the left side for navigation to find and select objects, and the right side to display information about selected objects. You can customize many aspects of the appearance and behavior of SQL Developer by setting preferences. The menus at the top contain standard entries, plus entries for features specific to SQL Developer. 1. View: Contains options that affect what is displayed in the SQL Developer interface 2. Navigate: Contains options for navigating to panes and in the execution of subprograms 3. Run: Contains the Run File and Execution Profile options that are relevant when a function or procedure is selected 4. Debug: Contains options relevant when a function or procedure is selected 5. Source: Contains options for use when editing functions and procedures 6. Tools: Invokes SQL Developer tools such as SQL*Plus, Preferences, and SQL Worksheet Oracle Database 10g: SQL and PL/SQL New Features

334 Creating a Database Connection
You must have at least one database connection to use SQL Developer. You can create and test connections: For multiple databases For multiple schemas SQL Developer automatically imports any connections defined in the tnsnames.ora file on your system. You can export connections to an XML file. Each additional database connection created is listed in the Connections Navigator hierarchy. Creating a Database Connection A connection is a SQL Developer object that specifies the necessary information for connecting to a specific database as a specific user of that database. To use SQL Developer, you must have at least one database connection, which may be existing, created, or imported. You can create and test connections for multiple databases and for multiple schemas. By default, the tnsnames.ora file is located in the $ORACLE_HOME/network/admin directory. But, it can also be in the directory specified by the TNS_ADMIN environment variable or registry value. When you start SQL Developer and display the Database Connections dialog box, SQL Developer automatically imports any connections defined in the tnsnames.ora file on your system. Note: On Windows systems, if the tnsnames.ora file exists but its connections are not being used by SQL Developer, define TNS_ADMIN as a system environment variable. You can export connections to an XML file so that you can reuse it later. You can create additional connections as different users to the same database or to connect to the different databases. Oracle Database 10g: SQL and PL/SQL New Features

335 Creating a Database Connection
Creating a Database Connection (continued) To create a database connection, perform the following steps: 1. Double-click <your_path>\sqldeveloper\sqldeveloper.exe. 2. On the Connections tabbed page, right-click Connections and select New Database Connection. 3. Enter the connection name, username, password, host name, and SID for the database you want to connect. 4. Click Test to make sure that the connection has been set correctly. Click Connect. On the Basic tabbed page, at the bottom, enter the following options: Hostname: Host system for the Oracle database Port: Listener port SID: Database name Service Name: Network service name for a remote database connection If you select the Save Password check box, the password is saved to an XML file. So, after you close the SQL Developer connection and open it again, you will not be prompted for the password. Oracle Database 10g: SQL and PL/SQL New Features

336 Browsing Database Objects
Use the Database Navigator to: Browse through many objects in a database schema Review the definitions of objects at a glance Browsing Database Objects After you have created a database connection, you can use the Database Navigator to browse through many objects in a database schema including Tables, Views, Indexes, Packages, Procedures, Triggers, Types, and so on. SQL Developer uses the left side for navigation to find and select objects, and the right side to display information about the selected objects. You can customize many aspects of the appearance of SQL Developer by setting preferences. You can see the definition of the objects broken into tabs of information that are pulled out of the data dictionary. For example, if you select a table in the Navigator, the details about columns, constraints, grants, statistics, triggers, and so on are displayed in an easy-to-read tabbed page. If you want to see the definition of the EMPLOYEES table as shown in the slide, perform the following steps: 1. Expand the Connections node in the Connections Navigator. 2. Expand Tables. 3. Double-click EMPLOYEES. Using the Data tab, you can enter new rows, update data, and commit these changes to the database. Oracle Database 10g: SQL and PL/SQL New Features

337 Creating a Schema Object
SQL Developer supports the creation of any schema object by: Executing a SQL statement in the SQL Worksheet Using the context menu Edit the objects using an Edit dialog box or one of the many context-sensitive menus. View the data definition language (DDL) for adjustments such as creating a new object or editing an existing schema object. Creating a Schema Object SQL Developer supports the creation of any schema object by executing a SQL statement in the SQL Worksheet. Alternatively, you can create objects using the context menus. After the objects are created, you can edit the objects using an edit dialog box or one of the many context-sensitive menus. As new objects are created or existing objects are edited, the DDL for those adjustments is available for review. An Export DDL option is available if you want to create the full DDL for one or more objects in the schema. The slide shows creating a table using the context menu. To open a dialog box for creating a new table, right-click Tables and select Create TABLE. The dialog boxes for creating and editing database objects have multiple tabs, each reflecting a logical grouping of properties for that type of object. Oracle Database 10g: SQL and PL/SQL New Features

338 Creating a New Table: Example
In the Create Table dialog box, if you do not select the Show Advanced Options check box, you can create a table quickly by specifying columns and some frequently used features. If you select the Show Advanced Options check box, the Create Table dialog box changes to one with multiple tabs, in which you can specify an extended set of features while creating the table. The example in the slide shows creating the DEPENDENTS table by selecting the Show Advanced Options check box. To create a new table, perform the following steps: 1. In the Connections Navigator, right-click Tables. 2. Select Create TABLE. 3. In the Create Table dialog box, select Show Advanced Options. 4. Specify column information. 5. Click OK. Although it is not required, you should also specify a primary key using the Primary Key tab in the dialog box. Sometimes, you may want to edit the table that you have created. To edit a table, right-click the table in the Connections Navigator, and select Edit. Oracle Database 10g: SQL and PL/SQL New Features

339 Using the SQL Worksheet
Use the SQL Worksheet to enter and execute SQL, PL/SQL, and SQL*Plus statements. Specify any actions that can be processed by the database connection associated with the worksheet. Using the SQL Worksheet When you connect to a database, a SQL Worksheet window for that connection is automatically opened. You can use the SQL Worksheet to enter and execute SQL, PL/SQL, and SQL*Plus statements. The SQL Worksheet supports SQL*Plus statements to a certain extent. SQL*Plus statements that are not supported by the SQL Worksheet are ignored and not passed to the database. You can specify any actions that can be processed by the database connection associated with the worksheet, such as: Creating a table Inserting data Creating and editing a trigger Selecting data from a table Saving the selected data to a file You can display a SQL Worksheet by using any of the following two options: Select Tools > SQL Worksheet. Click the Open SQL Worksheet icon. Oracle Database 10g: SQL and PL/SQL New Features

340 Using the SQL Worksheet
2 4 6 8 1 5 7 3 Using the SQL Worksheet (continued) You may want to use shortcut keys or icons to perform certain tasks such as executing a SQL statement, running a script, and viewing the history of SQL statements that you have executed. You can use the SQL Worksheet toolbar that contains icons to perform the following tasks: 1. Execute Statement: Executes the statement at the cursor in the Enter SQL Statement box. You can use bind variables in the SQL statements but not substitution variables. 2. Run Script: Executes all statements in the Enter SQL Statement box using the Script Runner. You can use substitution variables in the SQL statements but not bind variables. 3. Commit: Writes any changes to the database, and ends the transaction 4. Rollback: Discards any changes to the database, without writing them to the database, and ends the transaction 5. Cancel: Stops the execution of any statements currently being executed 6. SQL History: Displays a dialog box with information about SQL statements that you have executed 7. Execute Explain Plan: Generates the execution plan, which you can see by clicking the Explain tab 8. Clear: Erases the statement or statements in the Enter SQL Statement box Oracle Database 10g: SQL and PL/SQL New Features

341 Executing SQL Statements
Use the Enter SQL Statement box to enter single or multiple SQL statements. Executing SQL Statements In the SQL Worksheet, you can use the Enter SQL Statement box to type a single or multiple SQL statements. For a single statement, the semicolon at the end is optional. When you type in the statement, the SQL keywords are automatically highlighted. To execute a SQL statement, ensure that your cursor is within the statement and click the Execute Statement icon. Alternatively, you can press the F9 key. To execute multiple SQL statements and see the results, click the Run Script icon. Alternatively, you can press the F5 key. In the example in the slide, because there are multiple SQL statements, the first statement is terminated with a semicolon. The cursor is in the first statement and so when the statement is executed, results corresponding to the first statement are displayed in the Results box. Oracle Database 10g: SQL and PL/SQL New Features

342 Viewing the Execution Plan
You can execute a SQL script, and view the execution plan. To execute a SQL script file, perform the following steps: 1. Right-click in the Enter SQL Statement box, and select Open File from the drop-down menu. 2. In the Open dialog box, double-click the .sql file. 3. Click the Run Script icon. When you double-click the .sql file, the SQL statements are loaded into the Enter SQL Statement box. You can execute the script or each line individually. The results are displayed in the Script Output box. The example in the slide shows the execution plan. The Execute Explain Plan icon generates the execution plan. An execution plan is the sequence of operations that are performed to execute the statement. You can see the execution plan by clicking the Explain tab. Oracle Database 10g: SQL and PL/SQL New Features

343 Formatting the SQL Code
Before formatting Formatting the SQL Code You may want to better format the indentation, spacing, capitalization, and line separation of the SQL code. SQL Developer has the feature of formatting the SQL code. To format the SQL code, right-click in the statement area, and select Format SQL. In the example in the slide, before formatting, the SQL code has the keywords not capitalized and the statement not properly indented. After formatting, the SQL code is well formatted with the keywords capitalized and the statement properly indented. After formatting Oracle Database 10g: SQL and PL/SQL New Features

344 Oracle Database 10g: SQL and PL/SQL New Features 1 - 345
Using Snippets Snippets are code fragments that may be just syntax or examples. Using Snippets You may want to use certain code fragments when you are using the SQL Worksheet or creating or editing a PL/SQL function or procedure. SQL Developer has the feature called Snippets. Snippets are code fragments, such as SQL functions, Optimizer hints, and miscellaneous PL/SQL programming techniques. You can drag snippets into the Editor window. To display Snippets, select View > Snippets. The Snippets window is displayed on the right side. You can use the drop-down list to select a group. A Snippets button is placed in the right window margin, so that you can display the Snippets window if it becomes hidden. Oracle Database 10g: SQL and PL/SQL New Features

345 Using Snippets: Example
Inserting a snippet Editing the snippet Using Snippets: Example To insert a snippet into your code in a SQL Worksheet or in a PL/SQL function or procedure, drag the snippet from the Snippets window into the desired place in your code. Then you can edit the syntax so that the SQL function is valid in the current context. To see a brief description of a SQL function in a tool tip, place the cursor over the function name. The example in the slide shows that CONCAT(char1, char2)is dragged from the Character Functions group in the Snippets window. Then the CONCAT function syntax is edited and the rest of the statement is added such as in the following: SELECT CONCAT(first_name, last_name) FROM employees; Oracle Database 10g: SQL and PL/SQL New Features

346 Oracle Database 10g: SQL and PL/SQL New Features 1 - 347
Using SQL*Plus The SQL Worksheet does not support all SQL*Plus statements. You can invoke the SQL*Plus command-line interface from SQL Developer. Using SQL*Plus The SQL Worksheet supports some SQL*Plus statements. SQL*Plus statements must be interpreted by the SQL Worksheet before being passed to the database; any SQL*Plus statements that are not supported by the SQL Worksheet are ignored and not passed to the database. To display the SQL*Plus command window, from the Tools menu, select SQL*Plus. To use this feature, the system on which you are using SQL Developer must have an Oracle home directory or folder, with a SQL*Plus executable under that location. If the location of the SQL*Plus executable is not already stored in your SQL Developer preferences, you are asked to specify its location. Oracle Database 10g: SQL and PL/SQL New Features

347 Creating an Anonymous Block
Create an anonymous block and display the output of the DBMS_OUTPUT package statements. Creating an Anonymous Block You can create an anonymous block and display the output of the DBMS_OUTPUT package statements. To create an anonymous block and view the results, perform the following steps: 1. Enter the PL/SQL code in the Enter SQL Statement box. 2. Click the DBMS Output tab. Then click the Enable DBMS Output icon to set the server output ON. 3. Click the Execute Statement icon above the Enter SQL Statement box. Then click the DBMS Output tab to see the results. Oracle Database 10g: SQL and PL/SQL New Features

348 Editing the PL/SQL Code
Use the full-featured editor for PL/SQL program units. Editing the PL/SQL Code You may want to make changes to your PL/SQL code. SQL Developer includes a full-featured editor for PL/SQL program units. It includes customizable PL/SQL syntax highlighting in addition to common editor functions such as: Bookmarks Code Completion Code Folding Search and Replace To edit the PL/SQL code, click the object name in the Connections Navigator, and then click the Edit icon. Optionally, double-click the object name to invoke the Object Definition page with its tabs and the Edit page. You can update only if you are on the Edit tabbed page. The Code Insight feature is shown in the slide. For example, if you type DBMS_OUTPUT.and then press [Ctrl] + [Spacebar], you can select from a list of members of that package. Note that, by default, Code Insight is invoked automatically if you pause for more than one second after typing a period (“.”). When using the Code Editor to edit PL/SQL code, you can select either Compile or Compile for Debug. Oracle Database 10g: SQL and PL/SQL New Features

349 Creating a PL/SQL Procedure
1 Creating a PL/SQL Procedure Using SQL Developer, you can create PL/SQL functions, procedures, and packages. To create a PL/SQL procedure, perform the following steps: 1. Right-click the Procedures node in the Connections Navigator to invoke the Context menu, and select Create Procedure. 2. In the Create Procedure dialog box, specify the procedure information and click OK. Note: Ensure that you press [Enter] before you click OK. In the example in the slide, the EMP_LIST procedure is created. The default values for parameter name and parameter type are replaced with pMaxRows and NUMBER, respectively. 2 Oracle Database 10g: SQL and PL/SQL New Features

350 Compiling a PL/SQL Procedure
After you specify the parameter information in the Create Procedure dialog box and click OK, you see the Procedure tab added in the right window. You can then replace the anonymous block with your PL/SQL code. To compile the PL/SQL subprogram, click the Save button in the toolbar. If you expand Procedures in the Connections Navigator, you can see that the Procedure node is added. When an invalid PL/SQL subprogram is detected by SQL Developer, the status is indicated with a red X over the icon for the subprogram in the Connections Navigator. Compilation errors are shown in the Log window. You can navigate to the line reported in the error by simply double-clicking the error. SQL Developer also displays errors and hints in the right-hand gutter. If you place the cursor over each of the red bars in the gutter, the error message appears. For example, if the error messages indicate that there is a formatting error, modify the code accordingly and click the Compile icon. Oracle Database 10g: SQL and PL/SQL New Features

351 Running a PL/SQL Procedure
After you have created and compiled a PL/SQL procedure, you can run it using SQL Developer. To run a PL/SQL procedure, right-click the procedure name in the left navigator and select Run. Optionally, you can use the Run button in the right window. This invokes the Run PL/SQL dialog box. The Run PL/SQL dialog box enables you to select the target procedure or function to run and displays a list of parameters for the selected target. You can use the PL/SQL Block box to populate parameters to be passed to the program unit and to handle complex return types. After you make the necessary changes in the Run PL/SQL dialog box, click OK. You see the expected results in the Running-Log window. In the example in the slide, PMAXROWS := NULL; is changed to PMAXROWS := 5;. The results of the five rows returned are displayed in the Running-Log window. Oracle Database 10g: SQL and PL/SQL New Features

352 Oracle Database 10g: SQL and PL/SQL New Features 1 - 353
Debugging PL/SQL Debugging PL/SQL You may want to debug a PL/SQL function, procedure, or package. SQL Developer provides full support for PL/SQL debugging. To debug a function or procedure, perform the following steps: 1. Click the object name in the Connections Navigator. 2. Right-click the object and select Compile for Debug. 3. Click the Edit icon. Then click the Debug icon above its source listing. If the toggle numbers before each line of code are not yet displayed, right-click in the Code Editor margin and select Toggle Line Numbers. The PL/SQL debugger supplies many commands to control program execution including Step Into, Step Over, Step Out, Run to Cursor, and so on. While the debugger is paused, you can examine and modify the values of variables from the Smart Data, Watches, or Inspector windows. The Breakpoints window lists the defined breakpoints. You can use this window to add new breakpoints, or customize the behavior of existing breakpoints. Note: For PL/SQL debugging, you need the debug any procedure and debug connect session privileges. Oracle Database 10g: SQL and PL/SQL New Features

353 Oracle Database 10g: SQL and PL/SQL New Features 1 - 354
Database Reporting SQL Developer provides a number of predefined reports about the database and its objects. Database Reporting SQL Developer provides many reports about the database and its objects. These reports can be grouped into the following categories: About Your Database reports Database Administration reports Table reports PL/SQL reports Security reports XML reports Jobs reports Streams reports All Objects reports Data Dictionary reports User Defined reports To display reports, click the Reports tab on the left side of the window. Individual reports are displayed in tabbed panes on the right side of the window; and for each report, you can select (using a drop-down list) the database connection for which to display the report. For reports about objects, the objects shown are only those visible to the database user associated with the selected database connection, and the rows are usually ordered by Owner. Oracle Database 10g: SQL and PL/SQL New Features

354 Creating a User-Defined Report
Create and save user-defined reports for repeated use. Creating a User-Defined Report User-defined reports are any reports that are created by SQL Developer users. To create a user-defined report, perform the following steps: 1. Right-click the User Defined Reports node under Reports, and select Add Report. 2. In the Create Report Dialog box, specify the report name and the SQL query to retrieve information for the report. Then click Apply. In the example in the slide, the report name is specified as emp_sal. An optional description is provided indicating that the report contains details about employees with salary equal to or greater than 10,000. The complete SQL statement for retrieving the information to be displayed in the user-defined report is specified in the SQL box. You can also include an optional tool tip to be displayed when the cursor stays briefly over the report name in the Reports Navigator display. You can organize user-defined reports in folders, and you can create a hierarchy of folders and subfolders. To create a folder for user-defined reports, right-click the User Defined node or any folder name under that node and select Add Folder. Information about user-defined reports, including any folders for these reports, is stored in a file named UserReports.xml under the directory for user-specific information. Oracle Database 10g: SQL and PL/SQL New Features

355 Oracle Database 10g: SQL and PL/SQL New Features 1 - 356
Summary In this appendix, you should have learned how to use SQL Developer to do the following: Browse, create, and edit database objects Execute SQL statements and scripts in the SQL Worksheet Edit and debug PL/SQL statements Create and save custom reports Summary SQL Developer is a free graphical tool to simplify database development tasks. Using SQL Developer, you can browse, create, and edit database objects. You can use the SQL Worksheet to run SQL statements and scripts. Using SQL Developer, you can edit and debug PL/SQL. SQL Developer enables you to create and save your own special set of reports for repeated use. Oracle Database 10g: SQL and PL/SQL New Features

356 Using SQL*Plus and New SQL*Plus Enhancements

357 Oracle Database 10g: SQL and PL/SQL New Features 1 - 358
Objectives After completing this appendix, you should be able to do the following: Log in to SQL*Plus Edit SQL commands Format output using SQL*Plus commands Interact with script files Use the new Oracle Database 10g SQL*Plus features Objectives You might want to create SELECT statements that can be used again and again. This appendix also covers the use of SQL*Plus commands to execute SQL statements. You learn how to format output using SQL*Plus commands, edit SQL commands, and save scripts in SQL*Plus. Oracle Database 10g: SQL and PL/SQL New Features

358 SQL and SQL*Plus Interaction
SQL statements Server SQL*Plus Query results Buffer SQL and SQL*Plus SQL is a command language for communication with the Oracle9i Server from any tool or application. Oracle SQL contains many extensions. When you enter a SQL statement, it is stored in a part of memory called the SQL buffer and remains there until you enter a new SQL statement. SQL*Plus is an Oracle tool that recognizes and submits SQL statements to the Oracle9i Server for execution. It contains its own command language. Features of SQL Can be used by a range of users, including those with little or no programming experience Is a nonprocedural language Reduces the amount of time required for creating and maintaining systems Is an English-like language Features of SQL*Plus Accepts ad hoc entry of statements Accepts SQL input from files Provides a line editor for modifying SQL statements Controls environmental settings Formats query results into basic reports Accesses local and remote databases SQL scripts Oracle Database 10g: SQL and PL/SQL New Features

359 SQL Statements Versus SQL*Plus Commands
A language ANSI-standard Keywords cannot be abbreviated Statements manipulate data and table definitions in the database SQL*Plus An environment Oracle-proprietary Keywords can be abbreviated Commands do not allow manipulation of values in the database SQL and SQL*Plus (continued) The following table compares SQL and SQL*Plus: SQL statements SQL buffer SQL*Plus commands SQL*Plus buffer Oracle Database 10g: SQL and PL/SQL New Features

360 Oracle Database 10g: SQL and PL/SQL New Features 1 - 361
Overview of SQL*Plus Log in to SQL*Plus Describe the table structure Edit your SQL statement Execute SQL from SQL*Plus Save SQL statements to files and append SQL statements to files Execute saved files Load commands from file to buffer to edit SQL*Plus SQL*Plus is an environment in which you can do the following: Execute SQL statements to retrieve, modify, add, and remove data from the database Format, perform calculations on, store, and print query results in the form of reports Create script files to store SQL statements for repeated use in the future SQL*Plus commands can be divided into the following main categories: Oracle Database 10g: SQL and PL/SQL New Features

361 Oracle Database 10g: SQL and PL/SQL New Features 1 - 362
Logging In to SQL*Plus 1 2 sqlplus Logging In to SQL*Plus How you invoke SQL*Plus depends on which type of operating system or Windows environment you are running. To log in from a Windows environment: 1. Select Start > Programs > Oracle > Application Development > SQL*Plus. 2. Enter the username, password, and database connect string. To log in from a command-line environment: 1. Log on to your machine. 2. Enter the SQL*Plus command shown in the slide. In the syntax: username Your database username password Your database password (Your password is visible if you enter it here.) @database The database connect string Note: To ensure the integrity of your password, do not enter it at the operating system prompt. Instead, enter only your user name. Enter your password at the password prompt. After you log in to SQL*Plus, you see the message in the slide page (if you are using SQL*Plus version ). Oracle Database 10g: SQL and PL/SQL New Features

362 Displaying Table Structure
Use the SQL*Plus DESCRIBE command to display the structure of a table: DESC[RIBE] tablename Displaying Table Structure In SQL*Plus, you can display the structure of a table using the DESCRIBE command. The result of the command is a display of column names and data types as well as an indication of whether a column must contain data. In the syntax: tablename The name of any existing table, view, or synonym that is accessible to the user To describe the JOB_GRADES table, use this command: SQL> DESCRIBE job_grades Name Null? Type GRADE_LEVEL VARCHAR2(3) LOWEST_SAL NUMBER HIGHEST_SAL NUMBER Oracle Database 10g: SQL and PL/SQL New Features

363 Displaying Table Structure
DESCRIBE departments Name Null? Type DEPARTMENT_ID NOT NULL NUMBER(4) DEPARTMENT_NAME NOT NULL VARCHAR2(30) MANAGER_ID NUMBER(6) LOCATION_ID NUMBER(4) Displaying Table Structure (continued) The example in the slide displays the information about the structure of the DEPARTMENTS table. In the result: Null?: Specifies whether a column must contain data (NOT NULL indicates that a column must contain data.) Type: Displays the data type for a column The following table describes the data types: Oracle Database 10g: SQL and PL/SQL New Features

364 SQL*Plus Editing Commands
A[PPEND] text C[HANGE] / old / new C[HANGE] / text / CL[EAR] BUFF[ER] DEL DEL n DEL m n SQL*Plus Editing Commands SQL*Plus commands are entered one line at a time and are not stored in the SQL buffer. Guidelines If you press [Enter] before completing a command, SQL*Plus prompts you with a line number. You terminate the SQL buffer by either entering one of the terminator characters (semicolon or slash) or pressing [Enter] twice. The SQL prompt then appears. Oracle Database 10g: SQL and PL/SQL New Features

365 SQL*Plus Editing Commands
I[NPUT] I[NPUT] text L[IST] L[IST] n L[IST] m n R[UN] n n text 0 text SQL*Plus Editing Commands (continued) Note: You can enter only one SQL*Plus command for each SQL prompt. SQL*Plus commands are not stored in the buffer. To continue a SQL*Plus command on the next line, end the first line with a hyphen (-). Oracle Database 10g: SQL and PL/SQL New Features

366 Oracle Database 10g: SQL and PL/SQL New Features 1 - 367
Using LIST, n, and APPEND LIST 1 SELECT last_name 2* FROM employees 1 1* SELECT last_name A , job_id 1* SELECT last_name, job_id Using LIST, n, and APPEND Use the L[IST] command to display the contents of the SQL buffer. The asterisk (*) beside line 2 in the buffer indicates that line 2 is the current line. Any edits that you made apply to the current line. Change the number of the current line by entering the number (n) of the line that you want to edit. The new current line is displayed. Use the A[PPEND] command to add text to the current line. The newly edited line is displayed. Verify the new contents of the buffer by using the LIST command. Note: Many SQL*Plus commands, including LIST and APPEND, can be abbreviated to just their first letter. LIST can be abbreviated to L; APPEND can be abbreviated to A. LIST 1 SELECT last_name, job_id 2* FROM employees Oracle Database 10g: SQL and PL/SQL New Features

367 Using the CHANGE Command
LIST 1* SELECT * from employees c/employees/departments 1* SELECT * from departments LIST 1* SELECT * from departments Using the CHANGE Command Use L[IST] to display the contents of the buffer. Use the C[HANGE] command to alter the contents of the current line in the SQL buffer. In this case, replace the EMPLOYEES table with the DEPARTMENTS table. The new current line is displayed. Use the L[IST] command to verify the new contents of the buffer. Oracle Database 10g: SQL and PL/SQL New Features

368 SQL*Plus File Commands
SAVE filename GET filename START filename @ filename EDIT filename SPOOL filename EXIT SQL*Plus File Commands SQL statements communicate with the Oracle server. SQL*Plus commands control the environment, format query results, and manage files. You can use the commands described in the following table: Oracle Database 10g: SQL and PL/SQL New Features

369 Using the SAVE, START, and EDIT Commands
LIST 1 SELECT last_name, manager_id, department_id 2* FROM employees SAVE my_query Created file my_query START my_query LAST_NAME MANAGER_ID DEPARTMENT_ID King Kochhar ... 107 rows selected. Using the SAVE, START, and EDIT Commands SAVE Use the SAVE command to store the current contents of the buffer in a file. In this way, you can store frequently used scripts for use in the future. START Use the START command to run a script in SQL*Plus. Oracle Database 10g: SQL and PL/SQL New Features

370 Using the SAVE, START, and EDIT Commands
EDIT my_query Using the SAVE, START, and EDIT Commands (continued) EDIT Use the EDIT command to edit an existing script. This opens an editor with the script file in it. When you have made the changes, quit the editor to return to the SQL*Plus command line. Oracle Database 10g: SQL and PL/SQL New Features

371 Some of the New SQL*Plus Enhancements in Oracle Database 10g
Changes to the SET SERVEROUT[PUT] command White space support in file and path names in Windows Three new predefined SQL*Plus variables The new RECYCLEBIN clause of the SHOW command The new APPEND, CREATE, and REPLACE extensions to the SPOOL command New error messages for the COPY command Change in the DESCRIBE command behavior New PAGESIZE default New SQLPLUS program compatibility option Execution statistics information in the AUTOTRACE command report Oracle Database 10g: SQL and PL/SQL New Features

372 Changes to the SERVEROUTPUT Command
Use the SET SERVEROUT[PUT] command to control whether to display the output of stored procedures or PL/SQL blocks in SQL*Plus. The DBMS_OUTPUT line length limit is increased from 255 bytes to 32,767 bytes. The default size is now unlimited. Resources are not preallocated when SERVEROUTPUT is set. Because there is no performance penalty, use UNLIMITED unless you want to conserve physical memory. SET SERVEROUT[PUT] {ON | OFF} [SIZE {n | UNL[IMITED]}] [FOR[MAT] {WRA[PPED] | WOR[D_WRAPPED] | TRU[NCATED]}] New SQL*Plus Enhancements in Oracle Database 10g Most PL/SQL input and output is through SQL statements, to store data in database tables or query those tables. All other PL/SQL I/O is done through APIs that interact with other programs. For example, the DBMS_OUTPUT package has procedures such as PUT_LINE. To see the result outside of PL/SQL requires another program, such as SQL*Plus, to read and display the data passed to DBMS_OUTPUT. SQL*Plus does not display DBMS_OUTPUT data unless you first issue the SQL*Plus command SET SERVEROUTPUT ON as follows: SET SERVEROUTPUT ON Note SIZE sets the number of bytes of the output that can be buffered within the Oracle Database server. The default is UNLIMITED. n cannot be less than 2,000 or greater than 1,000,000. For additional information about SERVEROUTPUT, see the Oracle Database PL/SQL User's Guide and Reference 10g Release 2 (10.2) Oracle Database 10g: SQL and PL/SQL New Features

373 White Space Support in File and Path Names in Windows
In Windows, white space can be included in file names and paths. Examples of where white space can be used: RUN, SPOOL, SAVE, and EDIT commands To reference files or paths containing spaces, enclose the name or path in double quotation marks. Examples SAVE "Monthly Report.sql" START "Monthly Report.sql" Oracle Database 10g: SQL and PL/SQL New Features

374 Predefined SQL*Plus Variables
Variable Name Contains _CONNECT_IDENTIFIER Connection identifier used to make connection, where available _DATE * Current date, or a user-defined fixed string _EDITOR Specifies the editor used by the EDIT command _O_VERSION Current version of the installed Oracle Database O_RELEASE Full release number of the installed Oracle Database _PRIVILEGE * Privilege level of the current connection _SQLPLUS_RELEASE Full release number of installed SQL*Plus component _USER * User name used to make connection Predefined Variables There are eight variables defined during SQL*Plus installation. These variables differ from user-defined variables by having only predefined values. The new variables that are new in Oracle Database 10g have an asterisk next to them in the table in the slide. You can view the value of each of these variables with the DEFINE command. These variables can be accessed and redefined like any other substitution variable. They can be used in TTITLE, in '&' substitution variables, or in your SQL*Plus command-line prompt. You can use the DEFINE command to view the definitions of these eight predefined variables in the same way as you view other DEFINE definitions. You can also use the DEFINE command to redefine their values, or you can use the UNDEFINE command to remove their definitions and make them unavailable. Note: For additional information about the SQL*Plus predefined variables, see the SQL*Plus User’s Guide and Reference Release 10.2. Oracle Database 10g: SQL and PL/SQL New Features

375 Using the New Predefined SQL*Plus Variables: Examples
-- Change the SQL*Plus prompt to display the connection -- identifier SQL> SET SQLPROMPT '_CONNECT_IDENTIFIER > ' orcl > -- view the predefined value of the _SQLPLUS_RELEASE -- substitution variable orcl > DEFINE _SQLPLUS_RELEASE DEFINE _SQLPLUS_RELEASE = " " (CHAR) -- View the user name connected to the current -- connection. orcl > DEFINE _USER DEFINE _USER = "HR" (CHAR) Using the Pre-defined SQL*Plus Variables: Examples To view all predefined and user-defined variable definitions, enter DEFINE. All predefined and all user-defined variable definitions are displayed as shown below: orcl > DEFINE DEFINE _DATE = "06-JUL-06" (CHAR) DEFINE _CONNECT_IDENTIFIER = "orcl" (CHAR) DEFINE _USER = "HR" (CHAR) DEFINE _PRIVILEGE = "" (CHAR) DEFINE _SQLPLUS_RELEASE = " " (CHAR) DEFINE _EDITOR = "Notepad" (CHAR) DEFINE _O_VERSION = "Oracle Database 10g Enterprise Edition Release Production With the Partitioning, OLAP and Data Mining options" (CHAR) DEFINE _O_RELEASE = " " (CHAR) You can use UNDEFINE to remove a substitution variable definition and make it unavailable. Oracle Database 10g: SQL and PL/SQL New Features

376 The SHOW Command and the New RECYCLEBIN Clause
SHOW RECYC[LEBIN] [original_name] SELECT * FROM USER_RECYCLEBIN desc user_recyclebin; Name Null? Type OBJECT_NAME NOT NULL VARCHAR2(30) ORIGINAL_NAME VARCHAR2(32) OPERATION VARCHAR2(9) TYPE VARCHAR2(25) TS_NAME VARCHAR2(30) CREATETIME VARCHAR2(19) DROPTIME VARCHAR2(19) DROPSCN NUMBER PARTITION_NAME VARCHAR2(32) CAN_UNDROP VARCHAR2(3) CAN_PURGE VARCHAR2(3) RELATED NOT NULL NUMBER BASE_OBJECT NOT NULL NUMBER PURGE_OBJECT NOT NULL NUMBER SPACE NUMBER The SHOW Command and the RECYCLEBIN Clause Using the SHOW command, you can show objects in the recycle bin that can be reverted with the FLASHBACK BEFORE DROP command. You do not need to remember column names, or interpret the less readable output from the query. The following query returns three columns that are displayed in the slide: SELECT * FROM USER_RECYCLEBIN Oracle Database 10g: SQL and PL/SQL New Features

377 The SHOW Command and the RECYCLEBIN Clause: Example
DROP TABLE test; Table dropped. SHOW recyclebin Oracle Database 10g: SQL and PL/SQL New Features

378 Using the SQL*Plus SPOOL Command
SPO[OL] [file_name[.ext] [CRE[ATE] | REP[LACE] | APP[END]] | OFF | OUT] Option Description file_name[.ext] Spools output to the specified file name CRE[ATE] Creates a new file with the name specified REP[LACE] Replaces the contents of an existing file. If the file does not exist, REPLACE creates the file. APP[END] Adds the contents of the buffer to the end of the file you specify OFF Stops spooling OUT Stops spooling and sends the file to your computer's standard (default) printer Using the SQL*Plus SPOOL Command The SPOOL command stores query results in a file, or optionally sends the file to a printer. The SPOOL command has been enhanced. You can now append to, or replace an existing file, where previously you could use SPOOL to only create (and replace) a file. REPLACE is the default. To spool output generated by commands in a script without displaying the output on the screen, use SET TERMOUT OFF. SET TERMOUT OFF does not affect output from commands that run interactively. You must use quotation marks around file names containing white spaces. To create a valid HTML file using SPOOL APPEND commands, you must use PROMPT or a similar command to create the HTML page header and footer. The SPOOL APPEND command does not parse HTML tags. Set SQLPLUSCOMPAT[IBILITY] to 9.2 or earlier to disable the CREATE, APPEND, and SAVE parameters. Oracle Database 10g: SQL and PL/SQL New Features

379 Using the SQL*Plus SPOOL Command: Examples
-- Record the output in the new file DIARY using the -- default file extension. SPOOL DIARY CREATE -- Append the output to the existing file DIARY. SPOOL DIARY APPEND -- Record the output to the file DIARY, overwriting the -- existing content SPOOL DIARY REPLACE -- Stop spooling and print the file on your default printer. SPOOL OUT Oracle Database 10g: SQL and PL/SQL New Features

380 The COPY Command: New Error Messages
CPY-0002 Illegal or missing APPEND, CREATE, INSERT, or REPLACE option CPY-0003 Internal Error: logical host number out of Range CPY-0004 Source and destination table and column names don't match CPY-0005 Source and destination column attributes don't Match CPY-0006 Select list has more columns than destination Table CPY-0007 Select list has fewer columns than destination table The COPY Command: New Error Messages CPY-0002 Illegal or missing APPEND, CREATE, INSERT, or REPLACE option: An internal COPY function has invoked COPY with a create option (flag) value that is out of range. CPY-0003 Internal Error: Logical host number out of range: An internal COPY function has been invoked with a logical host number value that is out of range. CPY-0004 Source and destination table and column names don't match: On an APPEND operation or an INSERT (when the table exists), at least one column name in the destination table does not match the corresponding column name in the optional column name list or in the SELECT command. To correct this, respecify the COPY command, making sure that the column names and their respective order in the destination table match the column names and column order in the optional column list or in the SELECT command. CPY-0005 Source and destination column attributes don't match: On an APPEND operation or an INSERT (when the table exists), at least one column in the destination table does not have the same data type as the corresponding column in the SELECT command. To correct this, respecify the COPY command, making sure that the data types for items being selected agree with the destination. Use TO_DATE, TO_CHAR, and TO_NUMBER to make conversions. Oracle Database 10g: SQL and PL/SQL New Features

381 The COPY Command: New Error Messages
CPY-0008 More column list names than columns in the destination table CPY-0009 Fewer column list names than columns in the CPY-0012 Datatype cannot be copied Oracle Database 10g: SQL and PL/SQL New Features

382 Change in the DESCRIBE Command Behavior
Before Oracle Database 10g, using the DESCRIBE on an invalidated object failed with the error: ORA-24372: invalid object for describe The DESCRIBE command continued to fail even if the object had since been validated. In Oracle Database 10g, the DESCRIBE command now automatically validates the object and continues if the validation is successful. Oracle Database 10g: SQL and PL/SQL New Features

383 The SET PAGES[IZE] Command
It sets the number of rows on each page of the output in SQL*Plus. The default PAGESIZE has changed from 24 to 14. You can set PAGESIZE to zero to suppress all headings, page breaks, titles, the initial blank line, and other formatting information. SET PAGES[IZE] {14 | n} The SET PAGES[IZE] Command The SET PAGES[IZE]command sets the number of rows displayed on each page. Error and informational messages are not counted in the page size, so pages may not always be exactly the same length. The default page size for SQL*Plus has changed from 24 to 14. Oracle Database 10g: SQL and PL/SQL New Features

384 The SQLPLUS Program and the Compatibility Option
Sets the value of the SQLPLUSCOMPATIBILITY system variable to the SQL*Plus release specified by x.y[.z] SQLPLUS -C[OMPATIBILITY] {x.y[.z]} -- x is the version number -- y is the release number -- z is the update number SQLPLUS -C The SQLPLUS Program and the Compatibility Option The SQL*Plus Compatibility Matrix tabulates behavior affected by each SQL*Plus compatibility setting. SQL*Plus compatibility modes can be set in three ways: You can include a SET SQLPLUSCOMPATIBILITY command in your site or user profile. On installation, there is no SET SQLPLUSCOMPATIBILITY setting in glogin.sql. Therefore, the default compatibility is 10.2. You can use the SQLPLUS -C[OMPATIBILITY] {x.y[.z]} command argument at startup to set the compatibility mode of that session. You can use the SET SQLPLUSCOMPATIBILITY {x.y[.z]} command during a session to set the SQL*Plus behavior you want for that session. Note: For a list showing the release of SQL*Plus that introduced the behavior change, see the “SQL*Plus Compatibility Matrix” topic in SQL*Plus User's Guide and Reference Release 10.2. Oracle Database 10g: SQL and PL/SQL New Features

385 Using the AUTOTRACE Command
It displays a report after the successful execution of SQL DML statements such as SELECT, INSERT, UPDATE or DELETE. The report can now include execution statistics and the query execution path. SET AUTOT[RACE] {ON | OFF | TRACE[ONLY]} [EXP[LAIN]] [STAT[ISTICS]] SET AUTOTRACE ON -- The AUTOTRACE report includes both the optimizer -- execution path and the SQL statement execution -- statistics. Using the AUTOTRACE Command EXPLAIN shows the query execution path by performing an EXPLAIN PLAN. STATISTICS displays SQL statement statistics. The formatting of your AUTOTRACE report may vary depending on the version of the server to which you are connected and the configuration of the server. The additional information and tabular output of AUTOTRACE PLAN is supported when connecting to Oracle Database 10g (Release 10.1) or later. When you connect to an earlier database, the older form of AUTOTRACE reporting is used. The DBMS_XPLAN package provides an easy way to display the output of the EXPLAIN PLAN command in several, predefined formats. Note For additional information about the package and subprograms, see the Oracle Database PL/SQL Packages and Types Reference 10g Release 2 (10.2) guide. For additional information about the EXPLAIN PLAN, see Oracle Database SQL Reference 10g Release 2 (10.2). For additional information about Execution Plans and the statistics, see Oracle Database Performance Tuning Guide 10g Release 2 (10.2). Oracle Database 10g: SQL and PL/SQL New Features

386 Displaying a Plan Table Using the DBMS_XPLAN.DISPLAY Package Function
-- Execute an explain plan command on a SELECT -- statement EXPLAIN PLAN FOR SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename='benoit'; -- Display the plan using the DBMS_XPLAN.DISPLAY table -- function SET LINESIZE 130 SET PAGESIZE 0 SELECT * FROM table(DBMS_XPLAN.DISPLAY); Displaying a Plan Table Using the DBMS_XPLAN.DISPLAY Package Function The query in the slide page produces the following output: Plan hash value: | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | | | (34)| 00:00:01 | |* 1 | HASH JOIN | | | | (34)| 00:00:01 | |* 2 | TABLE ACCESS FULL| EMP | | | (34)| 00:00:01 | | 3 | TABLE ACCESS FULL| DEPT | | | (34)| 00:00:01 | Predicate Information (identified by operation id): 1 - access("E"."DEPTNO"="D"."DEPTNO") 2 - filter("E"."ENAME"='benoit') 15 rows selected. Oracle Database 10g: SQL and PL/SQL New Features

387 Oracle Database 10g: SQL and PL/SQL New Features 1 - 388
Summary In this appendix, you should have learned how to use SQL*Plus as an environment to do the following: Execute SQL statements Edit SQL statements Format output Interact with script files Use the new Oracle Database 10g SQL*Plus features Summary SQL*Plus is an execution environment that you can use to send SQL commands to the database server and to edit and save SQL commands. You can execute commands from the SQL prompt or from a script file. Oracle Database 10g: SQL and PL/SQL New Features

388 Working with Collections

389 Oracle Database 10g: SQL and PL/SQL New Features 1 - 390
Objectives After completing this lesson, you should be able to do the following: Describe an object type Create an object type specification Implement the constructor method on objects Create collections Nested table collections Varray collections Use collections methods Manipulate collections Objectives In this lesson, you are introduced to PL/SQL programming using collections, including user-defined object types and constructor methods. Oracle object types are user-defined data types that make it possible to model complex real-world entities such as customers and purchase orders as unitary entities—objects—in the database. A collection is an ordered group of elements, all of the same type (for example, phone numbers for each customer). Each element has a unique subscript that determines its position in the collection. Collections work like the set, queue, stack, and hash table data structures found in most third-generation programming languages. Collections can store instances of an object type and can also be attributes of an object type. Collections can be passed as parameters. So, you can use them to move columns of data into and out of database tables or between client-side applications and stored subprograms. You can define collection types in a PL/SQL package, and then use the same types across many applications. Oracle Database 10g: SQL and PL/SQL New Features

390 Understanding Collections
A collection is a group of elements, all of the same type. Collections work like arrays. Collections can store instances of an object type and, conversely, can be attributes of an object type. Types of collections in PL/SQL: Nested tables Varrays Associative arrays String-indexed collections INDEX BY pls_integer Collections A collection is a group of elements, all of the same type. Each element has a unique subscript that determines its position in the collection. Collections work like the arrays found in most third-generation programming languages. They can store instances of an object type and, conversely, can be attributes of an object type. Collections can also be passed as parameters. You can use them to move columns of data into and out of database tables or between client-side applications and stored subprograms. Object types are used not only to create object relational tables, but also to define collections. You can use any of the three categories of collections: Nested tables can have any number of elements. Varrays is an ordered collection of elements. Associative arrays (known as “index-by tables” in earlier Oracle releases) are sets of key-value pairs, where each key is unique and is used to locate a corresponding value in the array. The key can be an integer or a string. Note: Associative arrays will not be emphasized in this appendix. Oracle Database 10g: SQL and PL/SQL New Features

391 Describing the Collection Types
Nested table: Varray: Collections (continued) PL/SQL offers two collection types: Nested Tables A nested table holds a set of values. That is, it is a table within a table. Nested tables are unbounded, meaning the size of the table can increase dynamically. Nested tables are available in both PL/SQL as well as the database. Within PL/SQL, nested tables are like one-dimensional arrays whose size can increase dynamically. Within the database, nested tables are column types that hold sets of values. The Oracle database stores the rows of a nested table in no particular order. When you retrieve a nested table from the database into a PL/SQL variable, the rows are given consecutive subscripts starting at 1. This gives you array-like access to individual rows. Nested tables are initially dense but they can become sparse through deletions and, therefore, have nonconsecutive subscripts. Varrays Variable-size arrays, or varrays, are also collections of homogeneous elements that hold a fixed number of elements (although you can change the number of elements at run time). They use sequential numbers as subscripts. You can define equivalent SQL types, allowing varrays to be stored in database tables. They can be stored and retrieved through SQL, but with less flexibility than nested tables. You can reference the individual elements for array operations, or manipulate the collection as a whole. Oracle Database 10g: SQL and PL/SQL New Features

392 Listing Characteristics for Collections
PL/SQL Nested Tables DB Nested Tables PL/SQL Varrays Maximum size No Yes Sparsity Can be Dense Storage N/A Stored out of line Stored inline (if < 4,000 bytes) Ordering Does not retain ordering and subscripts Retains ordering and subscripts Choosing a PL/SQL Collection Type If you already have code or business logic that uses some other language, you can usually translate that language’s array and set types directly to PL/SQL collection types. Arrays in other languages become varrays in PL/SQL. Sets and bags in other languages become nested tables in PL/SQL. Hash tables and other kinds of unordered lookup tables in other languages become associative arrays in PL/SQL. If you are writing original code or designing business logic from the start, consider the strengths of each collection type and decide which is appropriate. Choosing Between Nested Tables and Varrays Use varrays when: The number of elements is known in advance The elements are usually all accessed in sequence Use nested tables when: The index values are not consecutive There is no predefined upper bound for index values You need to delete or update some elements, but not all the elements at once You would usually create a separate lookup table, with multiple entries for each row of the main table, and access it through join queries Oracle Database 10g: SQL and PL/SQL New Features

393 Using Collections Effectively
Varrays involve fewer disk accesses and are more efficient. Use nested tables for storing large amounts of data. Use varrays to preserve the order of elements in the collection column. If you do not have a requirement to delete elements in the middle of a collection, favor varrays. Varrays do not allow piecewise updates. Guidelines for Using Collections Effectively Because varray data is stored inline (in the same tablespace), retrieving and storing varrays involves fewer disk accesses. Varrays are thus more efficient than nested tables. To store large amounts of persistent data in a column collection, use nested tables. This way the Oracle server can use a separate table to hold the collection data, which can grow over time. For example, when a collection for a particular row could contain 1 to 1,000,000 elements, a nested table is simpler to use. If your data set is not very large and it is important to preserve the order of elements in a collection column, use varrays. For example, if you know that in each row the collection will not contain more than 10 elements, you can use a varray with a limit of 10. If you do not want to deal with deletions in the middle of the data set, use varrays. If you expect to retrieve the entire collection simultaneously, use varrays. Varrays do not allow piecewise updates. Oracle Database 10g: SQL and PL/SQL New Features

394 Creating Collection Types
Nested table in the database: Nested table in PL/SQL: Varray in the database: Varray in PL/SQL: CREATE [OR REPLACE] TYPE type_name AS TABLE OF Element_datatype [NOT NULL]; TYPE type_name IS TABLE OF element_datatype [NOT NULL]; CREATE [OR REPLACE] TYPE type_name AS VARRAY (max_elements) OF element_datatype [NOT NULL]; Creating Collection Types To create a collection, you first define a collection type, and then declare collections of that type. The slide shows the syntax for defining nested table and varray collection types in both the database (persistent) and in PL/SQL (transient), and defining a string-indexed collection in PL/SQL. Creating Collections in the Database You can create a nested table or a varray data type in the database, which makes the data type available to use in places such as columns in database tables, variables in PL/SQL programs, and attributes of object types. Before you can define a database table containing a nested table or varray, you must first create the data type for the collection in the database. Use the syntax shown in the slide to create collection types in the database. Creating Collections in PL/SQL You can also create a nested table or a varray in PL/SQL. Use the syntax shown in the slide to create collection types in PL/SQL. Note: Collections can be nested. TYPE type_name IS VARRAY (max_elements) OF element_datatype [NOT NULL]; Oracle Database 10g: SQL and PL/SQL New Features

395 Declaring Collections: Nested Table
First, define an object type: Second, declare a column of that collection type: CREATE TYPE typ_item AS OBJECT --create object (prodid NUMBER(5), price NUMBER(7,2) ) / CREATE TYPE typ_item_nst -- define nested table type AS TABLE OF typ_item 1 CREATE TABLE pOrder ( -- create database table ordid NUMBER(5), supplier NUMBER(5), requester NUMBER(4), ordered DATE, items typ_item_nst) NESTED TABLE items STORE AS item_stor_tab / 2 Declaring Collections: Nested Table To create a table based on a nested table, perform the following steps: 1. Create the typ_item type, which holds the information for a single line item. 2. Create the typ_item_nst type, which is created as a table of the typ_item type. Note: You must create the typ_item_nst nested table type based on the previously declared type because it is illegal to declare multiple data types in this nested table declaration. 3. Create the pOrder table and use the nested table type in a column declaration, which will include an arbitrary number of items based on the typ_item_nst type. Thus, each row of pOrder may contain a table of items. The NESTED TABLE STORE AS clause is required to indicate the name of the storage table in which the rows of all the values of the nested table reside. The storage table is created in the same schema and the same tablespace as the parent table. Note: The USER_COLL_TYPES dictionary view holds information about collections. 3 Oracle Database 10g: SQL and PL/SQL New Features

396 Understanding Nested Table Storage
Nested tables are stored out-of-line in storage tables. pOrder nested table Supplier Requester Ordered Items 123 321 456 789 10-MAR-97 12-FEB-97 Storage table NESTED_TABLE_ID ProdID Price 901 879 $ $ Nested Table Storage The rows for all nested tables of a particular column are stored within the same segment. This segment is called the storage table. A storage table is a system-generated segment in the database that holds instances of nested tables within a column. You specify the name for the storage table by using the NESTED TABLE STORE AS clause in the CREATE TABLE statement. The storage table inherits storage options from the outermost table. To distinguish between nested table rows belonging to different parent table rows, a system-generated nested table identifier (unique for each outer row that encloses a nested table) is created. Operations on storage tables are performed implicitly by the system. You should not access or manipulate the storage table, except implicitly through its containing objects. Privileges of the column of the parent table are transferred to the nested table. 333 112 $ $300.00 Oracle Database 10g: SQL and PL/SQL New Features

397 Declaring Collections: Varray
First, define a collection type: Second, declare a collection of that type: CREATE TYPE typ_Project AS OBJECT( --create object project_no NUMBER(2), title VARCHAR2(35), cost NUMBER(7,2)) / CREATE TYPE typ_ProjectList AS VARRAY (50) OF typ_Project -- define VARRAY type 1 2 CREATE TABLE department ( -- create database table dept_id NUMBER(2), name VARCHAR2(15), budget NUMBER(11,2), projects typ_ProjectList) -- declare varray as column / 3 Example The example in the slide shows how to create a table based on a varray. 1. Create the typ_project type, which holds information for a project. 2. Create the typ_ projectlist type, which is created as a varray of the project type. The varray contains a maximum of 50 elements. Create the DEPARTMENT table and use the varray type in a column declaration. Each element of the varray stores a project object. This example demonstrates how to create a varray of phone numbers, and then use it in a CUSTOMERS table (The OE sample schema uses this definition.): CREATE TYPE phone_list_typ AS VARRAY(5) OF VARCHAR2(25); / CREATE TABLE customers (customer_id NUMBER(6) ,cust_first_name VARCHAR2(50) ,cust_last_name VARCHAR2(50) ,cust_address cust_address_typ(100) ,phone_numbers phone_list_typ ... ); Oracle Database 10g: SQL and PL/SQL New Features

398 Working with Collections in PL/SQL
You can declare collections as formal parameters of procedures and functions. You can specify a collection type in the RETURN clause of a function specification. Collections follow the usual scoping and instantiation rules. CREATE OR REPLACE PACKAGE manage_dept_proj AS TYPE typ_proj_details IS TABLE OF typ_Project; ... PROCEDURE allocate_proj (propose_proj IN typ_proj_details); FUNCTION top_project (n NUMBER) RETURN typ_proj_details; Working with Collections There are several points about collections that you must know when working with them: You can declare collections as the formal parameters of functions and procedures. That way, you can pass collections to stored subprograms and from one subprogram to another. A function’s RETURN clause can be a collection type. Collections follow the usual scoping and instantiation rules. In a block or subprogram, collections are instantiated when you enter the block or subprogram and cease to exist when you exit. In a package, collections are instantiated when you first reference the package and cease to exist when you end the database session. In the example in the slide, a nested table is used as the formal parameter of a packaged procedure, the data type of an IN parameter for the procedure ALLOCATE_PROJ, and the return data type of the TOP_PROJECT function. Oracle Database 10g: SQL and PL/SQL New Features

399 Initializing Collections
Three ways to initialize: Use a constructor. Fetch from the database. Assign another collection variable directly. DECLARE this example uses a constructor v_accounting_project typ_ProjectList; BEGIN v_accounting_project := typ_ProjectList (typ_Project (1, 'Dsgn New Expense Rpt', 3250), typ_Project (2, 'Outsource Payroll', 12350), typ_Project (3, 'Audit Accounts Payable',1425)); INSERT INTO department VALUES(10, 'Accounting', 123, v_accounting_project); ... END; / Initializing Collections Until you initialize it, a collection is atomically null (that is, the collection itself is null, not its elements). To initialize a collection, you can use one of the following means: Use a constructor, which is a system-defined function with the same name as the collection type. A constructor allows the creation of an object from an object type. Invoking a constructor is a way to instantiate (create) an object. This function “constructs” collections from the elements passed to it. In the example shown in the slide, you pass three elements to the typ_ProjectList() constructor, which returns a varray containing those elements. Read an entire collection from the database using a fetch. Assign another collection variable directly. You can copy the entire contents of one collection to another as long as both are built from the same data type. Oracle Database 10g: SQL and PL/SQL New Features

400 Initializing Collections
DECLARE this example uses a fetch from the database v_accounting_project typ_ProjectList; BEGIN SELECT projects INTO v_accounting_project FROM department WHERE dept_id = 10; ... END; / 1 DECLARE -- this example assigns another collection -- variable directly v_accounting_project typ_ProjectList; v_backup_project typ_ProjectList; BEGIN SELECT projects INTO v_accounting_project FROM department WHERE dept_id = 10; v_backup_project := v_accounting_project; END; / 2 Initializing Collections (continued) In the first example shown in the slide, an entire collection from the database is fetched into the local PL/SQL collection variable. In the second example shown in the slide, the entire contents of one collection variable are assigned to another collection variable. Oracle Database 10g: SQL and PL/SQL New Features

401 Referencing Collection Elements
Use the collection name and a subscript to reference a collection element: Syntax: Example: To reference a field in a collection: collection_name(subscript) v_accounting_project(1) v_accounting_project(1).cost Referencing Collection Elements Every element reference includes a collection name and a subscript enclosed in parentheses. The subscript determines which element is processed. To reference an element, you can specify its subscript by using the following syntax: collection_name(subscript) In the preceding syntax, subscript is an expression that yields a positive integer. For nested tables, the integer must lie in the range 1 to For varrays, the integer must lie in the range from 1 to maximum_size that you provide. Oracle Database 10g: SQL and PL/SQL New Features

402 Using Collection Methods
EXISTS COUNT LIMIT FIRST and LAST PRIOR and NEXT EXTEND TRIM DELETE Using Collection Methods You can use collection methods from procedural statements but not from SQL statements. collection_name.method_name [(parameters)] Oracle Database 10g: SQL and PL/SQL New Features

403 Using Collection Methods
Traverse collections with methods: DECLARE i INTEGER; v_accounting_project typ_ProjectList; BEGIN v_accounting_project := typ_ProjectList( typ_Project (1,'Dsgn New Expense Rpt', 3250), typ_Project (2, 'Outsource Payroll', 12350), typ_Project (3, 'Audit Accounts Payable',1425)); i := v_accounting_project.FIRST ; WHILE i IS NOT NULL LOOP IF v_accounting_project(i).cost > then DBMS_OUTPUT.PUT_LINE('Project too expensive: ' || v_accounting_project(i).title); END IF; i := v_accounting_project.NEXT (i); END LOOP; END; / Traversing Collections In the example shown, the FIRST method finds the smallest index number, the NEXT method traverses the collection starting at the first index. The output from this block of code shown above is: Project too expensive: Outsource Payroll You can use the PRIOR and NEXT methods to traverse collections indexed by any series of subscripts. In the example shown, the NEXT method is used to traverse a varray. PRIOR(n) returns the index number that precedes index n in a collection. NEXT(n) returns the index number that succeeds index n. If n has no predecessor, PRIOR(n) returns NULL. Likewise, if n has no successor, NEXT(n) returns NULL. PRIOR is the inverse of NEXT. PRIOR and NEXT do not wrap from one end of a collection to the other. When traversing elements, PRIOR and NEXT ignore deleted elements. Oracle Database 10g: SQL and PL/SQL New Features

404 Using Collection Methods
DECLARE v_my_projects typ_ProjectList; v_array_count INTEGER; v_last_element INTEGER; BEGIN SELECT projects INTO v_my_projects FROM department WHERE dept_id = 10; v_array_count := v_my_projects.COUNT ; dbms_output.put_line('The # of elements is: ' || v_array_count); v_my_projects.EXTEND ; --make room for new project v_last_element := v_my_projects.LAST ; dbms_output.put_line('The last element is: ' || v_last_element); IF v_my_projects.EXISTS(5) THEN dbms_output.put_line('Element 5 exists!'); ELSE dbms_output.put_line('Element 5 does not exist.'); END IF; END; / Example The block of code shown uses the COUNT, EXTEND, LAST, and EXISTS methods on the my_projects varray. The COUNT method reports that the projects collection holds three projects for department 10. The EXTEND method creates a fourth empty project. Using the LAST method reports that four projects exist. When testing for the existence of a fifth project, the program reports that it does not exist. The output from this block of code is as follows: The # of elements is: 3 The last element is: 4 Element 5 does not exist. PL/SQL procedure successfully completed. Oracle Database 10g: SQL and PL/SQL New Features

405 Manipulating Individual Elements
CREATE OR REPLACE PROCEDURE add_project ( p_deptno IN NUMBER, p_new_project IN typ_Project, p_position IN NUMBER ) IS v_my_projects typ_ProjectList; BEGIN SELECT projects INTO v_my_projects FROM department WHERE dept_id = p_deptno FOR UPDATE OF projects; v_my_projects.EXTEND; --make room for new project /* Move varray elements forward */ FOR i IN REVERSE p_position..v_my_projects.LAST - 1 LOOP v_my_projects(i + 1) := v_my_projects(i); END LOOP; v_my_projects(p_position) := p_new_project; -- add new -- project UPDATE department SET projects = v_my_projects WHERE dept_id = p_deptno; END add_project; / Manipulating Individual Elements You must use PL/SQL procedural statements to reference the individual elements of a varray in an INSERT, UPDATE, or DELETE statement. In the example shown in the slide, the stored procedure inserts a new project into a department’s projects at a given position. To execute the procedure, pass the department number to which you want to add a project, the project information, and the position where the project information is to be inserted. EXECUTE add_project(10, - typ_Project(4, 'Information Technology', 789), 4) SELECT * FROM department; DEPT_ID NAME BUDGET PROJECTS(PROJECT_NO, TITLE, COST) 10 Accounting PROJECTLIST(PROJECT(1, 'Dsgn New Expense Rpt', 3250), PROJECT(2, 'Outsource Payroll', 12350), PROJECT(3, 'Audit Accounts Payable', 1425), PROJECT(4, 'Information Technology', 789)) Oracle Database 10g: SQL and PL/SQL New Features

406 Avoiding Collection Exceptions
Common exceptions with collections: COLLECTION_IS_NULL NO_DATA_FOUND SUBSCRIPT_BEYOND_COUNT SUBSCRIPT_OUTSIDE_LIMIT VALUE_ERROR Avoiding Collection Exceptions In most cases, if you reference a nonexistent collection element, PL/SQL raises a predefined exception. Oracle Database 10g: SQL and PL/SQL New Features

407 Avoiding Collection Exceptions
Common exceptions with collections: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; atomically null BEGIN /* Assume execution continues despite the raised exceptions. */ nums(1) := 1; raises COLLECTION_IS_NULL nums := NumList(1,2); -- initialize table nums(NULL) := raises VALUE_ERROR nums(0) := 3; raises SUBSCRIPT_OUTSIDE_LIMIT nums(3) := 3; raises SUBSCRIPT_BEYOND_COUNT nums.DELETE(1); delete element 1 IF nums(1) = 1 THEN -- raises NO_DATA_FOUND ... Example In the first case, the nested table is atomically null. In the second case, the subscript is null. In the third case, the subscript is outside the legal range. In the fourth case, the subscript exceeds the number of elements in the table. In the fifth case, the subscript designates a deleted element. Oracle Database 10g: SQL and PL/SQL New Features

408 Oracle Database 10g: SQL and PL/SQL New Features 1 - 409
Summary In this lesson, you should have learned how to: Identify types of collections Nested tables Varrays Define nested tables and varrays in the database Define nested tables and varrays in PL/SQL Access collection elements Use collection methods in PL/SQL Identify raised exceptions with collections Decide which collection type is appropriate for each scenario Summary Collections are a grouping of elements, all of the same type. The types of collections are nested tables, varrays, and associative arrays. You can define nested tables in PL/SQL program units and in the database. Nested tables, varrays, and associative arrays can be used in a PL/SQL program. When using collections in PL/SQL programs, you can access collection elements, use predefined collection methods, and use exceptions that are commonly encountered with collections. There are guidelines for using collections effectively and to determine which collection type is appropriate under specific circumstances. Oracle Database 10g: SQL and PL/SQL New Features


Download ppt "Introduction."

Similar presentations


Ads by Google