ACE Director Alum Daniel Morgan, founder of Morgan's Library, is scheduling
complimentary technical Workshops on Database Security for the first 30
Oracle Database customers located anywhere in North America, EMEA, LATAM, or
APAC that send an email to
asra_us@oracle.com. Request a Workshop for
your organization today.
Condition Precedence
SQL Operators are evaluated before conditions
Order
Operator
1
=, !=, <, >, <=, >=, !=, <>, ^=, ~=
2
IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT] IN, EXISTS, IS OF TYPE
Tests object instances based on specific type information
conn uwclass/uwclass@pdbdev
CREATE TYPE person_t AS OBJECT
(name VARCHAR2(30), ssn NUMBER) NOT FINAL;
/
CREATE TYPE employee_t UNDER person_t
(dept_id NUMBER, salary NUMBER) NOT FINAL;
/
CREATE TYPE part_time_emp_t UNDER employee_t
(num_hrs NUMBER);
/
CREATE TABLE persons OF person_t;
INSERT INTO persons VALUES (person_t('Morgan',1234));
INSERT INTO persons VALUES (employee_t('Morle',32456,12,10000));
INSERT INTO persons VALUES (part_time_emp_t('Kyte',5678,13,1000,20));
SELECT *
FROM persons;
SELECT *
FROM persons p
WHERE VALUE(p) IS OF TYPE (employee_t);
SELECT owner, table_name
FROM all_tables
WHERE owner IN ('SYS', 'SYSTEM');
IN (subquery)
<value_or_expression> IN (<subquery_result>)
SELECT owner, table_name
FROM all_tables
WHERE initial_extent IN (
SELECT MIN(initial_extent)
FROM all_tables);
NOT IN Antijoin
<value_or_expression> NOT IN (<expression_list>)
SELECT owner, table_name
FROM all_tables
WHERE initial_extent NOT IN (
SELECT MIN(initial_extent)
FROM all_tables);
Complex IN Demo Using CAST
-- based on emp table in scott/tiger
set serveroutput on
DECLARE
i PLS_INTEGER;
InStr VARCHAR2(20) := '10';
BEGIN
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno IN (InStr);
dbms_output.put_line(i);
END;
/
--==============================
DECLARE
i PLS_INTEGER;
InStr VARCHAR2(20) := '10,30';
BEGIN
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno IN (InStr);
dbms_output.put_line(i);
END;
/
--==============================
CREATE OR REPLACE TYPE InStrTab IS TABLE OF VARCHAR2(20);
/
DECLARE
i PLS_INTEGER;
x InStrTab := InStrTab('10','30');
BEGIN
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno IN (
SELECT column_value
FROM TABLE(CAST(x AS InStrTab)));
dbms_output.put_line(i);
END;
/
or
DECLARE
i PLS_INTEGER;
x InStrTab := InStrTab('10','30');
BEGIN
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno IN (
SELECT column_value
FROM TABLE(x));
dbms_output.put_line(i);
END;
/
MEMBER OF
Tests whether an element is a member of a nested table
conn oe/oe@pdbdev
CREATE TABLE customer_demo AS
SELECT *
FROM oe.customers;
CREATE OR REPLACE TYPE cust_address_tab_typ AS
TABLE OF cust_address_typ;
/
ALTER TABLE customer_demo
ADD (cust_address_ntab cust_address_tab_typ)
NESTED TABLE cust_address_ntab STORE AS cust_add_ntab_store;
desc customer_demo
UPDATE customer_demo cd
SET cust_address_ntab = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ);
SELECT customer_id, cust_address_ntab
FROM customer_demo
WHERE cust_address_typ(';8768 N State Rd 37';, 47404, ';Bloomington';, ';IN';, ';US';)
MEMBER OF cust_address_ntab;
conn scott/tiger@pdbdev
CREATE OR REPLACE TYPE deptno_t IS TABLE OF NUMBER(2);
/
set serveroutput on
DECLARE
dept_array deptno_t;
CURSOR empcur IS
SELECT e.ename
FROM emp e
WHERE e.deptno MEMBER OF (dept_array);
BEGIN
SELECT deptno BULK COLLECT INTO dept_array
FROM dept WHERE deptno IN (10,30);
FOR emprec IN empcur LOOP
dbms_output.put_line(emprec.ename);
END LOOP;
END;
/
NOT MEMBER OF
set serveroutput on
DECLARE
i PLS_INTEGER;
x InStrTab := InStrTab(10,30);
BEGIN
SELECT deptno BULK COLLECT INTO x
FROM dept WHERE deptno IN (10,30);
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno NOT MEMBER OF (x);
dbms_output.put_line(i);
END;
/
Complex IN Demo Using MEMBER OF
conn scott/tiger@pdbdev
CREATE OR REPLACE TYPE InStrTab IS TABLE OF NUMBER(2);
/
set serveroutput on
DECLARE
i PLS_INTEGER;
x InStrTab := InStrTab(10,30);
BEGIN
SELECT deptno BULK COLLECT INTO x
FROM dept WHERE deptno IN (10,30);
SELECT COUNT(*)
INTO i
FROM emp
WHERE deptno MEMBER OF (x);
dbms_output.put_line(i);
END;
/
Another Demo Using MEMBER OF
conn hr/hr@pdbdev
CREATE OR REPLACE TYPE t_deptno IS TABLE OF NUMBER(10);
/
DECLARE
depts t_deptno;
BEGIN
SELECT department_id BULK COLLECT INTO depts
FROM departments
WHERE department_id IN (10,20);
FOR i in 1 .. 10000 LOOP
FOR rec IN (SELECT * FROM employees e WHERE e.department_id MEMBER OF (depts)) LOOP
NULL;
END LOOP;
END LOOP;
END;
/
Tests whether a specified nested table is a submultiset of another specified nested table
<nested_table1> SUBMULTISET [OF] <nested_table2>
conn oe/oe@pdbdev
CREATE TABLE customer_demo AS
SELECT *
FROM oe.customers;
CREATE OR REPLACE TYPE cust_address_tab_typ AS
TABLE OF cust_address_typ;
/
ALTER TABLE customer_demo
ADD (cust_address_ntab1 cust_address_tab_typ,
cust_address_ntab2 cust_address_tab_typ)
NESTED TABLE cust_address_ntab1 STORE AS cust_add_ntab1_store
NESTED TABLE cust_address_ntab2 STORE AS cust_add_ntab2_store;
desc customer_demo
UPDATE customer_demo cd
SET cust_address_ntab1 = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ),
cust_address_ntab2 = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ);
SELECT customer_id, cust_address_ntab1
FROM customer_demo
WHERE cust_address_ntab1 SUBMULTISET OF cust_address_ntab2;
Tests whether a specified nested table is a submultiset of another specified nested table
<nested_table1> NOT SUBMULTISET [OF] <nested_table2>
SELECT customer_id, cust_address_ntab1
FROM customer_demo
WHERE cust_address_ntab1 NOT SUBMULTISET OF cust_address_ntab2;
MULTISET (Nested Table) Conditions
IS A SET
Tests whether a specified nested table is composed of unique elements <neseted_table> IS A SET
conn oe/oe@pdbdev
CREATE TABLE customer_demo AS
SELECT *
FROM oe.customers;
CREATE OR REPLACE TYPE cust_address_tab_typ AS
TABLE OF cust_address_typ;
/
ALTER TABLE customer_demo
ADD (cust_address_ntab cust_address_tab_typ)
NESTED TABLE cust_address_ntab STORE AS cust_add_ntab_store;
desc customer_demo
UPDATE customer_demo cd
SET cust_address_ntab = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ);
set linesize 121
SELECT customer_id, cust_address_ntab
FROM customer_demo
WHERE cust_address_ntab IS A SET
AND customer_id < 106;
IS NOT A SET
Tests whether a specified nested table is composed of unique elements <neseted_table> IS NOT A SET
conn oe/oe@pdbdev
CREATE TABLE customer_demo AS
SELECT *
FROM oe.customers;
CREATE OR REPLACE TYPE cust_address_tab_typ AS
TABLE OF cust_address_typ;
/
ALTER TABLE customer_demo
ADD (cust_address_ntab cust_address_tab_typ)
NESTED TABLE cust_address_ntab STORE AS cust_add_ntab_store;
desc customer_demo
UPDATE customer_demo cd
SET cust_address_ntab = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ);
set linesize 121
SELECT customer_id, cust_address_ntab
FROM customer_demo
WHERE cust_address_ntab IS NOT A SET
AND customer_id < 106;
IS EMPTY
Tests whether a specified nested table is empty <neseted_table> IS EMPTY
conn oe/oe@pdbdev
CREATE TABLE customer_demo AS
SELECT *
FROM oe.customers;
CREATE OR REPLACE TYPE cust_address_tab_typ AS
TABLE OF cust_address_typ;
/
ALTER TABLE customer_demo
ADD (cust_address_ntab cust_address_tab_typ)
NESTED TABLE cust_address_ntab STORE AS cust_add_ntab_store;
desc customer_demo
SELECT COUNT(*)
FROM customer_demo
WHERE cust_address_ntab IS EMPTY;
UPDATE customer_demo cd
SET cust_address_ntab = CAST(MULTISET(SELECT cust_address
FROM customers c
WHERE c.customer_id = cd.customer_id)
AS cust_address_tab_typ)
WHERE ROWNUM <11;
SELECT COUNT(*)
FROM customer_demo
WHERE cust_address_ntab IS NOT EMPTY;
IS NOT EMPTY
Tests whether a specified nested table is not empty <neseted_table> IS NOT EMPTY
SELECT COUNT(*)
FROM customer_demo
WHERE cust_address_ntab IS NOT EMPTY;
NULL Conditions
IS NULL
IS NULL(s VARCHAR2 CHARACTER SET ANY_CS) RETURN BOOLEAN;
conn scott/tiger@pdbdev
SELECT ename FROM emp WHERE comm IS NULL;
IS NOT NULL
IS NOT NULL(s VARCHAR2 CHARACTER SET ANY_CS) RETURN BOOLEAN;
conn scott/tiger@pdbdev
SELECT ename FROM emp WHERE comm IS NOT NULL;
PATH Conditions (also referred to by Oracle as "Functions" and "Ancillary Operators"
DEPTH
DEPTH is an ancillary function used only with the UNDER_PATH and EQUALS_PATH conditions. It returns the number of levels in the path specified by the UNDER_PATH condition with the same correlation variable.
conn / as sysdba
desc resource_view
SELECT path(1), DEPTH(2)
FROM resource_view
WHERE UNDER_PATH(res, '/sys/schemas', 1)=1
AND UNDER_PATH(res, '/sys/schemas', 2)=1;
PATH
Returns the relative path that leads to the resource specified in the parent condition. Only used with EQUALS_PATH and UNDER_PATH.
SELECT PATH(1), DEPTH(2)
FROM resource_view
WHERE UNDER_PATH(res, '/sys/schemas/PUBLIC', 1)=1
AND UNDER_PATH(res, '/sys/schemas/PUBLIC', 2)=1;
[NOT] LIKE(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
[NOT]
LIKE(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET,
esc IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
[NOT] LIKE(
str IN CLOB CHARACTER SET ANY_CS,
pat IN CLOB CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
[NOT] LIKE(
str IN CLOB CHARACTER SET ANY_CS,
pat IN CLOB CHARACTER SET str%CHARSET,
esc IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
LIKE with ending wildcard
Find any string that begins with the letter 'S'
conn scott/tiger@pdbdev
SELECT ename FROM emp WHERE ename LIKE 'S%';
LIKE with leading wildcard
Find any string that ends with the letter 'S'
SELECT ename FROM emp WHERE ename LIKE '%S';
LIKE with multiple wildcards
Find any string that contains, anywhere, the letter 'S'
SELECT ename FROM emp WHERE ename LIKE '%S%';
LIKE with single character wildcard
Find any string that contains the letter 'A' followed by any single character which followed by the letter 'E'
SELECT ename FROM emp WHERE ename LIKE '%A_E%';
LIKEC
[NOT] LIKEC(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
[NOT]
LIKEC(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET,
esc IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
LIKE2
[NOT] LIKE2(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
[NOT]
LIKE2(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER
SET str%CHARSET,
esc IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
LIKE4
LIKE4(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
LIKE4(
str IN VARCHAR2 CHARACTER SET ANY_CS,
pat IN VARCHAR2 CHARACTER SET str%CHARSET,
esc IN VARCHAR2 CHARACTER SET str%CHARSET)
RETURN BOOLEAN;
REGULAR EXPRESSION Conditions
REGEXP_LIKE
See Regular Expressions Link under Related Topics, at page bottom
Determines whether a resource in the Oracle XML database can be found in the database at a specified path.
SELECT any_path
FROM resource_view
WHERE EQUALS_PATH(res, '/sys/schemas/PUBLIC/www.w3.org')=1;
UNDER_PATH
Determines whether resources specified in a column can be found under a particular path specified by path_string in the Oracle XML database repository.
The path information is computed by the RESOURCE_VIEW view, which you query to use this condition.
SELECT any_path
FROM resource_view
WHERE UNDER_PATH(res, '/sys/schemas/PUBLIC/www.w3.org')=1;