Training to exam Oracle Database SQL 1Z0-071 (EN)

Печать

CHAPTER 1. "Relational Database concepts"
CHAPTER 2. "Restricting and Sorting Data"
CHAPTER 3. "Using Conversion Functions and Conditional Expressions"
CHAPTER 4. "Displaying Data from Multiple Tables"
CHAPTER 5. "Using SET Operators"
CHAPTER 6. "Managing Indexes Synonyms and Sequences"
CHAPTER 7. "Managing Views"
CHAPTER 8. "Managing Objects with Data Dictionary Views"
CHAPTER 9. "Retrieving Data using the SQL SELECT Statement"
CHAPTER 10. "Using Single-Row Functions to Customize Output"
CHAPTER 11. "Reporting Aggregated Data Using Group Functions"
CHAPTER 12. "Using Subqueries to Solve Queries"
CHAPTER 13. "Managing Tables using DML statements"
CHAPTER 14. "Use DDL to manage tables and their relationships"
CHAPTER 15. "Controlling User Access"
CHAPTER 16. "Managing Data in Different Time Zones"



CHAPTER 1. "Relational Database concepts":
1.1. Explaining the theoretical and physical aspects of a relational database
1.2. Relating clauses in SQL Select Statement to Components of an ERD
1.3. Explaining the relationship between a database and SQL

Task 1.1.1. ERD 
    1. What mean ERD? 
    2. List relationships.
Solution:
    --1
    ERD - entity-relationship diagram is a logical representation of real business
    system and displays the relationships of entitys in a database.
    --2
    One to one. One to many. Many to one. Many to many.
    
Task 1.1.2. Normal forms.
    1. List and explain normal forms.
Solution:
    --1
    --First normal form.
    No repeating rows. All tables are two-dimensional. Tables are structured in a 
    one-to-many relationship.
    Example:
    Table with not 1NF:
        John    1, 2    01.01.2000
        John    1, 2    01.01.2000
    Table with 1NF:
        John    1    01.01.2000
        John    2    01.01.2000
    --Second normal form.
    Contain first normal form + second normal form exists when no nonkey attribute 
    (column) is dependent upon part of a composite key.
    Example:
    Table with 1NF:
        'Table_0'
        John    1    01.01.2000
        John    2    01.01.2000
    Tables with 2NF: 
        'Table_1'    'Table_2'
        0    1       0    John    01.01.2000
        0    2           
    --Third normal form
    Contain 1NF + 2NF and all tables have primary key and one value for this primary
    key.
    Tables with 2NF: 
        'Table_1'    'Table_2'
        0    1       0    John    01.01.2000
        0    2 
    Tables with 3NF: 
        'Table_1'    'Table_2'    'Table_3'
        0    1       0    John    0    01.01.2000
        0    2               
    
Task 1.3.1 Types of SQL statements.
    1. Write types of SQL statements: DML, DDL, transaction control.
Solution:
    --1
    --DML
    SELECTINSERTUPDATEDELETEMERGE    
    --DDL
    CREATEALTERDROPRENAMETRUNCATEGRANTREVOKE, FLASHBACK, PURGE, COMMENT
    --Transaction control
    COMMITROLLBACKSAVEPOINT


CHAPTER 2. "Restricting and Sorting Data"
2.1. Applying Rules of precedence for operators in an expression
2.2. Limiting Rows Returned in a SQL Statement
2.3. Using Substitution Variables
2.4. Using the DEFINE and VERIFY commands
2.5. Sorting Data

Task 2.1.1. Applying Rules of precedence for operators in an expression
    1. List COMPARISON conditions;
    2. List rules of precedence all operators (high to low).
