http://www.joegarrepy.com/oracle_nestedtables.htm
/*
-- ****************************************************************** --
9/30/2003 NESTED TABLES Create Script (Joe Garrepy) VERSION 1.0
-- ****************************************************************** --
The following script creates several TYPE objects and one TABLE object
to illustrate the creation of NESTED tables. The script also shows
how to insert rows into the Regular table and also work with percision
on the nested tables (all DML statements). It also contains SQL code
to bring back values from the table.
-- ****************************************************************** --
*/
--> Create Name Column with "ROW" Type and "TABLE" Type
CREATE OR REPLACE TYPE "ROW_NAME"
AS OBJECT
(FIRST VARCHAR2(60),
LAST VARCHAR2(60),
MIDDLE VARCHAR2(30),
PREFIX VARCHAR2(10),
SUFFIX VARCHAR2(10),
CREATE_DATE DATE,
CHANGE_DATE DATE,
CREATE_USER VARCHAR2(30),
CHANGE_USER VARCHAR2(30))
/
CREATE OR REPLACE TYPE "TAB_NAME"
AS TABLE OF ROW_NAME
/
--> Create Person Column with "ROW" Type and "TABLE" Type
CREATE OR REPLACE TYPE "ROW_PERSON"
AS OBJECT
(SSN VARCHAR2(9),
GENDER VARCHAR2(1),
BDATE DATE,
ETHNICITY VARCHAR2(2),
MARITAL_STATUS VARCHAR2(2),
HAIR VARCHAR2(10),
EYES VARCHAR2(10),
HEIGHT VARCHAR2(10),
CREATE_DATE DATE,
CHANGE_DATE DATE,
CREATE_USER VARCHAR2(30),
CHANGE_USER VARCHAR2(30))
/
CREATE OR REPLACE TYPE "TAB_PERSON"
AS TABLE OF ROW_PERSON
/
--> Create Employment Column with "ROW" Type and "TABLE" Type
CREATE OR REPLACE TYPE "ROW_EMPLOYMENT"
AS OBJECT
(JOB_TITLE VARCHAR2(60),
START_DATE DATE,
TERMINATED VARCHAR2(1),
END_DATE DATE,
SALARY NUMBER(8,4),
CREATE_DATE DATE,
CHANGE_DATE DATE,
CREATE_USER VARCHAR2(30),
CHANGE_USER VARCHAR2(30)
)
/
CREATE OR REPLACE TYPE "TAB_EMPLOYMENT"
AS TABLE OF ROW_EMPLOYMENT
/
--> Create table with UID and TAB_NAME & TAB_PERSON tables as columns
CREATE TABLE "ENTITY"
( "UIDN" NUMBER(10) NOT NULL,
"NAME" "TAB_NAME" DEFAULT "TAB_NAME"(),
"PERSON" "TAB_PERSON" DEFAULT "TAB_PERSON"(),
"EMPLOYMENT" "TAB_EMPLOYMENT" DEFAULT "TAB_EMPLOYMENT"(),
"DEAD" VARCHAR2(1) DEFAULT 'N',
"DEAD_DATE" DATE,
"CREATE_DATE" DATE DEFAULT SYSDATE NOT NULL ENABLE,
"CHANGE_DATE" DATE,
"CREATE_USER" VARCHAR2(30) DEFAULT USER,
"CHANGE_USER" VARCHAR2(30),
PRIMARY KEY ("UIDN"))
NESTED TABLE "NAME" STORE AS "ENTITY_NAME"
NESTED TABLE "PERSON" STORE AS "ENTITY_PERSON"
NESTED TABLE "EMPLOYMENT" STORE AS "ENTITY_EMPLOYMENT"
/
COMMENT ON TABLE "ENTITY" IS 'Entity Base Table with repeating data as Nested Tables';
COMMENT ON COLUMN "ENTITY"."UIDN" IS 'Unique Identifaction Number/KEY';
COMMENT ON COLUMN "ENTITY"."NAME" IS 'Nested Table Storing Name Data for an entity';
COMMENT ON COLUMN "ENTITY"."PERSON" IS 'Nested Table Storing Person Data for an entity';
COMMENT ON COLUMN "ENTITY"."EMPLOYMENT" IS 'Nested Table Storing Employment related data for an entity';
COMMENT ON COLUMN "ENTITY"."DEAD" IS 'Y if entity is dead else N';
COMMENT ON COLUMN "ENTITY"."DEAD_DATE" IS 'Date of Death';
--> Now lets insert some records
INSERT INTO entity VALUES
(1,TAB_NAME(ROW_NAME('Orion','Pax',NULL,NULL,NULL,SYSDATE,NULL,USER,NULL),
ROW_NAME('Optimus','Prime',NULL,NULL,NULL,SYSDATE,NULL,USER,NULL)),
TAB_PERSON(ROW_PERSON('000000000','M','01-JAN-1985','AB',NULL,NULL,NULL,'10 meters',SYSDATE,NULL,USER,NULL)),
TAB_EMPLOYMENT(ROW_EMPLOYMENT('Autobot Leader','01-JAN-1985',NULL,NULL,1000,SYSDATE,NULL,USER,NULL)),
'N',NULL,SYSDATE,NULL,USER,NULL);
INSERT INTO entity VALUES
(2,TAB_NAME(ROW_NAME('Megatron',NULL,NULL,NULL,NULL,SYSDATE,NULL,USER,NULL)),
TAB_PERSON(ROW_PERSON('000000001','M','01-JAN-1985','DC',NULL,NULL,NULL,'10 meters',SYSDATE,NULL,USER,NULL)),
TAB_EMPLOYMENT(ROW_EMPLOYMENT('Decepticon Leader','01-JAN-1985',NULL,NULL,995,SYSDATE,NULL,USER,NULL)),
'N',NULL,SYSDATE,NULL,USER,NULL);
COMMIT;
--> View what whe have inserted by flatening out the column collections
SELECT src.uidn,
n.*,
p.*,
e.*,
dead,
dead_date,
src.create_date,
src.change_date,
src.create_user,
src.change_user
FROM ENTITY src,
TABLE(src.name) n,
TABLE(src.person) p,
TABLE(src.employment) e;
--> Insert specific records into column of collections
/* Megatron's name changed during Transformers the Movie so lets insert
a new record into the collection for Names.
The first thing that needs to be done is to get the base record from
the entity and the column with the collection that we want to update
table we do so with this statement
INSERT INTO
TABLE(select entity.name
from entity
where entity.uidn = 2)
The next part of the insert involves adding a record to the collection
column
('Galvatron',NULL,NULL,NULL,
NULL,SYSDATE,NULL,USER,NULL)
*/
INSERT INTO
TABLE(select entity.name
from entity
where entity.uidn = 2)
VALUES
('Galvatron',NULL,NULL,NULL,
NULL,SYSDATE,NULL,USER,NULL);
COMMIT;
--> Update specific records inside of column collections
/* We'll use a similiar method to update Megatrons Galvatron's
NAME record to have a last name
*/
UPDATE TABLE(select entity.name
from entity
where entity.uidn = 2)
SET last = 'Decepticon',
change_date = SYSDATE,
change_user = USER
WHERE first = 'Galvatron';
COMMIT;
--> Delete specific records inside of column collections
/* Eventually Galvatron's name returns to being Megatron,
so lets delete out the Galvatron record from the NAME
collection
*/
DELETE TABLE(select entity.name
from entity
where entity.uidn = 2)
WHERE first = 'Galvatron';
COMMIT;
Thursday, April 19, 2012
Tuesday, April 17, 2012
Oracle Pipelined table functions
http://www.oracle-base.com/articles/misc/pipelined-table-functions.php
http://www.joegarrepy.com/pipelined_function.htmhttp://www.akadia.com/services/ora_pipe_functions.html
Overview
Basically, when you would like a PLSQL (or java or c) routine to be the «source» | |
Using PL/SQL table functions can significantly lower the over-head of doing such transformations. PL/SQL table functions accept and return multiple rows, delivering them as they are ready rather than all at once, and can be made to execute as parallel operations.
Simple Example - Generating Some Random Data
Typical Pipelined Example
This are the typical steps to perform when using PL/SQL Table Functions:
Conclusion
Pipelined functions are useful if there is a need for a data source other than a table in a select statement. |
Wednesday, April 11, 2012
Wednesday, April 4, 2012
Search condition Case Statement
SET SERVEROUTPUT ON SIZE 1000000;
DECLARE
n_salary EMPLOYEES.SALARY%TYPE;
n_emp_id EMPLOYEES.EMPLOYEE_ID%TYPE := 200;
v_msg VARCHAR(20);
BEGIN
SELECT salary INTO n_salary FROM employees WHERE employee_id = n_emp_id; CASE
WHEN n_salary < 2000 THEN
v_msg := 'Low';
WHEN n_salary >= 2000 AND n_salary <=3000
THEN
v_msg := 'Fair';
WHEN n_salary >= 3000 THEN
v_msg := 'High';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_msg);
END;
/
DECLARE
n_salary EMPLOYEES.SALARY%TYPE;
n_emp_id EMPLOYEES.EMPLOYEE_ID%TYPE := 200;
v_msg VARCHAR(20);
BEGIN
SELECT salary INTO n_salary FROM employees WHERE employee_id = n_emp_id; CASE
WHEN n_salary < 2000 THEN
v_msg := 'Low';
WHEN n_salary >= 2000 AND n_salary <=3000
THEN
v_msg := 'Fair';
WHEN n_salary >= 3000 THEN
v_msg := 'High';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_msg);
END;
/
Tuesday, April 3, 2012
Update PK - Deferrable constraints
http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_12.shtml
Oracle Constraints - All in one page details
http://psoug.org/reference/constraints.html
Deferred Integrity Constraints in Oracle8
by Jeff Hunter, Sr. Database Administrator
Introduction
Up until the release of Oracle8, all integrity constraints in the database where considered immediate constraints. With an immediate constraint, if a user enters data that violates a constraint, the statement is rolled back and Oracle signals an error. With the introduction of Oracle8, users now have the option of selecting between immediate and a new option called deferred itegrity constraints.
Deferred Integrity Constraints
Deferred integrity constraints are those that are not enforced until the user attempts to commit the transaction. At the time of the commit, if any data entered during the transaction violates an integrity constraint, Oracle will then rollback the entire transaction and signal an error to the user.
Why use deferrable integrity constraints?
One use is pure laziness. In Oracle7, users had no way of entering data into a child table before entering the matching data into the parent table. With Oracle8, users now have the option of inserting data into a child table before insert its matching data into the parent table by simply deferring the foreign-key constraint.
Another feature is speed. Anyone that has ever dealt with inserting large amounts of data into a table, like found in a data warehousing environment, know of the cost loading (inserting) data into tables. Deferring the integrity checking until after the data has loaded can save considerable time when dealing with large volumes of data being inserted into tables.
Solving design issues. Take for example the two tables ORDER and ORDER LINE. In this model, we cannot have an ORDER LINE unless we have an ORDER, but we also assert that all ORDERS must have ORDER LINES. This catch-22 issue can easily be resolved by deferring all integrity constraints until the time of the commit.
Warnings
Deferred integrity constraints should only be used when absolutely necessary. If at all possible, avoid hard-coding constraint names with your application code. Deferring integrity constraints should only be used when solving a design issue. Be aware that very few applications support commit time errors.
Statements
To defer ALL constraints that are deferrable during the entire session, you can use the alter session set constraints=deferred statement.
A user can defer a named or all constraints that are deferrable for a specific transaction using the set constraint name deferred or set constraint all deferred.
The user process may also set constraints for immediate enforcement for a specific transaction using the set constraint name immediate or set constraint all immediate.
Are all constraints deferrable?
Not all constraints in the database can be set to deferrable. Only when the constraint is created with the deferrable option can user processes set the constraint as deferrable. If the constraint is created with the not deferrable option (the default), then user processes will always be bound by immediate integrity constraint.
Default behavior of constraints
Along with defining whether a constraint is deferrable or not, you can also set its default behavior with the initially deferred and initially immediate statement. The initially deferred option will enable the constraint as deferrable by default whereas the initially immediate option requires the user process to explicitly set the transaction or session to deferrable.
NOTE: The initially deferred and not deferrable keyword are mutually exclusive.
New columns in the CONSTRAINTS view
There are new columns in the "USER_CONSTRAINTS/DBA_CONSTRAINTS/ALL_CONSTRAINTS" views that will give you information on whether the constraint is deferrable. For example:
SELECT
constraint_name
, deferrable
, deferred
FROM user_constraints
WHERE constraint_name like 'EMP%';
CONSTRAINT_NAME DEFERRABLE DEFERRED
------------------------------ -------------- ---------
EMP_PRIMARY_KEY NOT DEFERRABLE IMMEDIATE
EMP_SELF_KEY NOT DEFERRABLE IMMEDIATE
EMP_FOREIGN_KEY DEFERRABLE DEFERRED
Example
REM -- ---------------------
REM -- Create example tables
REM -- ---------------------
DROP TABLE emp;
DROP TABLE dept;
CREATE TABLE dept (
deptno NUMBER(2) NOT NULL
, dname CHAR(14)
, loc CHAR(13)
, CONSTRAINT dept_pk PRIMARY KEY (deptno)
);
INSERT INTO dept VALUES (10,'FINANCE','PITTSBURGH');
INSERT INTO dept VALUES (20,'SALES','NEW YORK');
INSERT INTO dept VALUES (30,'OPERATIONS','BOSTON');
COMMIT;
CREATE TABLE emp (
empno NUMBER(4) NOT NULL
, ename CHAR(10)
, job CHAR(9)
, deptno NUMBER(2) NOT NULL
, CONSTRAINT emp_fk1 FOREIGN KEY (deptno)
REFERENCES dept (deptno)
DEFERRABLE
INITIALLY IMMEDIATE
, CONSTRAINT emp_pk PRIMARY KEY (empno)
);
INSERT INTO emp VALUES (1001, 'JEFF', 'PRESIDENT', 10);
INSERT INTO emp VALUES (1002, 'MELODY', 'MANAGER', 30);
INSERT INTO emp VALUES (1003, 'MARK', 'MANAGER', 10);
INSERT INTO emp VALUES (1004, 'MARTIN', 'MANAGER', 20);
COMMIT;
REM -- -------------------------------
REM -- Try to delete from parent table
REM -- -------------------------------
DELETE FROM dept WHERE deptno = 10;
ERROR at line 1:
ORA-02292: integrity constraint (OPS$ORACLE.EMP_FK1) violated - child record found
REM -- --------------------------------------------------------
REM -- Set this transaction to defer all deferrable constraints
REM -- --------------------------------------------------------
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM dept WHERE deptno = 10;
1 row deleted.
COMMIT;
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02292: integrity constraint (OPS$ORACLE.EMP_FK1) violated - child record found
Toms Discussion,
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:914629004506
Oracle Constraints - All in one page details
http://psoug.org/reference/constraints.html
Deferred Integrity Constraints in Oracle8
by Jeff Hunter, Sr. Database Administrator
Introduction
Up until the release of Oracle8, all integrity constraints in the database where considered immediate constraints. With an immediate constraint, if a user enters data that violates a constraint, the statement is rolled back and Oracle signals an error. With the introduction of Oracle8, users now have the option of selecting between immediate and a new option called deferred itegrity constraints.
Deferred Integrity Constraints
Deferred integrity constraints are those that are not enforced until the user attempts to commit the transaction. At the time of the commit, if any data entered during the transaction violates an integrity constraint, Oracle will then rollback the entire transaction and signal an error to the user.
Why use deferrable integrity constraints?
One use is pure laziness. In Oracle7, users had no way of entering data into a child table before entering the matching data into the parent table. With Oracle8, users now have the option of inserting data into a child table before insert its matching data into the parent table by simply deferring the foreign-key constraint.
Another feature is speed. Anyone that has ever dealt with inserting large amounts of data into a table, like found in a data warehousing environment, know of the cost loading (inserting) data into tables. Deferring the integrity checking until after the data has loaded can save considerable time when dealing with large volumes of data being inserted into tables.
Solving design issues. Take for example the two tables ORDER and ORDER LINE. In this model, we cannot have an ORDER LINE unless we have an ORDER, but we also assert that all ORDERS must have ORDER LINES. This catch-22 issue can easily be resolved by deferring all integrity constraints until the time of the commit.
Warnings
Deferred integrity constraints should only be used when absolutely necessary. If at all possible, avoid hard-coding constraint names with your application code. Deferring integrity constraints should only be used when solving a design issue. Be aware that very few applications support commit time errors.
Statements
To defer ALL constraints that are deferrable during the entire session, you can use the alter session set constraints=deferred statement.
A user can defer a named or all constraints that are deferrable for a specific transaction using the set constraint name deferred or set constraint all deferred.
The user process may also set constraints for immediate enforcement for a specific transaction using the set constraint name immediate or set constraint all immediate.
Are all constraints deferrable?
Not all constraints in the database can be set to deferrable. Only when the constraint is created with the deferrable option can user processes set the constraint as deferrable. If the constraint is created with the not deferrable option (the default), then user processes will always be bound by immediate integrity constraint.
Default behavior of constraints
Along with defining whether a constraint is deferrable or not, you can also set its default behavior with the initially deferred and initially immediate statement. The initially deferred option will enable the constraint as deferrable by default whereas the initially immediate option requires the user process to explicitly set the transaction or session to deferrable.
NOTE: The initially deferred and not deferrable keyword are mutually exclusive.
New columns in the CONSTRAINTS view
There are new columns in the "USER_CONSTRAINTS/DBA_CONSTRAINTS/ALL_CONSTRAINTS" views that will give you information on whether the constraint is deferrable. For example:
SELECT
constraint_name
, deferrable
, deferred
FROM user_constraints
WHERE constraint_name like 'EMP%';
CONSTRAINT_NAME DEFERRABLE DEFERRED
------------------------------ -------------- ---------
EMP_PRIMARY_KEY NOT DEFERRABLE IMMEDIATE
EMP_SELF_KEY NOT DEFERRABLE IMMEDIATE
EMP_FOREIGN_KEY DEFERRABLE DEFERRED
Example
REM -- ---------------------
REM -- Create example tables
REM -- ---------------------
DROP TABLE emp;
DROP TABLE dept;
CREATE TABLE dept (
deptno NUMBER(2) NOT NULL
, dname CHAR(14)
, loc CHAR(13)
, CONSTRAINT dept_pk PRIMARY KEY (deptno)
);
INSERT INTO dept VALUES (10,'FINANCE','PITTSBURGH');
INSERT INTO dept VALUES (20,'SALES','NEW YORK');
INSERT INTO dept VALUES (30,'OPERATIONS','BOSTON');
COMMIT;
CREATE TABLE emp (
empno NUMBER(4) NOT NULL
, ename CHAR(10)
, job CHAR(9)
, deptno NUMBER(2) NOT NULL
, CONSTRAINT emp_fk1 FOREIGN KEY (deptno)
REFERENCES dept (deptno)
DEFERRABLE
INITIALLY IMMEDIATE
, CONSTRAINT emp_pk PRIMARY KEY (empno)
);
INSERT INTO emp VALUES (1001, 'JEFF', 'PRESIDENT', 10);
INSERT INTO emp VALUES (1002, 'MELODY', 'MANAGER', 30);
INSERT INTO emp VALUES (1003, 'MARK', 'MANAGER', 10);
INSERT INTO emp VALUES (1004, 'MARTIN', 'MANAGER', 20);
COMMIT;
REM -- -------------------------------
REM -- Try to delete from parent table
REM -- -------------------------------
DELETE FROM dept WHERE deptno = 10;
ERROR at line 1:
ORA-02292: integrity constraint (OPS$ORACLE.EMP_FK1) violated - child record found
REM -- --------------------------------------------------------
REM -- Set this transaction to defer all deferrable constraints
REM -- --------------------------------------------------------
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM dept WHERE deptno = 10;
1 row deleted.
COMMIT;
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02292: integrity constraint (OPS$ORACLE.EMP_FK1) violated - child record found
Toms Discussion,
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:914629004506
Sunday, April 1, 2012
Create XML Schema on the FLY
OTN Thread to create XML on the FLY
https://forums.oracle.com/forums/thread.jspa?threadID=426163
CREATE OR REPLACE
PROCEDURE GEN_XML_SCHEMA_OUTPUT
(p_schema_name VARCHAR2, p_table_name VARCHAR2) AS
CURSOR c_table_columns(c_table_name varchar2, c_schema_name varchar2) IS
SELECT column_name, data_type, data_default
FROM all_tab_columns
WHERE table_name = c_table_name
AND owner = c_schema_name;
l_col_str VARCHAR2(2000);
BEGIN
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('<'>');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('');
FOR l_cur_table_columns IN c_table_columns(p_table_name, p_schema_name) LOOP
l_col_str := ' ELSIF l_cur_table_columns.data_type = 'NUMBER' THEN
l_col_str := l_col_str || 'xs:integer' || '"';
ELSIF l_cur_table_columns.data_type = 'DATE' THEN
l_col_str := l_col_str || 'xs:date' || '"';
END IF;
IF l_cur_table_columns.data_default IS NOT NULL THEN
l_col_str := l_col_str || ' default="' || TRIM(l_cur_table_columns.data_default) || '"';
END IF;
l_col_str := l_col_str || '/>';
DBMS_OUTPUT.PUT_LINE( l_col_str);
END LOOP;
DBMS_OUTPUT.PUT_LINE( ' ');
DBMS_OUTPUT.PUT_LINE( ' ');
DBMS_OUTPUT.PUT_LINE( ''>');
END;
https://forums.oracle.com/forums/thread.jspa?threadID=426163
CREATE OR REPLACE
PROCEDURE GEN_XML_SCHEMA_OUTPUT
(p_schema_name VARCHAR2, p_table_name VARCHAR2) AS
CURSOR c_table_columns(c_table_name varchar2, c_schema_name varchar2) IS
SELECT column_name, data_type, data_default
FROM all_tab_columns
WHERE table_name = c_table_name
AND owner = c_schema_name;
l_col_str VARCHAR2(2000);
BEGIN
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('
DBMS_OUTPUT.PUT_LINE('<'>');
DBMS_OUTPUT.PUT_LINE('
DBMS_OUTPUT.PUT_LINE('
FOR l_cur_table_columns IN c_table_columns(p_table_name, p_schema_name) LOOP
l_col_str := '
l_col_str := l_col_str || 'xs:integer' || '"';
ELSIF l_cur_table_columns.data_type = 'DATE' THEN
l_col_str := l_col_str || 'xs:date' || '"';
END IF;
IF l_cur_table_columns.data_default IS NOT NULL THEN
l_col_str := l_col_str || ' default="' || TRIM(l_cur_table_columns.data_default) || '"';
END IF;
l_col_str := l_col_str || '/>';
DBMS_OUTPUT.PUT_LINE( l_col_str);
END LOOP;
DBMS_OUTPUT.PUT_LINE( '
DBMS_OUTPUT.PUT_LINE( '
DBMS_OUTPUT.PUT_LINE( ''>');
END;
Subscribe to:
Comments (Atom)