Oracle Openworld Directory Index
New Oracle 9i & 8i Features Every i Developer Should Know
To Preserve Rows for Session:
Additional Information
DML statements on temporary tables do not generate redo logs for the data changes.
However, undo logs for the data and redo logs for the undo logs are generated.
Bulk Binds
New in Oracle8i, can significantly improve performance of “bulk” SQL statements
Used in conjunction with collections
Instead of “binding” each piece of a collection, an entire collection is passed back and forth to the SQL engine
Minimizes number of context switches between PL/SQL and SQL engines
FORALL Statement
Used to bulk bind input collections, in conjunction with DML statements
Iterates through collection, performing DML
Even though syntax is similar, it is not a FOR loop.
Syntax:
Basic Example
%BULK_ROWCOUNT(n)
Similar to scalar attributes of cursors (%ISOPEN, %FOUND, %NOTFOUND, and %ROWCOUNT)
Refers to an Index-By table, storing the number of rows processed by the nth execution of the DML statement within the FORALL construct
Uses same subscripts as FORALL
Not maintained for Inserts
Example
BULK COLLECT Clause
Used to bulk bind output collections within SQL engine, before returning to PL/SQL engine
SQL engine initializes and extends collections automatically, starting with a subscript of 1, overwriting data if necessary
Syntax:
FORALL and BULK COLLECT
SQL engine incrementally bulk binds column values
With each iteration of the FORALL, column values returned by the BULK COLLECT are added to the output collection (current values in the collection are not overwritten)
Example
Summary
Internal PL/SQL Enhancements
Case Expressions
New Internal Functions
New Data Types
Native Compilation of PL/SQL Code
Merge Statement
Autonomous Transactions
Triggers on System Events
Native Dynamic SQL
Global Temporary Tables
Bulk Binds with Collections
Fill Out a Survey and Get a Chance to Win a Compaq iPAQ!
We want to know what you think! Fill out the survey that was handed out at the beginning of the session for a chance to win a Compaq iPAQ. Remember to include your name and email in the available section and we will enter your name into two daily drawings to win an iPAQ
Tony Catalano, Vice President
catalanoa@tusc.com
377 E. Butterfield Road
Suite 100
Lombard, IL 60148
630-960-2909
800-755-TUSC
www.tusc.com
Copyright Information
Neither TUSC or the author guarantee this document to be error-free. Please provide comments/questions to catalanoa@tusc.com.
TUSC © 2001. This document cannot be reproduced without expressed written consent from an officer of TUSC
For More Information
www.tusc.com
www.odtug.com
metalink.oracle.com
technet.oracle.com
Sources
Oracle9i Application Developer's Guide - Fundamentals, Oracle Corporation
Getting to Know Oracle9i, Oracle Corporation
Oracle9i Concepts, Oracle Corporation
Oracle9i SQL Reference, Oracle Corporation
Oracle9i Reference, Oracle Corporation
---------
examples
DECLARE
customer_rating VARCHAR2(10);
customer_credit VARCHAR2(1);
BEGIN
customer_credit := 'B';
CASE customer_credit
WHEN 'A' THEN customer_rating := 'Rank 1';
WHEN 'B' THEN customer_rating := 'Rank 2';
WHEN 'C' THEN customer_rating := 'Rank 3';
ELSE customer_rating := 'Rank 5';
END CASE;
DBMS_OUTPUT.PUT_LINE('Customer Ranking: ' ||
customer_rating);
END;
/
DECLARE
customer_rating VARCHAR2(10);
customer_credit VARCHAR2(1);
BEGIN
customer_credit := 'B';
CASE
WHEN customer_credit='A' THEN customer_rating:='Rank 1';
WHEN customer_credit='B' THEN customer_rating:='Rank 2';
WHEN customer_credit='C' THEN customer_rating:='Rank 3';
ELSE customer_rating:='Rank 5';
END CASE;
DBMS_OUTPUT.PUT_LINE('Customer Ranking: ' ||
customer_rating);
END;
/
-------
DECLARE
x1 PLS_INTEGER := 1234;
x2 PLS_INTEGER := 1234;
x3 PLS_INTEGER;
x4 PLS_INTEGER;
x5 PLS_INTEGER;
x6 PLS_INTEGER;
BEGIN
x5 := NULLIF(x1, x2);
x6 := COALESCE(x3, x4, 4321);
DBMS_OUTPUT.PUT_LINE('x5: ' || x5);
DBMS_OUTPUT.PUT_LINE('x6: ' || x6);
END;
/
x5:
x6: 4321
PL/SQL procedure successfully completed.
------
DESCRIBE user_stored_settings
Name Null? Type
----------------------- -------- -----------------
OBJECT_NAME NOT NULL VARCHAR2(30)
OBJECT_ID NOT NULL NUMBER
OBJECT_TYPE VARCHAR2(12)
PARAM_NAME NOT NULL VARCHAR2(30)
PARAM_VALUE VARCHAR2(4000)
SELECT *
FROM user_stored_settings;
no rows selected
-------
CREATE PROCEDURE xyz AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello');
END;
/
Procedure created.
SET SERVEROUTPUT ON
EXECUTE xyz
Hello
PL/SQL procedure successfully completed.
--------
SELECT *
FROM user_stored_settings;
OBJECT OBJ_ID OBJ_TYPE PARAM_NAME PARAM_VALUE
------ ------ --------- -------------------- ------------
XYZ 32506 PROCEDURE plsql_compiler_flags INTERPRETED,
NON_DEBUG
XYZ 32506 PROCEDURE nls_length_semantics BYTE
ALTER SESSION SET plsql_compiler_flags = native;
Session altered.
CREATE PROCEDURE abc AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Good Bye');
END;
/
---------
SET SERVEROUTPUT ON
EXECUTE abc
Good Bye
PL/SQL procedure successfully completed.
SELECT *
FROM user_stored_settings
WHERE object_name = 'ABC';
OBJECT OBJ_ID OBJ_TYPE PARAM_NAME PARAM_VALUE
------ ------ --------- -------------------- -------------
ABC 32508 PROCEDURE plsql_compiler_flags NATIVE,NON_DE
BUG
ABC 32508 PROCEDURE nls_length_semantics BYTE
---------
MERGE INTO employee_master dest
USING
(SELECT emp_id, start_date, salary, title
FROM adp_employee_master@adp) orig
ON (dest.emp_id = orig.emp_id)
WHEN MATCHED THEN UPDATE
SET dest.salary = orig.salary,
dest.title = orig.title
WHEN NOT MATCHED THEN
INSERT (dest.emp_id, dest.start_date, dest.salary, dest.title)
VALUES
(orig.emp_id, orig.start_date, orig.salary, orig.title);
--------
CREATE PACKAGE billing AS
FUNCTION generate_late_charges (client_id INTEGER)
RETURN REAL;
END billing;
CREATE PACKAGE BODY billing AS
FUNCTION generate_late_charges (client_id INTEGER)
RETURN REAL IS
PRAGMA AUTONOMOUS_TRANSACTION;
Client_charge REAL;
BEGIN
INSERT …
END;
END billing;
-----
PROCEDURE ilog_error_auto ( p_package_c IN varchar2 default 'UNKNOWN',
p_procedure_c IN varchar2 default 'UNKNOWN',
p_location_c IN varchar2 default 'UNKNOWN',
p_error_c IN varchar2 default 'UNKNOWN',
p_text_c IN varchar2 default 'NONE',
p_user_c IN varchar2 default NULL,
p_error_time IN date default NULL) is
-- Make the DML in this procedure autonomous to pending transactions
PRAGMA AUTONOMOUS_TRANSACTION;
v_error_stack_c varchar2(500);
v_global_vars_c varchar2(1000);
v_call_stack_c varchar2(500);
BEGIN
-- Capture the Call Stack.
v_call_stack_c := substr(dbms_utility.format_call_stack, 1, 500);
-- Capture the Error Stack.
v_error_stack_c := substr(dbms_utility.format_error_stack, 1, 500);
-- Capture Gloval Variables.
v_global_vars_c := substr(capture_globals, 1, 1000);
-- Insert system error
insert
into lss_system_errors (serror_id, package_name, procedure_name,
execution_location, oracle_error_text, additional_information,
global_variables, call_stack, error_stack,
insert_time,insert_user)
values (lss_serror_id_seq.nextval,
substr(p_package_c, 1, 50),
substr(p_procedure_c, 1, 50),
substr(p_location_c, 1, 20),
substr(p_error_c, 1, 200),
substr(p_text_c, 1, 4000),
substr(v_global_vars_c, 1, 4000),
substr(v_call_stack_c, 1, 2000),
substr(v_error_stack_c, 1, 2000),
nvl(p_error_time, sysdate),
substr(nvl(p_user_c, user), 1, 30));
commit;
END ilog_error_auto;
--------
CREATE OR REPLACE TRIGGER audit_inventory
AFTER UPDATE OR DELETE ON s_inventory
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO s_inventory_audit
( audited_user, audit_time, old_product_id, old_warehouse_id,
old_amount_in_stock, old_reorder_point, new_product_id,
new_warehouse_id, new_amount_in_stock, new_reorder_point)
VALUES ( USER, SYSDATE,
:OLD.product_id, :OLD.warehouse_id, :OLD.amount_in_stock,
:OLD.reorder_point, :NEW.product_id, :NEW.warehouse_id,
:NEW.amount_in_stock, :NEW.reorder_point );
COMMIT;
END;
------
create table source_history (change_dt date not null, owner varchar2(30) not null, name varchar2(30) not null, type varchar2(20), line number not null, text varchar2(4000));
create or replace trigger source_historyafter create on databasedeclare v_sysdate date := sysdate;begin insert into source_history (select v_sysdate, ds.owner, ds.name,
ds.type, ds.line, ds.text from dba_source ds where ora_dict_obj_owner = ds.owner and ora_dict_obj_name = ds.name and ora_dict_obj_type = ds.type);end source_history;