Solution:
    --1)
    Equal to: = 
    Greater than: > 
    Greater than or equal to: >= 
    Less than: < 
    Less than or equal to: <= 
    Not equal to: <> 
    Between two values (inclusive): BEETWEN ... AND ... 
    Match any of a list values: [NOTIN (set) 
    Match a character pattern: [NOTLIKE 
    Is a null value: IS NULL
    --2)
    1 - Arithmetic operators
    2 - Concatenation operators
    3 - Comparison conditions
    4 - IS [NOTNULLLIKE, [NOTIN
    5 - [NOTBETWEEN
    6 - Not equal to
    7 - NOT logical operator
    8 - AND logical operator
    9 - OR logical operator
    
Task 2.1.2. Applying Rules of precedence for operators in an expression. NULL.
    1. If X = NULL which result will be in expression: X > 1.
    2. Display result for next comparisons:
    TRUE  AND TRUE  -> ?
    TRUE  AND FALSE -> ?
    FALSE AND FALSE -> ?
    TRUE  AND NULL  -> ?
    FALSE AND NULL  -> ?
    TRUE  OR  TRUE  -> ?
    TRUE  OR  FALSE -> ?
    FALSE OR  FALSE -> ?
    TRUE  OR  NULL  -> ?
    FALSE OR  NULL  -> ?    
Solution:
    --1
    NULL
    --2
    TRUE  AND TRUE  -> TRUE
    TRUE  AND FALSE -> FALSE
    FALSE AND FALSE -> FALSE
    TRUE  AND NULL  -> NULL
    FALSE AND NULL  -> FALSE
    TRUE  OR  TRUE  -> TRUE
    TRUE  OR  FALSE -> TRUE
    FALSE OR  FALSE -> FALSE
    TRUE  OR  NULL  -> TRUE
    FALSE OR  NULL  -> NULL
    
Task 2.2.1. Limiting Rows Returned in a SQL Statement. BETWEEN.
    Do the next operations.
        DROP TABLE TAB;
        CREATE TABLE TAB (ID CHAR, COL1 NUMBER, COL2 VARCHAR2(100));
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('A', -1,   'aaa'); --A
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('B', NULL, 'bbb'); --B
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('C', -2,   NULL);  --C
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('D', -3,   'CCC'); --D
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('E', 1,    'fff'); --E
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('F', 2,    'eee'); --F
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('G', 3,    'ddd'); --G
        COMMIT;
    Then write queries using COL1 or COL2 in WHERE clause:
    1. Show rows A, C, D.
    2. Show rows A, B, D.
    3. Show rows E, F, G. Two ways.
    4. Show rows D, E, F, G.
Solution:
    SELECT ID, 
           COL1,
           COL2,
           ASCII(SUBSTR(COL2,1,1))
        FROM TAB
            WHERE /* 1    */ COL1 BETWEEN -3 AND -1
                  /* 2    */ COL2 BETWEEN 'C' AND 'c'
                  /* 3.1. */ COL1 BETWEEN 1 AND 3
                  /* 3.2. */ COL2 BETWEEN 'd' AND 'g'                  
                  /* 4.   */ COL1 NOT BETWEEN -2 AND -1                      

Task 2.2.2. Limiting Rows Returned in a SQL Statement. LIKENULL.
    Do the next operations.
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (COL1 VARCHAR2(100));
        INSERT INTO TAB1 (COL1) VALUES ('num_One');
        INSERT INTO TAB1 (COL1) VALUES ('num%TwO');
        INSERT INTO TAB1 (COL1) VALUES (NULL);
        INSERT INTO TAB1 (COL1) VALUES ('_um__4');
        COMMIT;
    Then write queryes where:
    operator LIKE
    1. COL1 include 4th symbol is '_';
    2. COL1 include '__';
    3. COL1 include symbols 'T', 'O' at the same time;
    4. COL1 begin 'num';
    5. COL1 not ended '4';
    6. COL1 include 'um_';
    7. COL1 include '%'.
    operator NULL
    8. COL1 with NULL values;
    9. COL1 without NULL values.
Solution:
    SELECT COL1
        FROM TAB1
            WHERE   /* 1 */ COL1 LIKE '___/_%' ESCAPE '/'
                    /* 2 */ COL1 LIKE '%/_/_%' ESCAPE '/' 
                    /* 3 */ COL1 LIKE '%T%O%'
                    /* 4 */ COL1 LIKE 'num%' 
                    /* 5 */ COL1 NOT LIKE '%4' 
                    /* 6 */ COL1 LIKE '%um/_%' ESCAPE '/' 
                    /* 7 */ COL1 LIKE '%_%%' ESCAPE '_'
                    /* 8 */ COL1 IS NULL
                    /* 9 */ COL1 IS NOT NULL
            
Task 2.3.1. Using Substitution Variables. Using the DEFINE and VERIFY commands.        
    Answer on the questions:    
    1. Write the symbol of the SUBSTITUTION VARIABLE that will be discarded after use.
    2. Write how save values of couple SUBSTITUTION VARIABLE for the session. 2 ways.      
    3. Write how remove couple SUBSTITUTION VARIABLE.        
    4. Write how change text of the message`s header for couple SUBSTITUTION VARIABLE.
    Write how SELECT this substitutions from dual.
    5. Write how see old and new values of SUBSTITUTION VARIABLE.
    6. Write how disable recognition symbol of SUBSTITUTION VARIABLE;
    7. Write how enable recognition symbol of SUBSTITUTION VARIABLE;
Solution:
    /* 1 */ &my_var
    /* 2.1. */ DEFINE my_var1 = 'my_value1'; DEFINE my_var2 = 'my_value2';
    /* 2.2. */ &&my_var1, &&my_var2
    /* 3 */ UNDEFINE my_var1;  
            UNDEFINE my_var2;
    /* 4 */ ACCEPT my_var1 PROMPT 'my_text_1';
            ACCEPT my_var2 PROMPT 'my_text_2';
            SELECT &my_var1,
                   &my_var2
                FROM DUAL 
    /* 5 */ SET VERIFY ON
            SELECT &my_var
                FROM DUAL --then go to "SCRIPT_OUTPUT" and will see OLD and NEW values
    /* 6 */ SET DEFINE OFF;
    /* 7 */ SET DEFINE ON;
    
Task 2.5.1. Sorting Data. ORDER BY.
    Do the next operations.
        DROP TABLE TAB;
        CREATE TABLE TAB (COL1 NUMBER, COL2 VARCHAR2(100));
        INSERT INTO TAB (COL1, COL2) VALUES (1,    'one');
        INSERT INTO TAB (COL1, COL2) VALUES (NULL, 'two');
        INSERT INTO TAB (COL1, COL2) VALUES (3,    NULL);
        INSERT INTO TAB (COL1, COL2) VALUES (4,    'four');
        COMMIT;
    Then write SELECT COL1 c1, COL2 c2 FROM TAB 
    and make:
    1. For COL2 show NULL at the end. Three ways.
    2. For COL2 show NULL at the beginning. Two ways.
    3. Sort COL1 and COL2 together, but in result for COL1 show NULL at the beginning.
    4. Sort COL1 and COL2 together, but in result for COL2 show NULL at the end.
    5. Sort COL1 and COL2, but do not write in ORDER BY words: "COL1, COL2". Two ways.
    6. Sort COL1 multiply 10.
Solution:
    SELECT COL1 c1,
           COL2 c2
        FROM TAB
            ORDER BY /* 1.1. */ COL2 
                     /* 1.2. */ COL2 ASC
                     /* 1.3. */ COL2 DESC NULLS LAST
                     /* 2.1. */ COL2 DESC
                     /* 2.2. */ COL2 NULLS FIRST  
                     /* 3 */    COL1 || COL2 DESC
                     /* 4 */    COL2 || COL1 DESC
                     /* 5.1. */ 1, 2
                     /* 5.2. */ c1, c2
                     /* 6. */   COL1 * 10
                                          
Task 2.5.2. Sorting Data. ORDER BYFETCH.
    Do the next operations.
        DROP TABLE TAB;
        CREATE TABLE TAB (ID CHAR, COL1 NUMBER, COL2 VARCHAR2(100));
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('A', 1,    'one');  
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('B', 2,    'two');  
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('C', 3,    NULL);   
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('D', NULL, 'zzz');       
        INSERT INTO TAB (ID, COL1, COL2) VALUES ('E', 2,    'TWO');     
        COMMIT;
    Then write SELECT for ID, COL1, COL2 and using only COL1 or COL2 make:
    1. Show in result rows A, B, C, D. Two ways.
    2. Show in result rows E, A, B. Two ways.
    3. Show in result rows A, B, E. Four ways.
    4. Show in result rows C, B, E or C, E, B. Four ways.
Solution:
    SELECT ID,
           COL1,
           COL2
        FROM TAB
    /* 1.1. */ FETCH FIRST 4 ROWS ONLY
    /* 1.2. */ FETCH FIRST 75 PERCENT ROWS ONLY
    /* 2.1. */ ORDER BY COL2 FETCH FIRST 3 ROWS ONLY
    /* 2.2. */ ORDER BY COL2 FETCH FIRST 60 PERCENT ROWS ONLY             
    /* 3.1. */ ORDER BY COL1 FETCH FIRST 3 ROWS ONLY   
    /* 3.2. */ ORDER BY COL1 FETCH FIRST 60 PERCENT ROWS ONLY 
    /* 3.3. */ ORDER BY COL1 FETCH FIRST 2 ROWS WITH TIES  
    /* 3.4. */ ORDER BY COL1 FETCH FIRST 40 PERCENT ROWS WITH TIES 
    /* 4.1. */ ORDER BY COL1 DESC OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY
    /* 4.2. */ ORDER BY COL1 DESC OFFSET 1 ROWS FETCH NEXT 60 PERCENT ROWS ONLY
    /* 4.3. */ ORDER BY COL1 DESC OFFSET 1 ROWS FETCH NEXT 2 ROWS WITH TIES
    /* 4.4. */ ORDER BY COL1 DESC OFFSET 1 ROWS FETCH NEXT 40 PERCENT ROWS WITH TIES
             
             
CHAPTER 3. "Using Conversion Functions and Conditional Expressions"
3.1. Applying the NVLNULLIF, and COALESCE functions to data
3.2. Understanding implicit and explicit data type conversion
3.3. Using the TO_CHARTO_NUMBER, and TO_DATE conversion functions
3.4. Nesting multiple functions

Task 3.1.1. Applying the NVLNULLIF, and COALESCE functions to data. CASEDECODE.
    Do the next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (C1 NUMBER, C2 NUMBER, C3 NUMBER, C4 NUMBER, C5 NUMBER);
        INSERT INTO TAB1 (C1, C2, C3, C4, C5) 
                  VALUES (NULLNULL, 1, 2, 3);
        COMMIT;
    Then write query which display:
    1. Display C3 if C1 is NULL.
    2. Display NULL when C3 = C4, otherwise display C3.
    3. In range C1, C2, C3, C4 display first not-NULL value.
    4. Display first TRUE condition: if C1 = NULL then display C4, if C3 = 1 then 
    display C5, otherwise display 0.
    5. Display first TRUE condition: if C3 = NULL then display C4, if C3 = 1 then 
    display C5, otherwise display 0.
Solution:
    SELECT /* 1 */ NVL(C1, C3), 
           /* 2 */ NULLIF(C3, C4),
           /* 3 */ COALESCE(C1, C2, C3, C4),
           /* 4 */    
           CASE
               WHEN C1 IS NULL 
                 THEN C4
               WHEN C3 = 1 
                 THEN C5
               ELSE 0
             END,
           /* 5 */
           DECODE(C3, NULL, C4,
                      1, C5,
                      0)
        FROM TAB1;
    
Task 3.3.1. Date to text
    Do the next operations.
        DROP TABLE TAB;
        CREATE TABLE TAB (COL DATE);
        INSERT INTO TAB (COL) VALUES (TO_DATE('13.07.2099 23:55:59',
                                              'DD.MM.YYYY HH24:MI:SS'));
        COMMIT;
    Then сonvert date to text:
    1. Show '2099';
    2. Show 'TWENTY NINETY-NINE';
    3. Show '07';
    4. Show 'JULY     ';
    5. Show 'JUL';
    6. Show '13';
    7. Show 'MONDAY';
    8. Show 'MON';
    9. Show '23' OR '11' (for 11 two ways);
    10. Show '55';
    11. Show '59';
    12. Show '86159';
    13. Show '13.07.2099 11:55:59 PM'. Two ways;
    14. Show '13.07.2099 23:55:59 PM';
    15. Show '13TH SEVEN 2099 23:55:59';
    16. Show 'THIRTEENTH JUL 2099 23:55:59'. Two ways;
    17. Show 'THIRTEENTH JULY TWENTY NINETY-NINE';
    18. Show 'DAY: THIRTEENTH / MONTH: JULY / YEAR: 2099';
    19. Show '13.7.2099 11:55:59'.    
Solution:
    SELECT /* 1 */  TO_CHAR(COL, 'YYYY'),
           /* 2 */  TO_CHAR(COL, 'YEAR'),
           /* 3 */  TO_CHAR(COL, 'MM'),
           /* 4 */  TO_CHAR(COL, 'MONTH'),
           /* 5 */  TO_CHAR(COL, 'MON'),
           /* 6 */  TO_CHAR(COL, 'DD'),
           /* 7 */  TO_CHAR(COL, 'FMDAY'),
           /* 8 */  TO_CHAR(COL, 'DY'),
           /* 9 */  TO_CHAR(COL, 'HH24'),
                    TO_CHAR(COL, 'HH12'),
                    TO_CHAR(COL, 'HH'),
           /* 10 */ TO_CHAR(COL, 'MI'),
           /* 11 */ TO_CHAR(COL, 'SS'),
           /* 12 */ TO_CHAR(COL, 'SSSSS'),
           /* 13 */ TO_CHAR(COL, 'DD.MM.YYYY HH:MI:SS AM'), --or use PM
                    TO_CHAR(COL, 'DD.MM.YYYY HH12:MI:SS AM'), --or use PM
           /* 14 */ TO_CHAR(COL, 'DD.MM.YYYY HH24:MI:SS AM'), --or use PM
           /* 15 */ TO_CHAR(COL, 'DDTH MMSP YYYY HH24:MI:SS'),
           /* 16 */ TO_CHAR(COL, 'DDSPTH MON YYYY HH24:MI:SS'),
                    TO_CHAR(COL, 'DDTHSP MON YYYY HH24:MI:SS'),
           /* 17 */ TO_CHAR(COL, 'FMDDSPTH MONTH YEAR'),  
           /* 18 */ TO_CHAR(COL, 'FM"DAY:" DDSPTH / "MONTH:" MONTH / "YEAR:" YYYY'),
           /* 19 */ TO_CHAR(COL, 'FMDD.MM.YYYY HH:MI:SS')
        FROM TAB;
                
Tack 3.3.2. Number to text. 
    Number to text:
    1. 2659.49 convert to ' 2,659.49'. Three ways.
    2. 2659.49 convert to '0,002,659.490'. Two ways.
    3. -10 convert to '$10-'. 
    4. -10 convert to '-10'. Two ways.
    5. -10 convert to '<10>'.
    6. 10.69 convert to '+$10.7'.
    7. For 120.9 and 1000333 write one function, that return '120.90' or 
    '1,000,333.00'.
Solution:
    SELECT /* 1 */ TO_CHAR(2659.49, '9G999D99'),
                   TO_CHAR(2659.49, '9,999.99'),
                   TO_CHAR(2659.49, '0,000.00'),
           /* 2 */ TO_CHAR(2659.49, 'FM0,000,000.000'),
                   TO_CHAR(2659.49, 'FM0,009,999.990'),
           /* 3 */ TO_CHAR(-10, '$99MI'),
           /* 4 */ TO_CHAR(-10, 'S99'),
                   TO_CHAR(-10, '99'),
           /* 5 */ TO_CHAR(-10, '99PR'),
           /* 6 */ TO_CHAR(10.69, 'S$99.9'),
           /* 7 */ TO_CHAR(120.9, 'FM999,999,999.00'),
                   TO_CHAR(1000333, 'FM999,999,999.00')           
        FROM DUAL;

Task 3.3.3. To date. Text to date.
    1. Show date '01.01.2049'. Three ways.
    2. Show date '01.01.1950'. Two ways.
    3. Show date '01.01.2050'. Two ways.
    4. For date '01.01.2000' add 5 days.
    5. For date '01.01.2000' subtract 5 days.
    6. For date '01.01.2000' add 3 months.
    7. For date '01.01.2000' subtract 3 months.    
    8. Show quantity of days between '01.01.1999' and '01.01.2000'. Write result.
    9. Show quantity of days between '01.01.2000' and '01.01.1999'. Write result.
    10. Show quantity of month between '01.01.2000' and '01.01.1999'. Write result.
    11. Show quantity of month between '01.01.1999' and '01.01.2000'. Write result.
    12. For date '01.01.2000' show last day in month.
    13. For date '01.01.2000' show next monday. Two ways.
    14. Convert '17.07.2000 13:45:59' to '18.07.2000'.
    15. Convert '17.07.2000 13:45:59' to '01.01.2001'.
    16. Convert '17.07.2000 13:45:59' to '01.08.2000'.
    17. Convert '17.07.2000 13:45:59' to '17.07.2000'.
    18. Convert '17.07.2000 13:45:59' to '01.01.2000'.
    19. Convert '17.07.2000 13:45:59' to '01.07.2000'.
    Text to date:
    20. '31.december.2000' convert to date 31.12.2000.        
Solution:
    SELECT 
    /* 1 */ TO_DATE('01.01.49', 'DD.MM.RR'),
            TO_DATE('01.01.49', 'DD.MM.YY'),
            TO_DATE('01.01.2049', 'DD.MM.YYYY'),
    /* 2 */ TO_DATE('01.01.50', 'DD.MM.RR'),
            TO_DATE('01.01.1950', 'DD.MM.YY'),
    /* 3 */ TO_DATE('01.01.50', 'DD.MM.YY'),
            TO_DATE('01.01.2050', 'DD.MM.YYYY'),
    /* 4 */ TO_DATE('01.01.2000', 'DD.MM.YYYY') + 5,
    /* 5 */ TO_DATE('01.01.2000', 'DD.MM.YYYY') - 5,
    /* 6 */ ADD_MONTHS(TO_DATE('01.01.2000', 'DD.MM.YYYY'), 3),
    /* 7 */ ADD_MONTHS(TO_DATE('01.01.2000', 'DD.MM.YYYY'), -3),
    /* 8 */ TO_DATE('01.01.1999', 'DD.MM.YYYY') - TO_DATE('01.01.2000', 'DD.MM.YYYY'),
    /* 9 */ TO_DATE('01.01.2000', 'DD.MM.YYYY') - TO_DATE('01.01.1999', 'DD.MM.YYYY'),
    /* 10 */ MONTHS_BETWEEN(TO_DATE('01.01.1999', 'DD.MM.YYYY'),
                           TO_DATE('01.01.2000', 'DD.MM.YYYY')),
    /* 11 */ MONTHS_BETWEEN(TO_DATE('01.01.2000', 'DD.MM.YYYY'),
                           TO_DATE('01.01.1999', 'DD.MM.YYYY')),
    /* 12 */ LAST_DAY(TO_DATE('01.01.2000', 'DD.MM.YYYY')),
    /* 13 */ NEXT_DAY(TO_DATE('01.01.2000', 'DD.MM.YYYY'), 'MONDAY'),
            -- 2 = 'MONDAY' in my NLS_DATE_LANGUAGE
             NEXT_DAY(TO_DATE('01.01.2000', 'DD.MM.YYYY'), 2), 
    /* 14 */ ROUND(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS')),
    /* 15 */ ROUND(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS'), 'YEAR'),
    /* 16 */ ROUND(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS'), 'MONTH'),
    /* 17 */ TRUNC(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS')),
    /* 18 */ TRUNC(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS'), 'YEAR'),
    /* 19 */ TRUNC(TO_DATE('17.07.2000 13:45:59', 'DD.MM.YYYY HH24:MI:SS'), 'MONTH'),
    /* 20 */ TO_DATE('31.december.2000', 'DD.MM.YYYY')
        FROM DUAL;


CHAPTER 4. "Displaying Data from Multiple Tables"
4.1. Using Self-joins
4.2. Using Various Types of Joins
4.3. Using Non equijoins
4.4. Using OUTER joins
4.5. Understanding and Using Cartesian Products

Task 4.2.1. JOINS.
    1. List Oracle proprietary joins.
    2. List SQL:1999 joins.
Solution:
    Oracle proprietary joins.
    1. Cartesian product, Equijoin, Nonequijoin, Outer join, Self join.
    2. Cross join, Natural join, Using clause, Join, Left join, Right join, Full join.
   
Task 4.2.2. Oracle proprietary joins.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        DROP TABLE TAB3;
        CREATE TABLE TAB1 (COL1 NUMBER,
                           COL2 VARCHAR2(100),
                           COL3 NUMBER);
            CREATE TABLE TAB2 (COL1 NUMBER,
                               COL22 VARCHAR2(100),
                               COL33 NUMBER);
                CREATE TABLE TAB3 (COL11 VARCHAR2(100),
                                   COL22 NUMBER);                       
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(11, 'group11', 22);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(22, 'group22', 22);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(33, 'group33', 11);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(11, '11', 20);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(22, '22', 30);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(44, '44', 50);    
                INSERT INTO TAB3(COL11, COL22) VALUES('new22', 22);
                INSERT INTO TAB3(COL11, COL22) VALUES('new44', 44);
                INSERT INTO TAB3(COL11, COL22) VALUES('new55', 55);            
        COMMIT;
    Then make Oracle proprietary joins:    
    1. Cartesian product for TAB1 and TAB2;
    2. Equijoin for TAB1 and TAB2 and TAB3;
       Equijoin for TAB1 and TAB2 with additional condition TAB1.COL1 > 11;
    3. Nonequijoin for TAB2 and TAB1. Two ways with same condition;
    4. Outer join for TAB1 and TAB2;
    5. Self join for TAB1;
Solution:
    --1 Cartesian product
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
    --2 Equijoin
    SELECT t1.*,
           t2.*,
           t3.*
        FROM TAB1 t1,
             TAB2 t2,
             TAB3 t3
            WHERE t1.COL1 = t2.COL1 AND 
                  t2.COL1 = t3.COL22;
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
            WHERE t1.COL1 = t2.COL1 AND
                  t1.COL1 > 11
    --3 Nonequijoin
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
            WHERE t1.COL1 BETWEEN t2.COL1 AND t2.COL33;
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
            WHERE t1.COL1 >= t2.COL1 AND 
                  t1.COL1 <= t2.COL33;    
    --4 Outer join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
            WHERE t1.COL1 = t2.COL1(+);
    SELECT t1.*,
           t2.*
        FROM TAB1 t1,
             TAB2 t2
            WHERE t1.COL1(+) = t2.COL1;            
    --5 Self join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1, 
             TAB1 t2
            WHERE t1.COL1 = t2.COL3    
    
Task 4.2.3. SQL:1999 joins.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        DROP TABLE TAB3;
        CREATE TABLE TAB1 (COL1 NUMBER,
                           COL2 VARCHAR2(100),
                           COL3 NUMBER);
            CREATE TABLE TAB2 (COL1 NUMBER,
                               COL22 VARCHAR2(100),
                               COL33 NUMBER);
                CREATE TABLE TAB3 (COL11 VARCHAR2(100),
                                   COL22 NUMBER);                       
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(11, 'group11', 22);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(22, 'group22', 22);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES(33, 'group33', 11);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(11, '11', 20);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(22, '22', 30);
            INSERT INTO TAB2(COL1, COL22, COL33) VALUES(44, '44', 50);    
                INSERT INTO TAB3(COL11, COL22) VALUES('new22', 22);
                INSERT INTO TAB3(COL11, COL22) VALUES('new44', 44);
                INSERT INTO TAB3(COL11, COL22) VALUES('new55', 55);            
        COMMIT;
    Then make SQL:1999 joins:
    1. Cross join for TAB1 and TAB2;
    2. Natural join (in SELECT list correctly all columns);
    3. Using clause (in SELECT list correctly all columns);
    4. Join for TAB1 and TAB2 and TAB3 together;
    5. Nonequijoin for TAB1 and TAB2;
    6. Left join for TAB1 and TAB2;
    7. Right join for TAB1 and TAB2;
    8. Full join for TAB1 and TAB2.
Solution:
    --1 Cross join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1
            CROSS JOIN TAB2 t2
    --2 Natural join
    SELECT COL1,
           t1.COL2,
           t1.COL3,
           t2.COL22,
           t2.COL33
        FROM TAB1 t1
            NATURAL JOIN TAB2 t2 --type of COL1 must be same
    --3 Using clause
    SELECT COL22,
           t2.COL1,
           t2.COL33,
           t3.COL11
        FROM TAB2 t2
            JOIN TAB3 t3
                USING (COL22) --type of COL22 must be compatible           
    --4 Join
    SELECT t1.*,
           t2.*,
           t3.*
        FROM TAB1 t1
            JOIN TAB2 t2
            ON t1.COL1 = t2.COL1
                JOIN TAB3 t3
                ON t2.COL22 = t3.COL22
    --5 Nonequijoin with JOIN
    SELECT t1.*,
           t2.*
        FROM TAB1 t1
            JOIN TAB2 t2
            ON t1.COL1 BETWEEN t2.COL1 AND t2.COL33
    --6 Left join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1
            LEFT JOIN TAB2 t2
            ON t1.COL1 = t2.COL1
    --7 Right join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1
            RIGHT JOIN TAB2 t2
            ON t1.COL1 = t2.COL1 
    --8 Full join
    SELECT t1.*,
           t2.*
        FROM TAB1 t1
            FULL JOIN TAB2 t2
            ON t1.COL1 = t2.COL1     


CHAPTER 5. "Using SET Operators"
5.1. Matching the SELECT statements
5.2. Using the ORDER BY clause in set operations
5.3. Using The INTERSECT operator
5.4. Using The MINUS operator
5.5. Using The UNION and UNION ALL operators

Task 5.2.1. Using the ORDER BY clause in set operations
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER);
        INSERT INTO TAB1(COL1) VALUES(4);
        INSERT INTO TAB1(COL1) VALUES(3);
        CREATE TABLE TAB2 (COL2 NUMBER);
        INSERT INTO TAB2(COL2) VALUES(1);
        INSERT INTO TAB2(COL2) VALUES(2);        
        COMMIT;
    Then do next:
    1. Explain presedence of set operators.
    2. Merge TAB1 (write first), TAB2 (write second) and display result: 1 2 3 4.
    3. Merge TAB1 (write first), TAB2 (write second) and display result: 4 3 2 1.
Solution:
    --1
    The set operators have equal precedence. Use parentheses to override precedence.
    --2
    SELECT COL1 FROM TAB1
    UNION
    SELECT COL2 FROM TAB2
    --3
    SELECT COL1 FROM TAB1
    UNION
    SELECT COL2 FROM TAB2
    ORDER BY COL1 DESC
        
Task 5.3.1-5.4.1 Using The INTERSECT operator, using The MINUS operator.
    Do the next operations:
        DROP TABLE MY_TAB1;
        DROP TABLE MY_TAB2;
        CREATE TABLE MY_TAB1 AS 
            SELECT NULL COL1 FROM DUAL
            UNION ALL      
            SELECT 4 COL1 FROM DUAL
            UNION ALL
            SELECT 3 COL1 FROM DUAL
            UNION ALL      
            SELECT 2 COL1 FROM DUAL
            UNION ALL
            SELECT 2 COL1 FROM DUAL;      
        CREATE TABLE MY_TAB2 AS
            SELECT 2 COL1 FROM DUAL
            UNION ALL
            SELECT 2 COL1 FROM DUAL 
            UNION ALL    
            SELECT 1 COL1 FROM DUAL
            UNION ALL
            SELECT 1 COL1 FROM DUAL
            UNION ALL
            SELECT NULL COL1 FROM DUAL;            
    Then make operations (first table must be MY_TAB1 and second table must be 
    MY_TAB2) with SET operators, explain them and write result:    
    1. Intersection of sets.    
    2. Difference of sets.
Solution:    
    --1 Matching rows from both tables will be retrieve. Duplicates will be removed.
    --Also result will be sort by ASC.
    --Result: 2 NULL
    SELECT COL1 FROM MY_TAB1
    INTERSECT
    SELECT COL1 FROM MY_TAB2        
    --2 Duplicates will be removed. Matching rows from both tables will be removed.
    --We retrieve remaining rows only from first table (MY_TAB1) and result will be
    --sort by ASC.
    --Result: 3 4
    SELECT COL1 FROM MY_TAB1
    MINUS
    SELECT COL1 FROM MY_TAB2

Task 5.5.1. Using The UNION and UNION ALL operators.
    Do the next operations:
        DROP TABLE MY_TAB1;
        DROP TABLE MY_TAB2;
        CREATE TABLE MY_TAB1 AS 
            SELECT NULL COL1 FROM DUAL
            UNION ALL      
            SELECT 3 COL1 FROM DUAL
            UNION ALL
            SELECT 3 COL1 FROM DUAL
            UNION ALL      
            SELECT 2 COL1 FROM DUAL
            UNION ALL
            SELECT 2 COL1 FROM DUAL;      
        CREATE TABLE MY_TAB2 AS
            SELECT 2 COL1 FROM DUAL
            UNION ALL
            SELECT 2 COL1 FROM DUAL 
            UNION ALL    
            SELECT 1 COL1 FROM DUAL
            UNION ALL
            SELECT 1 COL1 FROM DUAL
            UNION ALL
            SELECT NULL COL1 FROM DUAL;     
    Then make operations (first table must be MY_TAB1 and second table must be 
    MY_TAB2) with SET operators, explain them and write result:
    1. Merge with the exclusion of duplicates;
    2. Merge duplicates without the exclusion of duplicates;
Solution:
    --1 Result will be sort by ASCNULL-rows will be represented by 1 NULL-row.
    --Result: 1 2 3 NULL
    SELECT COL1 FROM MY_TAB1
    UNION
    SELECT COL1 FROM MY_TAB2
    --2 All rows will be merged full.
    --Result: NULL 3 3 2 2 2 2 1 1 NULL
    SELECT COL1 FROM MY_TAB1
    UNION ALL
    SELECT COL1 FROM MY_TAB2

    
CHAPTER 6. "Managing Indexes Synonyms and Sequences"
6.1. Managing Indexes
6.2. Managing Synonyms
6.3. Managing Sequences

Task 6.1.1. Managing Indexes.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1(COL1 NUMBER,
                          COL2 VARCHAR2(100));
        INSERT INTO TAB1(COL1, COL2) VALUES(111, 'one');
        COMMIT;
    Then do next operations: 
    1. Write when need create index;
    2. Write when not need create index;
    3. Explain when Oracle can create index for TAB1.
    4. Write how user can create index for TAB1 and what indexes.
    5. How see indexes in dictionary.
    6. How remove index. Two ways.
    7. How change index.
Solution:
    --1
    - A column contains a wide range of values;
    - A column contains a large number of null values;
    - One or more columns are frequently used together in a WHERE clause or a join
    condition;
    - The table is large and most queries are expected to retrieve less than 2% to 4%
    of the rows in the table.
    --2
    - The columns are not often used as a condtiton in the query;
    - The table is small or most queries are expected to retrieve more than 2% to 4%
    of the rows in the table;
    - The table is updated frequently;
    - The indexed columns are referenced as part of an expression.
    --3 Unique indexes creates by Oracle for constraints: PRIMARY KEY and UNIQUE.
    --In column with unique index can`t be duplicates. INDEX_TYPE will be 'NORMAL'
    --Name of indexes will be equal name of constraints, for example:
    CREATE TABLE TAB1(COL1 NUMBER CONSTRAINT CONS_TAB1_PK PRIMARY KEY,
                      COL2 VARCHAR2(100) CONSTRAINT CONS_TAB1_U UNIQUE);
    --4 Not unique index can create by user. INDEX_TYPE will be 'NORMAL'.
    CREATE INDEX MY_IND ON TAB1(COL1, COL2);
    --Unique index can create by user. Column will not have duplicates. And if we 
    --use function for index, that INDEX_TYPE will be 'FUNCTION-BASED NORMAL'
    CREATE UNIQUE INDEX MY_IND_U ON TAB1(UPPER(COL1), COL2);
    --Bitmap index can create in Enterprise edition. INDEX_TYPE will be 'BITMAP'.
    --Bitmap index need create for group rows in columns.
    CREATE BITMAP INDEX MY_IND_B ON TAB1(COL2);
    --5
    --view with all indexes by user
    SELECT * 
        FROM USER_INDEXES
            WHERE TABLE_NAME = 'TAB1';
    --view with columns and their indexes
    SELECT * 
        FROM USER_IND_COLUMNS
            WHERE TABLE_NAME = 'TAB1';
    --view for 'FUNCTION-BASED NORMAL' indexes
    SELECT * 
        FROM USER_IND_EXPRESSIONS
            WHERE TABLE_NAME = 'TAB1';
    --6
    DROP INDEX MY_IND_U;
    ALTER TABLE TAB1 DISABLE CONSTRAINT CONS_TAB1_U;
    --7 need drop and create again
    DROP INDEX MY_IND;
    CREATE INDEX MY_IND ON TAB1(COL1, COL2);   

Task 6.2.1. Managing Synonyms.
    Do next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
            CREATE TABLE TAB1(COL1 NUMBER, COL2 VARCHAR2(100));
            INSERT INTO TAB1(COL1, COL2) VALUES(111, 'one');
                CREATE TABLE TAB2(COL1 NUMBER, COL2 VARCHAR2(100));
                INSERT INTO TAB2(COL1, COL2) VALUES(222, 'two');
        COMMIT;
    Then do next operations: 
    1. Create private synonym using TAB1 for your schema;
    2. Create synonym (with same name from point 1) for TAB2 for all users.
    3. What a precedence between synonyms from point 1 and 2. Explain it.
    4. Find both synonyms in dictionary. Who owns these synonyms?
    5. Remove both synonyms.
Solution:
    --1
    CREATE SYNONYM MY_SYN FOR TAB1;
    --2
    CREATE PUBLIC SYNONYM MY_SYN FOR TAB2;
    --3
    Private synonym have precedence over public.
    If we make SELECT * FROM MY_SYN in result we will see data from TAB1;
    --4
    --For private synonym owner will be user, which created this synonym.
    --For public synonym owner will be PUBLIC
    SELECT * FROM ALL_SYNONYMS;
    --5
    DROP SYNONYM MY_SYN;
    DROP PUBLIC SYNONYM MY_SYN;

Task 6.3.1. Managing Sequences.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1(COL1 NUMBER,
                          COL2 VARCHAR2(100));
        INSERT INTO TAB1(COL1, COL2) VALUES(111, 'one');
        COMMIT;
    Then do next operations:    
    1. Create sequence with name SEQ (write all parameters manually).
    2. For TAB1 write all situation where we can use next and current values of SEQ;
    3. For TAB1 write all situation where we can`t use next and current values of SEQ;
    4. Show dictionary info for SEQ;
    5. Change maximum value to 1000;
    6. Remove SEQ.
    7. Create sequence in range [-1;-999] (write all parameters manually).
Solution:
    --1
    CREATE SEQUENCE SEQ
        START WITH 1
            INCREMENT BY 1
                MINVALUE 1 --NOMINVALUE, it is mean that MINVALUE = START WITH
                    MAXVALUE 999 --NOMAXVALUE
                        NOCYCLE --CYCLE
                            CACHE 20 --NOCACHE
                                ORDER --NOORDER;
    --2
    --2.1. The SELECT list of a SELECT statement that is not part of subquery
    SELECT COL1, 
           SEQ.NEXTVAL
        FROM TAB1;
    --2.2. The VALUES clause of an INSERT statement;
    INSERT INTO TAB1(COL1) VALUES(SEQ.NEXTVAL);
    COMMIT;
    --2.3. The SET clause of an UPDATE statement
    UPDATE TAB1
        SET COL1 = SEQ.CURRVAL
            WHERE COL2 = 'one';
    COMMIT;
    --2.4. In DEFAULT value.
    ALTER TABLE TAB1 MODIFY COL1 DEFAULT SEQ.NEXTVAL;
    DROP TABLE TAB2;
    CREATE TABLE TAB2 (COL1 NUMBER DEFAULT SEQ.NEXTVAL,
                       COL2 VARCHAR2(100));
    --3
    --3.1. Sequence is part of subquery in SELECTDELETE or UPDATE
    SELECT *
        FROM (SELECT SEQ.NEXTVAL FROM TAB1);    
    SELECT *
        FROM TAB1
            WHERE COL1 = SEQ.NEXTVAL;
    DELETE TAB1
        WHERE COL1 = SEQ.NEXTVAL;      
    UPDATE TAB1
        SET COL2 = 'two'
            WHERE COL1 = SEQ.NEXTVAL;
    --3.2. In SELECT with DISTINCT
    SELECT DISTINCT SEQ.NEXTVAL
        FROM TAB1;
    --3.3. A SELECT statement with GROUP BYHAVING or ORDER BY clauses.
    SELECT SEQ.NEXTVAL 
        FROM TAB1 
            GROUP BY COL1; --GROUP BY SEQ.NEXTVAL;
    SELECT SEQ.NEXTVAL 
        FROM TAB1 
            ORDER BY COL1; --ORDER BY SEQ.NEXTVAL;
    --3.4. The SELECT list of a view
    CREATE OR REPLACE VIEW VIEW_TAB1 AS
        SELECT COL1,
               SEQ.NEXTVAL COL_SEQ
            FROM TAB1;   
    --4 
    SELECT *
        FROM USER_SEQUENCES
            WHERE SEQUENCE_NAME = 'SEQ';
    --5
    ALTER SEQUENCE SEQ MAXVALUE 1000;
    --6
    DROP SEQUENCE SEQ;
    --7
    CREATE SEQUENCE SEQ
        START WITH -1
            INCREMENT BY -1
                MINVALUE -999 --NOMINVALUE
                    MAXVALUE -1 --NOMAXVALUE
                        CYCLE --NOCYCLE
                            CACHE 20 --NOCACHE
                                ORDER--NOORDER


CHAPTER 7. "Managing Views"
7.1. Managing Views

Task 7.1.1. Managing Views
    Do next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1(COL1 NUMBER,
                          COL2 VARCHAR2(100));
            INSERT INTO TAB1(COL1, COL2) VALUES(111, 'one');
            INSERT INTO TAB1(COL1, COL2) VALUES(222, 'two');
        CREATE TABLE TAB2(COL1 NUMBER,
                          COL2 VARCHAR2(100));
            INSERT INTO TAB2(COL1, COL2) VALUES(111, 'ONE_ONE');    
            INSERT INTO TAB2(COL1, COL2) VALUES(333, 'three');
        COMMIT;
    Then do next operations: 
    1. Create view without tables in database;
    2. Create simple view. Two ways (list constraint`s type ). Explain them and find 
    in constraint`s dictionary.
    3. Create complex view with all conditions of complex view. But CREATE clause 
    must be another that in point 1 or 2.
    4. Explain INSERTDELETEUPDATE for view where it is allowed.
    5. Find view in dictionary.
    6. Remove view.    
Solution:
    --1
    DROP TABLE MY_TABLE;
    CREATE OR REPLACE FORCE VIEW V_F AS
    SELECT MY_COLUMN
        FROM MY_TABLE;
    --2
    --DML-operations not allowed
    CREATE OR REPLACE VIEW V_TAB1 AS
    SELECT COL1, COL2   
        FROM TAB1
            WITH READ ONLY--constraint type is "O"
    --DML operations allowed only for condition of view (for COL1 = 111)         
    CREATE OR REPLACE VIEW V_TAB2 AS    
    SELECT COL1, COL2
        FROM TAB2
            WHERE COL1 = 111
                WITH CHECK OPTION CONSTRAINT CONS_V_TAB1_V; --constraint type is "V"
    INSERT INTO V_TAB2 (COL1, COL2) VALUES (111, 'onlyCOL1 = 111');
    COMMIT;
    --this constraints in dictionary
    SELECT *
        FROM USER_CONSTRAINTS
            WHERE TABLE_NAME = 'V_TAB1' OR
                  CONSTRAINT_NAME = 'CONS_V_TAB1_V';
    --3
    CREATE OR REPLACE VIEW V_COM (C1, C2) AS
    SELECT t1.COL1,
           MAX(t2.COL1)
        FROM TAB1 t1
            LEFT JOIN TAB2 t2
            ON t1.COL1 = t2.COL1
                GROUP BY t1.COl1;
    --4
    DML allowed in simple views and in complex views (not always).
    DELETE not allowed if view:
    - contain group functions;
    - contain GROUP BY clause;
    - contain DISTINCT;
    - contain ROWNUM.
    UPDATE not allowed if view:
    - contain group functions;
    - contain GROUP BY clause;
    - contain DISTINCT;
    - contain ROWNUM;
    - columns defined by expressions (for example: COL1 * 5).
    INSERT not allowed if view:
    - contain group functions;
    - contain GROUP BY clause;
    - contain DISTINCT;
    - contain ROWNUM;
    - columns defined by expressions (for example: COL1 * 5);
    - NOT NULL columns without default value in the base tables that are not
    selected by the view.
    --5
    SELECT *
        FROM USER_VIEWS
            WHERE VIEW_NAME = 'V_F';
    --6
    DROP VIEW V_F;


CHAPTER 8. "Managing Objects with Data Dictionary Views"
8.1. Using data dictionary views    

Task 8.1.1. Using data dictionary views 
    1. What user own all base tables and user-accessible views of the data dictionary?
    2. List prefixes for dictionary`s views and explain what there contain.
    3. Explain USER_OBJECTS/ALL_OBJECTS and what contain columns: OBJECT_NAME
    OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME, STATUS, GENERATED.
    4. Explain view USER_CATALOG, columns and write synonym.
    5. Explain view USER_TABLES. Write synonym.
    6. Explain USER_TAB_COLUMNS.
    7. Explain USER_CONSTRAINTS and columns: CONSTRAINT_TYPE, DELETE_RULE, STATUS.
    8. Explain USER_CONS_COLUMNS.    
    9. Create table with one column and create comment for table and for this column.
    Display views containing info about this comments. What comment length is allowed?
Solution:
    --1
    SYS
    --2
    USER - contains information about objects that you own.
    ALL  - contains information about all objects to which you have access.
    DBA  - contains information about all objects by all users.
    V$   - perfomance-related data.
    --3
    USER_OBJECTS  - contain info about all objects in your schema. 
    ALL_OBJECTS   - contain info about all objects to which you have access. 
    OBJECT_NAME   - name of the object;
    OBJECT ID     - dictionary object number of the object;
    OBJECT_TYPE   - type of object;
    CREATED       - timestamp for the creation of the object;
    LAST_DDL_TIME - timestamp of last DDL modification of the object;
    STATUS        - status of the object (valid, invalid or N/A);
    GENERATED     - was the name of this object system-generated (Y/N).
    --4 
    'USER_CATALOG' contain tables, views, synonyms and sequences owned by the user.
    Have columns: TABLE_NAME, TABLE_TYPE. Synonym is 'CAT'.
    --5
    'USER_TABLES' contain detailed info about of all your tables and views. 
    Synonym is 'TABS'.
    --6
    'USER_TAB_COLUMNS' contain info about columns of user: tables and views.
    Have column names, column data types, length of data_types, precision and scale 
    for NUMBER columns, nullable, default value.
    --7
    'USER_CONSTRAINTS' contain info about constraints for your tables.
    CONSTRAINT_TYPE - contain: 'C' - check constraint or not null,
                               'P' - primary key,
                               'U' - unique key,
                               'R' - referential integrity (foreign key),
                               'V' - with check option, on view,
                               'O' - with read-only, on a view;
    DELETE_RULE     - 'CASCADE', 'SET NULL', 'NO ACTION';
    STATUS          - 'ENABLED', 'DISABLED'.
    --8
    'USER_CONS_COLUMNS' contain info about constraints for columns.
    --9
    DROP TABLE TAB1;
    CREATE TABLE TAB1(COL1 NUMBER);
    COMMENT ON TABLE TAB1 IS 'This is comment for TAB1';
    COMMENT ON COLUMN TAB1.COL1 IS 'This is comment for COL1';
    SELECT * FROM ALL_TAB_COMMENTS;
    SELECT * FROM ALL_COL_COMMENTS;
    Comment length <= 4000 bytes.    


CHAPTER 9. "Retrieving Data using the SQL SELECT Statement"
9.1. Using Column aliases.
9.2. Using The SQL SELECT statement.
9.3. Using concatenation operator, literal character strings, alternative quote 
operator, and the DISTINCT keyword.
9.4. Using Arithmetic expressions and NULL values in the SELECT statement.

Task 9.2.1. Using The SQL SELECT statement. PIVOT.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 VARCHAR2(100), CNT NUMBER);
        INSERT INTO TAB1 VALUES(10, 'A', 1);
        INSERT INTO TAB1 VALUES(10, 'A', 1);
        INSERT INTO TAB1 VALUES(20, 'A', 1);
        INSERT INTO TAB1 VALUES(20, 'B', 1);
        INSERT INTO TAB1 VALUES(30, 'A', 1);
        COMMIT;
    Then do next operations:        
    1. Pivot table. Show in rows for COL1, count of rows for values from COL2.
Solution:
    SELECT * 
        FROM
            (
            SELECT COl1, 
                   COl2, 
                   CNT
                FROM TAB1
            )
            PIVOT (
                   COUNT(CNT) FOR COL2 IN ('A', 'B')
                  )
                ORDER BY 1  

Task 9.3.1. Using Column aliases, SQL SELECT statement, concatenation operator,
literal character strings, alternative quote operator, and the DISTINCT keyword.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (COL1 NUMBER
                           COL2 VARCHAR2(100),
                           COL3 NUMBER);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES (1, 'one', 2);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES (1, 'one', 3);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES (2, 'two', 4);
        INSERT INTO TAB1(COL1, COL2, COL3) VALUES (NULL, 'nn', 5);
        COMMIT;    
    Then do next operations:
    1. Make query that retrieve unique rows for COL1 and write alias starting to 
    number with spaces.
    2. Make query that retrieve unique rows for COL1 and COL2.
    3. Make query that concatenating COL1 and COL2. But between this values must be
    text (without double quotes) " it's COL1 + COL2_".
Solution:
    --1
    SELECT DISTINCT COL1 "1 col1 "
        FROM TAB1
    --2
    SELECT DISTINCT COL1, COL2
        FROM TAB1
    --3 
    SELECT COL1||q'{ it's COL1 + COL2_}'||COL2
        FROM TAB1
        
Task 9.4.1. Using Arithmetic expressions and NULL values in the SELECT statement.       
    1. Explain result of arithmetic expressions with NULL.
    2. Write result for query: 
    SELECT 1 + NULL
           1 - NULL
           1 * NULL
           1 / NULL 
        FROM DUAL
Solution:
    --1
    Arithmetic expressions with NULL have result equal NULL.
    --2
    NULLNULLNULLNULL


CHAPTER 10. "Using Single-Row Functions to Customize Output"
10.1. Manipulating strings with character functions in SQL SELECT and WHERE clauses
10.2. Performing arithmetic with date data
10.3. Manipulating numbers with the ROUNDTRUNC and MOD functions
10.4. Manipulating dates with the date function        

Task 10.1.1. U, L, I, C, S, L, I, C.
    For next string 'One  two': 
    1. Convert to text 'one  two';
    2. Convert to text 'ONE  TWO';
    3. Convert to text 'One  Two'.
    For SELECT 'One', 'Two', 1 FROM DUAL:
    4. Convert to text 'OneTwo';
    5. Convert to text 'OneTwo1'.
    For SELECT 'abcde' FROM DUAL:
    6. Convert to text 'abc';
    7. Convert to text 'de'. Two ways.
    8. Convert to text 'bcd';
    For SELECT 'nameANn' FROM DUAL:
    9. Show symbol`s quantity.
    10. Show number`s position for 'a';
    11. Show number`s position for 'A';
    12. Show number`s position for second 'n' left to right. Two ways;
    13. Show number`s position for second 'n' right to left. Two ways;
    Show symbol:
    14. For symbol`s code 98.
Solution:
    SELECT /* 1 */ LOWER('One two'),
           /* 2 */ UPPER('One two'),
           /* 3 */ INITCAP('One two')
        FROM DUAL;
    SELECT /* 4 */ CONCAT('One', 'Two'),
           /* 5 */ 'One' || 'Two' || 1           
        FROM DUAL;
    SELECT /* 6 */    SUBSTR('abcde', 1, 3),
           /* 7.1. */ SUBSTR('abcde', 4, 2),    
           /* 7.2. */ SUBSTR('abcde', -2),    
           /* 8 */    SUBSTR('abcde', 2, 3)
        FROM DUAL;
    SELECT /* 9 */     LENGTH('nameANn'),
           /* 10 */    INSTR('nameANn', 'a'),
           /* 11 */    INSTR('nameANn', 'A'),
           /* 12.1. */ INSTR('nameANn', 'n', 2),
           /* 12.2. */ INSTR('nameANn', 'n', 1, 2),
           /* 13.1. */ INSTR('nameANn', 'n', -2),
           /* 13.2. */ INSTR('nameANn', 'n', -1, 2)
        FROM DUAL;
    SELECT /* 14 */ CHR(98) 
        FROM DUAL;
        
Task 10.1.2. L, R, R, T, T, L, R.
    For SELECT 'one' FROM DUAL:
    1. Convert to text '  one'. Two ways.
    2. Convert to text 'one  '. Two ways.
    3. Convert to text '111one'.
    4. Convert to text 'oneZZZ'.
    For SELECT 'myORAcleORA' FROM DUAL:
    5. Convert to text 'my2cle2'.
    6. Convert to text 'mycle'.
    7. Convert to text 'zzORAzzzORA'.
    8. Convert to text 'ORAORA'.
    For SELECT ' ora ZZZ  ' FROM DUAL:
    9. Convert to text 'ora ZZZ'. Three ways.
    10. Convert to text 'ora ZZZ  '. Two ways.
    11. Convert to text ' ora ZZZ'. Two ways.
    For SELECT ' oraYYY' FROM DUAL:
    12. Convert to text ' ora'. Three ways.
Solution:
    SELECT /* 1.1. */ LPAD('one', 5),
           /* 1.2. */ LPAD('one', 5, ' '),
           /* 2.1. */ RPAD('one', 5),
           /* 2.2. */ RPAD('one', 5, ' '),
           /* 3    */ LPAD('one', 6, '1'),
           /* 4    */ RPAD('one', 6, 'Z')
        FROM DUAL;
    SELECT /* 5 */ REPLACE('myORAcleORA', 'ORA', '2'),
           /* 6 */ REPLACE('myORAcleORA', 'ORA'),
           /* 7 */ TRANSLATE('myORAcleORA', 'mycle', 'zzzzz'),
           /* 8 */ REPLACE(TRANSLATE('myORAcleORA', 'mycle', '     '), ' ')
        FROM DUAL;
    SELECT /* 9.1. */  TRIM(' ora ZZZ  '),
           /* 9.2. */  TRIM(' ' FROM ' ora ZZZ  '),
           /* 9.3. */  TRIM(BOTH ' ' FROM ' ora ZZZ  '),
           /* 10.1. */ TRIM(LEADING ' ' FROM ' ora ZZZ  '),
           /* 10.2. */ LTRIM(' ora ZZZ  '),
           /* 11.1. */ TRIM(TRAILING ' ' FROM ' ora ZZZ  '),
           /* 11.2. */ RTRIM(' ora ZZZ  '),           
           /* 12.1. */ TRIM(TRAILING 'Y' FROM ' oraYYY'),
           /* 12.2. */ TRIM('Y' FROM ' oraYYY'),
           /* 12.3. */ RTRIM(' oraYYY', 'Y')
        FROM DUAL;

Task 10.3.1. R, T, M.
    Without cut off:
    1. Convert 155.594 to 156;
    2. Convert 155.594 to 155.6;
    3. Convert 155.594 to 155.59;
    4. Convert 155.594 to 160;
    5. Convert 155.594 to 200;
    6. Convert 155.594 to 0;
    With cut off:
    7. Convert 155.594 to 155;
    8. Convert 155.594 to 155.59;
    9. Convert 155.594 to 100;
    10. Convert 155.594 to 0;
    Get the remainder of the division:
    11. 10/2;
    12. 9/7.
Solution:
    SELECT /* 1 */  ROUND(155.594),
           /* 2 */  ROUND(155.594, 1),
           /* 3 */  ROUND(155.594, 2),
           /* 4 */  ROUND(155.594, -1),
           /* 5 */  ROUND(155.594, -2),
           /* 6 */  ROUND(155.594, -3),
           /* 7 */  TRUNC(155.594),
           /* 8 */  TRUNC(155.594, 2),
           /* 9 */  TRUNC(155.594, -2),
           /* 10 */ TRUNC(155.594, -3),
           /* 11 */ MOD(10, 2),
           /* 12 */ MOD(9, 7)
        FROM DUAL;
  
  
CHAPTER 11. "Reporting Aggregated Data Using Group Functions"
11.1. Restricting Group Results
11.2. Creating Groups of Data
11.3. Using Group Functions   
         
Task 11.3.1. Using Group Functions.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1(COL1 NUMBER);        
        INSERT INTO TAB1 VALUES(1);
        INSERT INTO TAB1 VALUES(3);
        INSERT INTO TAB1 VALUES(NULL);
        COMMIT;
    Then do next operations:
    1. Write what happen with NULL values in group functions?
    2. Retrieve minimum value for COL1.
    3. Retrieve maximum value for COL1.
    4. Retrieve average for COL1.
    5. Retrieve addition of all values for COL1.
    6. Retrieve quantity of rows for COL1.
    7. Display all values of COL1 through comma.
Solution:
    --1 In group functions NULLs ignored.    
SELECT /* 2 */ MIN(COL1), 
       /* 3 */ MAX(COL1),
       /* 4 */ AVG(COL1),
       /* 5 */ SUM(COL1),
       /* 6 */ COUNT(COL1),
       /* 7 */ LISTAGG(COL1, ', ')
                   WITHIN GROUP (ORDER BY COL1)
    FROM TAB1
        
Task 11.3.2. Using Group Functions. COUNT.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1(COL1 NUMBER);
        INSERT INTO TAB1 VALUES(NULL);
        INSERT INTO TAB1 VALUES(NULL);
        INSERT INTO TAB1 VALUES(1);
        INSERT INTO TAB1 VALUES(1);
        INSERT INTO TAB1 VALUES(2);
        COMMIT;
    Then make query: 
    SELECT COUNT(COL1),
           COUNT(*),
           COUNT(1),
           COUNT(DISTINCT COL1)
        FROM TAB1
    1. Write result and explain what happens with NULLS.
Solution:
    --1
    COUNT(COL1) = 3 --Quantity of rows for COL1, but NULLs will be ignored.
    COUNT(*) = 5 --Quantity of all rows in table and all NULLs too.
    COUNT(1) = 5 --Quantity of all rows in table and all NULLs too.
    COUNT(DISTINCT COL1) = 2 --Quantity of rows for COL1, but NULLs will be ignored.
                             --Duplicates will be removed.
   
   
CHAPTER 12. "Using Subqueries to Solve Queries"
12.1. Using Single Row Subqueries
12.2. Using Multiple Row Subqueries
12.3. Update and delete rows using correlated subqueries

Task 12.1.2. Using Multiple Row Subqueries.
    Do the next operations:
        DROP TABLE TAB;
        CREATE TABLE TAB(PROD VARCHAR2(100),  
                         PRICE NUMBER,
                         MARK NUMBER);
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod1', 100,  1);
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod2', 170,  3);
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod3', NULL, 1);
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod4', 150,  NULL);    
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod5', 170,  2);    
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod6', 190,  2);  
        INSERT INTO TAB(PROD, PRICE, MARK) VALUES('prod7', NULL, 2);     
        COMMIT;
    Then make SELECT with subqueries:
    1. Show rows where price = price for prod with MARK = 2. Two ways.
    2. Show rows where price <> price for prod with MARK = 1. Two ways.
    3. Show rows where price > price for prod with MARK = 1 OR 
                             > price for prod with MARK = 3. Two ways.
    4. Show rows where price < price for prod with MARK = 2 (it is mean price must be 
    < 170 and < 190 simultaneously).
Solution:
    --1.
    SELECT t.*
        FROM TAB t
            WHERE t.PRICE IN (SELECT PRICE
                                  FROM TAB
                                      WHERE MARK = 2)
                ORDER BY t.PROD;
    SELECT t1.*
        FROM TAB t1
            WHERE EXISTS (SELECT NULL
                              FROM TAB t2
                                  WHERE t1.PRICE = t2.PRICE AND 
                                        t2.MARK = 2)
                ORDER BY t1.PROD;                                  
    --2.
    SELECT t.*
        FROM TAB t
            WHERE NVL(t.PRICE, 1) NOT IN (SELECT NVL(PRICE, 0) PRICE
                                              FROM TAB
                                                  WHERE MARK = 1)
                ORDER BY t.PROD;  
    SELECT t1.*
        FROM TAB t1
            WHERE NOT EXISTS (SELECT NULL
                                  FROM TAB t2
                                      WHERE t1.PRICE = t2.PRICE AND
                                            t2.MARK = 1)
                ORDER BY t1.PROD;
    --3.
    SELECT t.*
        FROM TAB t
            WHERE t.PRICE > ANY /* SOME */ (SELECT PRICE
                                                FROM TAB
                                                    WHERE MARK IN (1, 3))
                ORDER BY t.PROD;                              
    --4.
    SELECT t.*
        FROM TAB t
            WHERE t.PRICE < ALL (SELECT PRICE
                                     FROM TAB
                                         WHERE MARK = 2)
                ORDER BY t.PROD;   
    
    
CHAPTER 13. "Managing Tables using DML statements"
13.1. Managing Database Transactions
13.2. Controlling transactions
13.3. Perform Insert, Update and Delete operations
13.4. Performing multi table Inserts
13.5. Performing Merge statements

Task 13.2.1. Controlling transactions
    Look on operations and answer the questions:
    /* A */ CREATE TABLE TAB1 (COL1 NUMBER);
    /* B */ INSERT INTO TAB1 (COL1) VALUES(100);
    /* C */ INSERT INTO TAB1 (COL1) VALUES(200);
    /* D */ CREATE TABLE TAB2 (COL1 NUMBER);
    /* E */ INSERT INTO TAB2 (COL1) VALUES(300);
    /* F */ INSERT INTO TAB2 (COL1) VALUES(400);
    /* G */ ...
    Answer the questions:
    1. What tables and data we will see in another session after row C?
    2. What tables and data we will see in another session after row D?
    3. How to return data back in TAB2 before row E, when TAB2 was empty?
    4. How to return data back in TAB2 before row F, when TAB2 had only row E?
    5. What we will see in another session after action №4?
    6. How to make see in another session all rows (except G) and tables in database?
Solution:
    1. TAB1 without data, because didn`t wrote 'COMMIT';
    2. TAB1 with rows B and C. and empty TAB2. Because CREATE is DDL command, DDL 
    commands makes COMMIT;
    3. Write 'ROLLBACK;' in row G.
    4. Write, for example, 'SAVEPOINT A;' after row E. Then after row F write 
    'ROLLBACK TO SAVEPOINT A;'.
    5. We will see TAB1 with rows B, C and TAB2 without rows because need COMMIT;
    6. Write 'COMMIT;' in row G.

Task 13.3.1. Perform Insert, Update and Delete operations. INSERT.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 VARCHAR2(100));
        CREATE TABLE TAB2 (COL1 NUMBER, COL2 VARCHAR2(100));
    Then:
    1. Show 3 ways of INSERT in TAB1.
    2. Show 3 ways of INSERT from TAB1 to TAB2;
Solution:
    --1. 
    INSERT INTO TAB1 (COL1, COL2) VALUES (1, 'one');
    INSERT INTO TAB1 (COL2, COL1) VALUES ('one', 1);
    INSERT INTO TAB1 VALUES (1, 'one');
    --2.
    INSERT INTO TAB2 SELECT * FROM TAB1;
    INSERT INTO TAB2 SELECT COL1, COL2 FROM TAB1;
    INSERT INTO TAB2 (COL2, COL1) SELECT COL2, COL1 FROM TAB1;

Task 13.3.2. Perform Insert, Update and Delete operations. INSERT.
    Do next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER,
                           COL2 VARCHAR2(100) DEFAULT 'zero');
        INSERT INTO TAB1 (COL1, COL2) VALUES (1, 'one');
        INSERT INTO TAB1 (COL1, COL2) VALUES (2, 'two');
        INSERT INTO TAB1 (COL1, COL2) VALUES (3, 'three');
        COMMIT;
        CREATE TABLE TAB2 (COL1 NUMBER,
                           COL2 VARCHAR2(100));    
    Then do next operations:                       
    1. List types of data warehouse and explain it.
    2. Show how insert into TAB1.COL2 DEFAULT value (two ways). 
    3. Show how insert into TAB1.COL2 NULL value. 
    4. Insert rows into TAB2 from TAB1. 2 ways.
    5. Insert rows into TAB2 from subquery where TAB1 have union all with TAB1.
Solution:
    --1
    OLTP - database designed for transaction processing (DML, DDL, etc.);
    OLAP - database designed for queries and analysis.
    --2
    INSERT INTO TAB1(COL1) VALUES (4);
    INSERT INTO TAB1(COL1, COL2) VALUES (5, DEFAULT);
    COMMIT;
    --3
    INSERT INTO TAB1(COL1, COL2) VALUES (6, NULL);
    COMMIT;
    --4
    INSERT INTO TAB2 
        SELECT * FROM TAB1;
    INSERT INTO TAB2 (COL2, COL1)
        SELECT COL2, COL1 FROM TAB1;
    COMMIT;
    --5
    INSERT INTO TAB2
        SELECT COL1, COL2 FROM TAB1
        UNION ALL
        SELECT COL1, COL2 FROM TAB1;
    COMMIT;
       
Task 13.3.3. Perform Insert, Update and Delete operations. FOR UPDATE.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 VARCHAR2(100));
        INSERT INTO TAB1 (COL1, COL2) VALUES (1, 'one');
        INSERT INTO TAB1 (COL1, COL2) VALUES (2, 'two');   
        INSERT INTO TAB1 (COL1, COL2) VALUES (3, 'three');    
        INSERT INTO TAB1 (COL1, COL2) VALUES (4, 'four');             
        CREATE TABLE TAB2 (COL1 NUMBER, COL2 VARCHAR2(100));  
        INSERT INTO TAB2 (COL1, COL2) VALUES (2, 'two');
        INSERT INTO TAB2 (COL1, COL2) VALUES (3, 'three');  
        COMMIT;
    Answer the questions:
    1. How try to update TAB1 with unlimiting waiting?
    2. How try to update TAB1 table with waiting 1 min?
    3. How try to update TAB1 table without waiting and with message on screen if 
    updating not available?
    4. How lock only rows in TAB1 where TAB1.COL1 = TAB2.COL1? TAB2 must be 
    available for update. TAB1 with COL1 <> TAB2.COL1 must be available for update.
    5. How to save FOR UPDATE actions for TAB1 in database?
    6. How do not save FOR UPDATE actions for TAB1 in database?
Solution:
    --1
    SELECT COL1, COL2 FROM TAB1
    FOR UPDATE;
    --2 
    SELECT COL1, COL2 FROM TAB1
    FOR UPDATE wait 60;    
    --3
    SELECT COL1, COL2 FROM TAB1
    FOR UPDATE nowait;   
    --4
    SELECT t1.COL1, 
           t1.COL2
        FROM TAB1 t1
            JOIN TAB2 t2
            ON t1.COL1 = t2.COL1
    FOR UPDATE of t1.COL1;    
    --5
    SELECT COL1, COL2 FROM TAB1
    FOR UPDATE;
    COMMIT;
    --6
    SELECT COL1, COL2 FROM TAB1
    FOR UPDATE;
    ROLLBACK;  
        
Task 13.3.4. Perform Insert, Update and Delete operations. UPDATE.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 VARCHAR2(100));
            INSERT INTO TAB1 (COL1, COL2) VALUES (1, 'one');
            INSERT INTO TAB1 (COL1, COL2) VALUES (2, 'two');    
        CREATE TABLE TAB2 (COL1 NUMBER, COL2 VARCHAR2(100));  
            INSERT INTO TAB2 (COL1, COL2) VALUES (NULL, 'two');
            INSERT INTO TAB2 (COL1, COL2) VALUES (4,    'four');   
        COMMIT;
    Then:
    1. Update rows in TAB1.COL1 by value 111 only if TAB1.COL1 = 1 and 
    TAB1.COL2 = 'one'. Two ways.
    2. Update rows in TAB2.COL1 by value from TAB1.COL1 if TAB2.COL2 = TAB1.COL2.
    3. Update all rows in TAB2 for COL1 and COL2 simultaneously by values 5, 'five'.
    4. After action №3 update simultaneously TAB1.COL2, TAB1.COL1 if TAB1.COL2 = 'one' 
    by values from TAB2.COL2, TAB2.COL1 after DISTINCT.
    5. Update TAB1 by NULL values.
Solution:
    --1
    UPDATE TAB1
        SET COL1 = 111
            WHERE COL1 = 1 AND
                  COL2 = 'one';
    UPDATE (SELECT COL1 
                FROM TAB1 
                    WHERE COL1 = 1 AND 
                          COL2 = 'one')
        SET COL1 = 111;
    --2
    UPDATE TAB2 t2
        SET t2.COL1 = (SELECT t1.COL1 
                           FROM TAB1 t1
                               WHERE t1.COL2 = t2.COL2)
            WHERE t2.COL2 = (SELECT t1.COL2 
                                 FROM TAB1 t1
                                     WHERE t1.COL2 = t2.COL2);
    --3
    UPDATE TAB2
        SET COL1 = 5,
            COL2 = 'five';
    --4
    UPDATE TAB1
        SET (COL2, COL1) = (SELECT DISTINCT COL2, 
                                            COL1                                 
                                FROM TAB2)
            WHERE COL2 = 'one';
    --5
    UPDATE TAB1
        SET COL1 = NULL,
            COL2 = NULL;
                        
Task 13.3.5. Perform Insert, Update and Delete operations. DELETE.
    Do the next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 VARCHAR2(100));
            INSERT INTO TAB1 (COL1, COL2) VALUES (1, 'one');
            INSERT INTO TAB1 (COL1, COL2) VALUES (2, 'two');   
            INSERT INTO TAB1 (COL1, COL2) VALUES (3, 'three');    
            INSERT INTO TAB1 (COL1, COL2) VALUES (4, 'four');             
        CREATE TABLE TAB2 (COL1 NUMBER, COL2 VARCHAR2(100));  
            INSERT INTO TAB2 (COL1, COL2) VALUES (2, 'two');
            INSERT INTO TAB2 (COL1, COL2) VALUES (3, 'three');  
            INSERT INTO TAB2 (COL1, COL2) VALUES (4, NULL);
        COMMIT;
    Then:
    1. Delete rows from TAB1 if TAB1.COL2 equal 'one'.    
    2. Delete rows from TAB1 if TAB1.COL2 not equal values from subquery to TAB2.COL2.
    3. Delete rows from TAB2 if COL1 equal 4 and COL2 equal NULL.
    4. Clean TAB2. Two ways.
Solution:
    --1
    DELETE FROM TAB1
        WHERE COL2 = 'one';
    --2
    DELETE TAB1
        WHERE COL2 NOT IN (SELECT NVL(COL2, 'zzz') FROM TAB2);
    --3
    DELETE TAB2
        WHERE COL1 = 4 AND
              COL2 IS NULL;
    --4
    DELETE TAB2; COMMIT;
    TRUNCATE TABLE TAB2;

Task 13.4.1. Performing multi table Inserts
    Do next operations:
        DROP TABLE TAB1;
        DROP TABLE TAB2;
        DROP TABLE TAB3;
        CREATE TABLE TAB1 (COL1 NUMBER,
                           COL2 VARCHAR2(100),
                           COL3 DATE);
        INSERT INTO TAB1 (COL1, COL2, COL3) VALUES (1, 'AA', SYSDATE);
        INSERT INTO TAB1 (COL1, COL2, COL3) VALUES (2, 'BB', SYSDATE);
        INSERT INTO TAB1 (COL1, COL2, COL3) VALUES (3, 'BB', SYSDATE);        
        COMMIT;
        CREATE TABLE TAB2 (COLN NUMBER,
                           COLV VARCHAR2(100));    
        CREATE TABLE TAB3 (COLN NUMBER,
                           COLD DATE);                           
    Then do next operations:        
    1. Insert data from TAB1 to TAB2 and TAB3 at the same time.
    2. Insert data from TAB1 to TAB2(if TAB1.COL1 > 2) and TAB3(if TAB1.COL2 = 'BB').
    Which rows will be inserted in TAB2 and in TAB3?
    3. Insert data from TAB1 to TAB2(if TAB1.COL1 > 2) and TAB3(if TAB1.COL2 = 'BB'),
    but if 'if TAB1.COL1 > 2' will be met, then skip insert to TAB3.
    Which rows will be inserted in TAB2 and in TAB3?
    4. Write restrictions on multitable INSERT.
Solution:
    --1
    INSERT ALL
        INTO TAB2 (COLN, COLV) VALUES (COL1, COL2)
        INTO TAB3 (COLN, COLD) VALUES (COL1, COL3)
            SELECT COL1, COL2, COL3
                FROM TAB1;
    --2
    INSERT ALL
        WHEN COl1 > 2 THEN
            INTO TAB2 (COLN, COLV) VALUES (COl1, COL2)
        WHEN COL2 = 'BB' THEN
            INTO TAB3 (COLN, COLD) VALUES (COL1, COL3)
                SELECT COL1, COL2, COL3
                    FROM TAB1;
    "TAB2"
    COLN    COLV
    3        BB
    "TAB3"
    COLN    COLD
    2        15.05.2020 17:43:00
    3        15.05.2020 17:43:00
    --3
    INSERT FIRST
        WHEN COl1 > 2 THEN
            INTO TAB2 (COLN, COLV) VALUES (COl1, COL2)
        WHEN COL2 = 'BB' THEN
            INTO TAB3 (COLN, COLD) VALUES (COL1, COL3)
                SELECT COL1, COL2, COL3
                    FROM TAB1;    
    "TAB2"
    COLN    COLV
    3        BB
    "TAB3"
    COLN    COLD
    2        15.05.2020 17:43:00
    --4
    - Multitable INSERT available only for tables;
    - Can`t use Multitable INSERT on remote table (table in another database);
    - Can`t specify a table collection expression;  
    
Task 13.5.1. Performing Merge statements    
    Do next operations:
        DROP TABLE WAREHOUSE1;
        DROP TABLE WAREHOUSE2;
        DROP TABLE ALL_WRH;
            CREATE TABLE WAREHOUSE1(ITEM VARCHAR2(100), QUANTITY NUMBER);
            INSERT INTO WAREHOUSE1 (ITEM, QUANTITY) VALUES ('ITEM1',10);
            INSERT INTO WAREHOUSE1 (ITEM, QUANTITY) VALUES ('ITEM2',20);
            INSERT INTO WAREHOUSE1 (ITEM, QUANTITY) VALUES ('ITEM3',30);
                CREATE TABLE WAREHOUSE2(ITEM VARCHAR2(100), QUANTITY NUMBER);
                INSERT INTO WAREHOUSE2 (ITEM, QUANTITY) VALUES ('ITEM2',20);
                INSERT INTO WAREHOUSE2 (ITEM, QUANTITY) VALUES ('ITEM3',30);
                INSERT INTO WAREHOUSE2 (ITEM, QUANTITY) VALUES ('ITEM4',40);
                    CREATE TABLE ALL_WRH (ITEM VARCHAR2(100), QUANTITY NUMBER);
    Then do next operations:
    1. Merge data from WAREHOUSE1 into ALL_WRH: 
    when ALL_WRH.ITEM = WAREHOUSE1.ITEM then UPDATE ALL_WRH,
    when ALL_WRH.ITEM <> WAREHOUSE1.ITEM then INSERT rows into ALL_WRH.
    Write which data will be in ALL_WRH.
    2. Merge data from WAREHOUSE2 into ALL_WRH :
    when ALL_WRH.ITEM = WAREHOUSE2.ITEM then DELETE this rows from ALL_WRH,
    when ALL_WRH.ITEM <> WAREHOUSE2.ITEM then INSERT rows into ALL_WRH.
    Write which data will be in ALL_WRH.
Solution:
    --1 
    --'ITEM1', 10
    --'ITEM2', 20
    --'ITEM3', 30
    MERGE INTO ALL_WRH DEST
    USING (SELECT ITEM,
                  QUANTITY
               FROM WAREHOUSE1) SRC                     
    ON (DEST.ITEM = SRC.ITEM)
    WHEN MATCHED THEN
        UPDATE SET DEST.QUANTITY = SRC.QUANTITY
    WHEN NOT MATCHED THEN
        INSERT (DEST.ITEM,
                DEST.QUANTITY) VALUES (SRC.ITEM,
                                       SRC.QUANTITY);
    COMMIT;  
    --2
    --'ITEM1', 10
    --'ITEM4', 40
    MERGE INTO ALL_WRH DEST
    USING (SELECT ITEM,
                  QUANTITY
               FROM WAREHOUSE2) SRC
    ON (DEST.ITEM = SRC.ITEM)
    WHEN MATCHED THEN
        UPDATE SET DEST.QUANTITY = SRC.QUANTITY
        DELETE WHERE DEST.ITEM = SRC.ITEM
    WHEN NOT MATCHED THEN 
        INSERT (DEST.ITEM,
                DEST.QUANTITY) VALUES (SRC.ITEM,
                                       SRC.QUANTITY);
    COMMIT;    


CHAPTER 14. "Use DDL to manage tables and their relationships"
14.1. Describing and Working with Tables
14.2. Describing and Working with Columns and Data Types
14.3. Creating tables
14.4. Dropping columns and setting column UNUSED
14.5. Truncating tables
14.6. Creating and using Temporary Tables
14.7. Creating and using external tables
14.8. Managing Constraints

Task 14.1.1.-14.2.1 Naming rules
    Write naming rules.
Solution:
    1. Begin with letter,
    2. Name long <= 30 symbols (in Oracle 12c Release 2 <= 128).
    3. Contain only: A-Z; a-z; 0-9; _; $; #.
    4. One user can`t create objects with same names.
    5. For name not allowed using Oracle`s server-reserved words.
    6. In double quotation marks can write any name, but always must use this name 
    with "".
    
Task 14.2.2. Describing and Working with Columns and Data Types
    Explain data types:
    1. LONG;
    2. CLOB;
    3. NCLOB;
    4. RAW(size);
    5. LONG RAW;
    6. BLOB;
    7. BFILE;
    8. ROWID;
    9. TIMESTAMP;
    10. INTERVAL YEAR TO MONTH;
    11. INTERVAL DAY TO SECOND;
Solution:
    --1 LONG
    Variable-length character data (up to 2 gb). A LONG column is not copied when
    a table is created using a subquery. A LONG column cannot be included in a 
    GROUP BY or an ORDER BY clause. Only one LONG column can be used per table. 
    Constraints can`t be defined on a long column.
    --2 CLOB
    A character large object containing single-byte or multibyte characters. Maximum
    size is (4gb - 1) * (DB_BLOCK_SIZE). Stores national character set data.
    --3 NCLOB
    A character large object containing Unicode characters. Both fixed-width and 
    variable-width character sets are supported, both using the database national 
    character set. Maximum size is (4 gb - 1) * (database block size); stores national
    character set data.
    --4 RAW (size) 
    Raw binary data of length size bytes. You must specify size for a RAW value.
    Maximum size is: 32767 bytes if MAX_SQL_STRING_SIZE = EXTENDED, 4000 bytes if 
    MAX_SQL_STRING_SIZE = LEGACY
    --5 LONG RAW
    Raw binary data of variable length up to 2 gb.
    --6 BLOB
    A binary large object. Maximum size is (4 gb - 1) * (DB_BLOCK_SIZE initializtion
    parameter (8TB to 128 TB)).
    --7 BFILE
    Binary data stored in an external file (up to 4gb).
    --8 ROWID
    Base 64 string representing the unique address of a row in its table. This data
    type is primarily for values returned by the ROWID pseudocolumn.
    --9 TIMESTAMP
    Enables storage of time as a date with fractional seconds. It stores the year, 
    month, day, hour, minute, and the second value of the DATE data type, as well as
    the fractional seconds value. Variations: TIMESTAMP WITH TIMEZONE and TIMESTAMP
    WITH LOCALTIMEZONE.
    --10 INTERVAL YEAR TO MONTH
    Enables storage of time as an interval of years and months; used to represent the 
    difference between two datetime values in which the only significant portions are 
    the year and month.
    --11 INTERVAL DAY TO SECOND
    Enables storage of time as an interval of days, hours, minutes, and seconds; used
    to represent the precise difference between two datetime values.        
    
Task 14.3.1. Creating tables. CREATE + Constraints
    1. Create table TAB with column 'COL1' NUMBER, 'COL2' NUMBER
    COL1 can`t have NULL values and will use for relation in table TAB1 (if delete 
    write null).
    COL2 can have NULL values and will use for relation in table TAB2 (if delete 
    write condtiton other then null).
    2. Create table TAB1 with constraints using column level syntax. For each column 
    set default value = 10. One column can`t have NULL values.
    3. Create table TAB2 with constraints using table level syntax. For each column
    set default value = 10. One column can`t have NULL values. Primary key must have 
    two columns. In tables must be two columns (except primary key), where not allow 
    duplicates for this columns together.
Solution:
    --1
    CREATE TABLE TAB(COL1 NUMBER PRIMARY KEY
                     COL2 NUMBER UNIQUE);
    --2
    CREATE TABLE TAB1
        (COL1 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_PK PRIMARY KEY,
         COL2 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_FK REFERENCES TAB(COL1) 
                                                                ON DELETE SET NULL,
         COL3 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_NN NOT NULL,
         COL4 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_UN UNIQUE,
         COL5 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_CH CHECK (COL5 BETWEEN 10 AND 20));
    --3
    CREATE TABLE TAB2
        (COL1 NUMBER DEFAULT 10,
         COL2 NUMBER DEFAULT 10,
         COL3 NUMBER DEFAULT 10,
         COL4 NUMBER DEFAULT 10,
         COL5 NUMBER DEFAULT 10,
         CONSTRAINT TAB2_C_PK PRIMARY KEY (COL1, COL2),
         CONSTRAINT TAB2_C_FK FOREIGN KEY (COL2) REFERENCES TAB(COL2) 
                                                                ON DELETE CASCADE
         CONSTRAINT TAB2_C_NN CHECK (COL3 IS NOT NULL),
         CONSTRAINT TAB2_C_U1 UNIQUE (COL4, COL5),
         CONSTRAINT TAB2_C_CH CHECK (COL5 BETWEEN 10 AND 20));
         
Task 14.3.2. Creating tables. FLASHBACK.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (COL1 NUMBER, COL2 NUMBER);
        INSERT INTO TAB1 (COL1, COL2) VALUES(10, 111);
        INSERT INTO TAB1 (COL1, COL2) VALUES(20, 222);
        INSERT INTO TAB1 (COL1, COL2) VALUES(20, 333);
        COMMIT;
    Then do next operations:
    1. Which object are stored info about dropped tables.
    2. How remove dropped tables.
    3. What mean SCN.
    4. Remove table TAB1 and then restore TAB1.
    5. Update COL2 with value = 444, if COL1 = 20. Show history of updating for COL2,
    where can see old values and new values.
Solution:
    --1
    SELECT * 
        FROM RECYCLEBIN;
    --2
    PURGE RECYCLEBIN;
    --3
    The SCN (system change number) is an integer value associated with each change
    to the database. Is is unique incremental number in the database. Every time you
    commit a transaction, a new SCN is recorded.
    --4
    DROP TABLE TAB1;
    FLASHBACK TABLE TAB1
        TO BEFORE DROP;
    --5
    UPDATE TAB1
        SET COL2 = 444
            WHERE COL1 = 20;
    COMMIT--without commit we can`t see VERSIONS_STARTTIME and VERSIONS_ENDTIME
    SELECT VERSIONS_STARTTIME,
           VERSIONS_ENDTIME,
           COL2
        FROM TAB1
            VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
                WHERE COL1 = 20;         

Task 14.4.1. Dropping columns and setting column UNUSED. ALTER.
    Do the next operations:
        DROP TABLE TAB;
        CREATE TABLE TAB (COL1 NUMBER(5,2), COL2 VARCHAR2(4));       
        INSERT INTO TAB (COL1, COL2) VALUES (110.25, 'one');
    Then do next operations:
    1. Add column COL4 DATE with default value = SYSDATE and not null. 
    2. Change name COL4 on COL3.
    3. Set COL2 default 'zzz'.
    4. Set COL3 without duplicates (null allow). Two ways.
    5. For COL2 remake to CHAR type with minimum long as possible.
    6. For COL1 remake type for can insert 1111.999.
    7. For COL3 make not use (two ways). Which object in dictionary contain info
    about this not used columns and table, list columns.
    8. Add in table again column with name COL3 DATE.
    9. Delete not using columns.
    10. Delete COL2, COL3 from table.
    11. Disable for table allow change data.
    12. Enable for table allow change data.
    13. Change name for table TAB to TABTAB. Two ways.
    14. Remove table TABTAB from database. Two ways. Explain it.
Solution:
    --1
    ALTER TABLE TAB ADD COL4 DATE 
        DEFAULT SYSDATE 
            NOT NULL;
    --2
    ALTER TABLE TAB RENAME COLUMN COL4 TO COL3;
    --3
    ALTER TABLE TAB MODIFY COL2 DEFAULT 'zzz';
    --4
    ALTER TABLE TAB ADD CONSTRAINT CON_C1 UNIQUE (COL3);
    ALTER TABLE TAB MODIFY COL3 UNIQUE;
    --5
    ALTER TABLE TAB MODIFY COL2 CHAR(3);
    --6
    ALTER TABLE TAB MODIFY COL1 NUMBER(7, 3);
    --7
    ALTER TABLE TAB SET UNUSED (COL3) ONLINE;
    --ALTER TABLE TAB SET UNUSED COLUMN COL3 ONLINE;
    SELECT TABLE_NAME, COUNT
        FROM USER_UNUSED_COL_TABS
            WHERE TABLE_NAME = 'TAB';
    --8
    ALTER TABLE TAB ADD COL3 DATE;
    --9
    ALTER TABLE TAB DROP UNUSED COLUMNS;
    --10
    ALTER TABLE TAB DROP (COL2, COL3);
    --11
    ALTER TABLE TAB READ ONLY;
    --12
    ALTER TABLE TAB READ WRITE;
    --13
    RENAME TAB TO TABTAB;
    --ALTER TABLE TAB RENAME TO TABTAB;
    --14
    DROP TABLE TABTAB; --drop in recycle bin, can be recovered
    --DROP TABLE TABTAB PURGE; --drop forever

Task 14.6.1. Creating and using Temporary Tables. GLOBAL TEMPORARY TABLE
    1. Create global table. Two options. Explain it.
Solution:
    DROP TEMP1;
    DROP TEMP2;
    --global temporary tables save data only for session. When session ended table
    --will be clean.
    CREATE GLOBAL TEMPORARY TABLE TEMP1 (COL1 NUMBER, COL2 VARCHAR2(100))
        ON COMMIT DELETE ROWS--this mean that after COMMIT rows will be removed
    CREATE GLOBAL TEMPORARY TABLE TEMP2 (COL1 NUMBER, COL2 VARCHAR2(100))
        ON COMMIT PRESERVE ROWS--after COMMIT rows will be save in session

Task 14.7.1. Creating and using external tables. SQL LOADER.
    Do next operations:
        DROP TABLE FOR_EXT_TAB;
        CREATE TABLE FOR_EXT_TAB(COL1 NUMBER, COL2 VARCHAR2(100));
    Then do next operations:    
    1. Load data from external table to TAB1;    
Solution:
    --1
    Create in directory (for example D:\) 'my_table.csv' file with two columns 
    delimited by ";".
    With data:
    1;one
    2;two
    3;three
    --2
    Create 'my_table.ctl' file in the same directory with 'my_table.csv'.
    Paste next text into 'my_table.ctl':
        LOAD DATA
        INFILE 'D:\my_table.csv'
        APPEND
        INTO TABLE FOR_EXT_TAB
        FIELDS TERMINATED BY ';' 
        (
        COL1,
        COL2
        )
    --3
    Execute next command in CMD for Windows with Username hr/hr@orclpdb:
    sqlldr control=D:\my_table.ctl log=D:\my_table.log
    
Task 14.7.2. Creating and using external tables. EXTERNAL TABLES.
    Do next operations:
        DROP TABLE FOR_EXT_TAB;
        CREATE TABLE FOR_EXT_TAB(COL1 NUMBER, COL2 VARCHAR2(100));
        INSERT INTO FOR_EXT_TAB(COL1, COL2) VALUES (111, 'AAA');
        INSERT INTO FOR_EXT_TAB(COL1, COL2) VALUES (222, 'BBB');
        COMMIT;
    Then do next operations: 
    1. Explain what mean external table. How to create external table?
    2. Access to external table with oracle_loader.
    3. Access to external table with oracle_datapump.
Solution:
    --1 
    External table is read only (DML, indexes not allowed), which metadata is stored 
    in the database. 
    Create 'ext_tab.csv' with two columns delimited by ";" in directory 'D:\external'. 
    Connect to database sys as sysdba.
    Then do:
        Alter session set container=orclpdb; --or another DB 
        grant create any DIRECTORY to my_schema;
    CREATE OR REPLACE DIRECTORY MY_DIR AS 'D:\external';
    --2 
    CREATE TABLE TAB_LOADER (COL1 NUMBER
                             COL2 VARCHAR2(100))
        ORGANIZATION EXTERNAL 
            (
            TYPE ORACLE_LOADER
            DEFAULT DIRECTORY MY_DIR
            ACCESS PARAMETERS (RECORDS DELIMITED BY NEWLINE
                               FIELDS TERMINATED BY ';')
            LOCATION ('ext_tab.csv')
            )
        REJECT LIMIT UNLIMITED; --but DEFAULT = 0        
    SELECT * FROM TAB_LOADER;
    --3
    --3.1.
    CREATE TABLE TAB_PUMP (COL1, 
                           COL2) --table will be created with data from 
                                 --ext_tab_pump.dmp
        ORGANIZATION EXTERNAL 
            (
            TYPE ORACLE_DATAPUMP
            DEFAULT DIRECTORY MY_DIR
            LOCATION ('ext_tab_pump.dmp') --this table will be store data from 
                                          --FOR_EXT_TAB
            )
            AS SELECT COL1, 
                      COL2
                   FROM FOR_EXT_TAB;                 
    SELECT * FROM TAB_PUMP;
    --3.2. create table for read data from created table 'ext_tab_pump.dmp'
    CREATE TABLE TAB_PUMP_READ (COL1 NUMBER,
                                COL2 VARCHAR2(100))
        ORGANIZATION EXTERNAL 
            (
            TYPE ORACLE_DATAPUMP
            DEFAULT DIRECTORY MY_DIR
            LOCATION ('ext_tab_pump.dmp')
            );
    SELECT * FROM TAB_PUMP_READ;
    
Task 14.8.1. Managing Constraints. USER_CONSTRAINTS.
    Do next operations.
    DROP TABLE TAB0;
    DROP TABLE TAB1;
    CREATE TABLE TAB0(COL1 NUMBER PRIMARY KEY
                      COL2 NUMBER UNIQUE);    
    CREATE TABLE TAB1
        (COL1 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_PK PRIMARY KEY,
         COL2 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_FK REFERENCES TAB0(COL1) 
                                                                    ON DELETE CASCADE
         COL3 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_NN NOT NULL,
         COL4 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_UN UNIQUE,
         COL5 NUMBER DEFAULT 10 CONSTRAINT TAB1_C_CH CHECK (COL5 BETWEEN 10 AND 20));    
    Then do next operations:    
    1. Show name of table, name of column and all columns about constraints for TAB1.
Solution:
    SELECT ucc.TABLE_NAME,
           ucc.COLUMN_NAME,
           uc.*           
        FROM USER_CONSTRAINTS uc
            LEFT JOIN USER_CONS_COLUMNS ucc
            ON uc.CONSTRAINT_NAME = ucc.CONSTRAINT_NAME            
                WHERE uc.TABLE_NAME = 'TAB1'
                    ORDER BY uc.CONSTRAINT_NAME
       
Task 14.8.2. Managing Constraints. ALTER CONSTRAINTS.
    Do next operations:
    DROP TABLE TAB1;
    DROP TABLE TAB2;
        CREATE TABLE TAB1(COL1 NUMBER PRIMARY KEY, COL2 NUMBER);
        INSERT INTO TAB1(COL1, COL2) VALUES(1, 10);   
            CREATE TABLE TAB2(COL1 NUMBER REFERENCES TAB1(COL1), COL2 VARCHAR2(100));
            INSERT INTO TAB2(COL1, COL2) VALUES(1, 'one');
                COMMIT;
    Then do next operations:    
    1. Drop PRIMARY KEY from TAB1.
    2. Make TAB1.COL1 as PRIMARY KEY. Two syntax.
    3. Make TAB2.COL1 as FOREIGN KEY with relation to TAB1.COL1. Two syntax.
    4. Disable primary key in TAB1.COL1 and foreign key in TAB2.COL1. Two syntax.
       Enable primary key TAB1.COL1 and foreign key in TAB2.COL1.   
    5. Remove column TAB1.COL1.
    6. Create NOT NULL constraint with name 'CONS_TAB2_NN' for TAB2.COL2. Then rename 
    'CONS_TAB2_NN' to 'C_T2_NN'.
Solution:
    --1
    ALTER TABLE TAB1 DROP PRIMARY KEY CASCADE;
    --2
    ALTER TABLE TAB1 ADD CONSTRAINT TAB1_PK PRIMARY KEY (COL1);
        --ALTER TABLE TAB1 MODIFY COL1 PRIMARY KEY;
    --3
    ALTER TABLE TAB2 ADD CONSTRAINT TAB2_FK FOREIGN KEY (COL1) 
        REFERENCES TAB1(COL1);
        --ALTER TABLE TAB2 MODIFY COL1 REFERENCES TAB1(COL1); 
    --4
    ALTER TABLE TAB1 DISABLE PRIMARY KEY CASCADE;
    --ALTER TABLE TAB1 DISABLE CONSTRAINT TAB1_PK CASCADE;
        ALTER TABLE TAB1 ENABLE PRIMARY KEY;
        --ALTER TABLE TAB1 ENABLE CONSTRAINT TAB1_PK;
            ALTER TABLE TAB2 ENABLE CONSTRAINT TAB2_FK;        
    --5
    ALTER TABLE TAB1 DROP COLUMN COL1 CASCADE CONSTRAINTS;
    --6
    ALTER TABLE TAB2 ADD CONSTRAINT CONS_TAB2_NN CHECK(COL2 IS NOT NULL);
    ALTER TABLE TAB2 RENAME CONSTRAINT CONS_TAB2_NN TO C_T2_NN;

Task 14.8.3. Managing Constraints. DEFERRABLE CONSTRAINTS.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1(COL1 NUMBER, COL2 NUMBER);
    Then do next operations: 
    1. For COL1, COL2 create different deferrable constraints. Explain it.
    2. Change behavior deferrable constraint for session.
Solution:
    --1
    ALTER TABLE TAB1 
        ADD CONSTRAINT C_CH_COL1 CHECK (COL1 > 6) 
            DEFERRABLE INITIALLY DEFERRED--it wil be violated when you try to commit
    ALTER TABLE TAB1 
        ADD CONSTRAINT C_CH_COL2 CHECK (COL2 < 5) 
            DEFERRABLE INITIALLY IMMEDIATE--it wil be violated immediate
    --2
    SET CONSTRAINT C_CH_COL1 IMMEDIATE;
    SET CONSTRAINT C_CH_COL2 DEFERRED;
    
    
CHAPTER 15. "Controlling User Access"
15.1. Differentiating system privileges from object privileges.
15.2. Granting privileges on tables.
15.3. Distinguishing between granting privileges and roles.

Task 15.1.1 - 15.3.1.
    1. What mean system privileges, object privileges for users.
    2. Show list of users in database.
    3. Show all the system privileges available for the version release.
    4. Create new user "U1" and "U2" with password 123 and connect for them.
    5. User must be gain access to create: table, sequence, view, synonym.
    6. User must be gain access to SELECT for TAB1.
    7. User must be gain access insert values only into TAB1.COL2.
    8. Create role "my_role" which must be gain access to all privileges TAB1. Attach 
    this role to "U1". Explain which priviligies available in this role.
    9. Grant SELECT from TAB1 to all users in the database.
    10. Provide CREATE TABLE, then SELECT and DELETE for TAB1 to user U2, who can 
    assign this privilege to another user.
    11. Get back SELECT and DELETE for TAB1 from user U2.
    12. Provide SELECT for any tables to U2;
    13. Show what privilegies have U2 in session.
    14. Change password for user U2 from 123 to 123456.
    15. List dictionary`s views with data about privileges.
    16. Create table U2.MY_TAB (COL1 NUMBER), then remove user U2.
Solution:
    --1
    System privileges for gain access to the database and perfoming a particular 
    action within the database.
    Object privileges for manipulate the content of the objects in the database.
    --2
    SELECT * FROM ALL_USERS
    --3
    SELECT * FROM SYSTEM_PRIVILEGE_MAP
    --4
    login sys as sysdba;
    alter session set container=orclpdb;
        CREATE USER U1 IDENTIFIED BY 123;
        GRANT CREATE SESSION TO U1;
            CREATE USER U2 IDENTIFIED BY 123;
            GRANT CREATE SESSION TO U2;    
    --5 
    GRANT CREATE TABLE TO U1;
        GRANT UNLIMITED TABLESPACE TO U1;
    GRANT CREATE SEQUENCE
          CREATE VIEW
          CREATE SYNONYM TO U1;
    --6
    GRANT SELECT ON HR.TAB1 TO U1;
    --7
    GRANT INSERT(COL2) ON HR.TAB1 TO U1;
    --8
    --in this role will be available OBJECT privs, for SYSTEM privs need add new role
    CREATE ROLE MY_ROLE;
    GRANT ALL ON HR.TAB1 
        TO MY_ROLE; 
    GRANT MY_ROLE TO U1;
    --9
    GRANT SELECT ON HR.TAB1 TO PUBLIC;
    --10
    GRANT CREATE TABLE TO U2;
    GRANT SELECTDELETE ON HR.TAB1 
        TO U2
            WITH GRANT OPTION;
    --11
    REVOKE SELECTDELETE ON HR.TAB1 
        FROM U2;
    --12
    GRANT SELECT ANY TABLE TO U2;
    --13
    SELECT * FROM SESSION_PRIVS;
    --14
    ALTER USER U2 IDENTIFIED BY 123456;
    --15
    ROLE_SYS_PRIVS      - system privileges granted to roles;
    ROLE_TAB_PRIVS      - table privileges granted to roles;
    USER_ROLE_PRIVS     - roles accessible by the user;
    USER_SYS_PRIVS      - system privileges granted to the user;
    USER_TAB_PRIVS_MADE - object privileges granted on the user`s objects;
    USER_TAB_PRIVS_RECD - object privileges granted to the user;
    USER_COL_PRIVS_MADE - object privs granted on the columns of the user`s objects;
    USER_COL_PRIVS_RECD - object privileges granted to the user on specific columns.
    --16
    CREATE TABLE MY_TAB(COL1 NUMBER);
    DROP USER U2 CASCADE;    


CHAPTER 16. "Managing Data in Different Time Zones"
16.1. Working with CURRENT_DATECURRENT_TIMESTAMP,and LOCALTIMESTAMP.
16.2. Working with INTERVAL data types.

Task 16.1.1. Working with CURRENT_DATECURRENT_TIMESTAMP,and LOCALTIMESTAMP.
    1. Create table with three columns: first not contain time zone, second contain 
    time zone, third contain local time zone.
    2. Show the current date and time for user session (timestamp with time zone).
    Show the current date and time for user session (timestamp).
    3. Show system date at the timestamp type.
    4. Select data from table with zones names. Explain zone names.
    5. Show the database time zone.
    6. Show the session time zone.
    7. Show current date for user session.
    8. Change session`s time zone to 'AMERICA/DETROIT'.
    9. Show offset of timezone 'EUROPE/AMSTERDAM'.
    10. Convert 25.11.2000 10:10:05 to timestamp.
    11. Convert 25.11.2000 10:10:05 to timestamp with time zone 'EUROPE/AMSTERDAM'.
    12. Which values accept fractional seconds precision? Default value?
Solution:
    --1
    DROP TABLE TAB1;    
    CREATE TABLE TAB1 (COL1 TIMESTAMP
                       COL2 TIMESTAMP WITH TIME ZONE,
                       COL3 TIMESTAMP WITH LOCAL TIME ZONE);
    --2
    SELECT CURRENT_TIMESTAMP 
        FROM DUAL;
    SELECT LOCALTIMESTAMP 
        FROM DUAL;
    --3
    SELECT SYSTIMESTAMP 
        FROM DUAL;
    --4
    SELECT * 
        FROM V$TIMEZONE_NAMES;
    --5
    SELECT DBTIMEZONE 
        FROM DUAL;
    --6
    SELECT SESSIONTIMEZONE 
        FROM DUAL;
    --7
    SELECT CURRENT_DATE 
        FROM DUAL; 
    --8
    ALTER SESSION SET TIME_ZONE = 'AMERICA/DETROIT';
    --9
    SELECT TZ_OFFSET('EUROPE/AMSTERDAM')
        FROM DUAL;
    --10
    SELECT TO_TIMESTAMP('25.11.2000 10:10:05','DD.MM.YYYY HH:MI:SS')
        FROM DUAL;
    --11
    SELECT FROM_TZ(TIMESTAMP '2000-11-25 10:10:05', 'EUROPE/AMSTERDAM')
        FROM DUAL;
    --12
    0-9. Default = 6.

Task 16.2.1. Working with INTERVAL data types. Interval.
    1. Show interval for 1 year and 2 months. Write result.
    2. Show interval for 1 year and 12 months. Write result.
    3. Show interval for 100 years and 120 months. Write result.
    4. Show interval for 121 months (using only month). Write result.
    5. Show interval for -100 years (using only year). Write result.
    6. Show interval for 30 days and 20 hours and 20 min. Write result.
    7. Show interval for 333 days and 10 hours and 10 sec. Write result.
    8. Show interval for 240 hours (using only hour). Write result.
    9. Show interval for 1200 minutes (using only minutes). Write result.
    10. Show interval for 100 days (using only days). Write result.
    11. Show interval for 606 seconds (using only seconds). Write result.
Solution:
    SELECT
        /* 1)  +01-02  */ INTERVAL '1-2' YEAR TO MONTH,
        /* 2)  +02-00  */ INTERVAL '2-0' YEAR TO MONTH,
        /* 3)  +110-00 */ INTERVAL '110-0' YEAR(3) TO MONTH,
        /* 4)  +10-01  */ INTERVAL '121' MONTH,
        /* 5)  -100-00 */ INTERVAL '-100' YEAR(3),
        /* 6)  +30 20:20:00.000000  */ INTERVAL '30 20:20:00' DAY TO SECOND,
        /* 7)  +333 10:00:10.000000 */ INTERVAL '333 10:00:10' DAY(3) TO SECOND,
        /* 8)  +10 00:00:00 */ INTERVAL '240' HOUR,
        /* 9)  +00 20:00:00 */ INTERVAL '1200' MINUTE,
        /* 10) +100 00:00:00 */ INTERVAL '100' DAY(3),
        /* 11) +00 00:10:06.000000 */ INTERVAL '606' SECOND
        FROM DUAL;        

Task 16.2.2. Working with INTERVAL data types. Interval. Add interval, to interval, 
extract.
    Do next operations:
        DROP TABLE TAB1;
        CREATE TABLE TAB1 (COL1 DATE);
        INSERT INTO TAB1 
            VALUES(TO_DATE('01.01.2000 10:30:00', 'DD.MM.YYYY HH24:MI:SS'));
        COMMIT;
    Then do next operations:
    1. To COL1 add 1 year and 10 months. Two ways.
    2. To COL1 add 100 years and 120 months. Two ways.
    3. To COL1 add 15 days and 12 hours. Two ways.
    4. To COL1 add 120 days and 600 seconds. Two ways.
    5. Select only year.
    6. Select only month.
    7. Select only day.
Solution:   
    SELECT 
        /* 1.1. */ COL1 + INTERVAL '1-10' YEAR TO MONTH,
        /* 1.2. */ COL1 + TO_YMINTERVAL('1-10'),
        /* 2.1. */ COL1 + INTERVAL '100' YEAR(3) + INTERVAL '120' MONTH,
        /* 2.2. */ COL1 + TO_YMINTERVAL('100-00') + INTERVAL '120' MONTH,
        /* 3.1. */ COL1 + INTERVAL '15 12:00:00' DAY TO SECOND,
        /* 3.2. */ COL1 + TO_DSINTERVAL('15 12:00:00'),
        /* 4.1. */ COL1 + INTERVAL '120' DAY(3) + INTERVAL '600' SECOND,
        /* 4.2. */ COL1 + TO_DSINTERVAL('120 00:00:00') + INTERVAL '600' SECOND,
        /* 5 */ EXTRACT(YEAR FROM COL1),
        /* 6 */ EXTRACT(MONTH FROM COL1),
        /* 7 */ EXTRACT(DAY FROM COL1)
        FROM TAB1;