Obsah
Řešení úkolů Cvičení 1. Založení tabulky se specifikací fyzického uložení Úkol 1.1 CREATE TABLE projects ( proj_id NUMBER NOT NULL, proj_desc VARCHAR2(60 NOT NULL TABLESPACE users STORAGE (INITIAL 32K NEXT 32K PCTINCREASE 0 Úkol 1.2 ALTER TABLE projects MOVE TABLESPACE projects STORAGE (INITIAL 100 k NEXT 100 k PCTINCREASE 0
Cvičení 2. Partitionované tabulky Úkol 2.1 CREATE TABLE project_history ( item_id NUMBER NOT NULL, item_desc VARCHAR2(60, item_date DATE NOT NULL, proj_id NUMBER NOT NULL PARTITION BY RANGE (item_date (PARTITION ph_part_0607 VALUES LESS THAN (TO_DATE('01.08.2006','dd.mm.yyyy' TABLESPACE users, PARTITION ph_part_0608 VALUES LESS THAN (TO_DATE('01.09.2006','dd.mm.yyyy' TABLESPACE users, PARTITION ph_part_0609 VALUES LESS THAN (TO_DATE('01.10.2006','dd.mm.yyyy' TABLESPACE users Úkol 2.2 INSERT INTO project_history (item_id, item_desc, item_date, proj_id VALUES (1, 'Kick-off', SYSDATE, 1 UPDATE project_history SET item_date = item_date + 31 WHERE item_id = 1 Úkol 2.3 ALTER TABLE project_history ENABLE ROW MOVEMENT UPDATE project_history SET item_date = item_date + 31 WHERE item_id = 1 UPDATE project_history SET item_date = item_date + 365 WHERE item_id = 1
Cvičení 3. Vnořené tabulky Úkol 3.1 CREATE TYPE team_members_type AS TABLE OF VARCHAR2 (30 Úkol 3.2 ALTER TABLE projects ADD (team_members team_members_type NESTED TABLE team_members STORE AS nested_team_members (TABLESPACE users Úkol 3.3 INSERT INTO projects (proj_id, proj_desc, team_members VALUES (100, 'Školení', team_members_type ('Karel','Milan','Honza' Úkol 3.4 UPDATE TABLE (SELECT team_members FROM projects WHERE proj_id = 100 SET column_value = 'Michal' WHERE column_value = 'Karel' DELETE FROM TABLE (SELECT team_members FROM projects WHERE proj_id = 100 WHERE column_value = 'Honza' SELECT * FROM TABLE (SELECT team_members FROM projects WHERE proj_id = 100 ORDER BY column_value Úkol 3.5 INSERT INTO projects (proj_id, proj_desc, team_members VALUES (101, 'ALL_staff', CAST (MULTISET (SELECT last_name FROM employees AS team_members_type SELECT COUNT (* FROM TABLE (SELECT team_members FROM projects WHERE proj_id = 101 WHERE column_value LIKE 'K%'
Cvičení 4. Indexy (unikátní index, compozitní index, bitmapový index, funkční index Úkol 4.1 CREATE UNIQUE INDEX ph_pk ON project_history (item_id TABLESPACE users STORAGE (INITIAL 32 k NEXT 32 k PCTINCREASE 0 Úkol 4.2 CREATE INDEX ph_proj_fk_ind ON project_history (proj_id LOCAL Úkol 4.3 CREATE INDEX proj_desc_up_ind ON projects ( UPPER(proj_desc
Cvičení 5. Indexově organizovaná tabulka Úkol 5.1 CREATE TABLE project_files ( proj_id NUMBER NOT NULL, file_name VARCHAR2(30 NOT NULL, file_desc VARCHAR2(200, CONSTRAINT pf_pk PRIMARY KEY (proj_id, file_name ORGANIZATION INDEX TABLESPACE users INCLUDING file_name OVERFLOW TABLESPACE users Úkol 5.2 ALTER TABLE project_files MOVE COMPRESS 1
Cvičení 6. Synonyma a sekvence Úkol 6.1 CREATE SYNONYM prj FOR projects CREATE SYNONYM prh FOR project_history Úkol 6.2 CREATE SEQUENCE prh_seq MINVALUE 1000 INSERT INTO prh (item_id, item_desc, item_date, proj_id, VALUES (prh_seq.nextval, 'Test insert', sysdate, 100
Cvičení 7. Data dictionary Úkol 7.1 SELECT table_name FROM user_tab_columns WHERE column_name = 'DEPARTMENT_ID' AND table_name IN (SELECT table_name FROM user_tables Úkol 7.2 SELECT 'drop ' object_type ' ' object_name ';' FROM user_objects WHERE object_type IN ('VIEW', 'SEQUENCE', 'SYNONYM', 'PACKAGE' UNION SELECT 'drop table ' table_name ';' FROM user_tables WHERE table_name NOT LIKE 'BIN$%' AND table_name NOT LIKE 'SYS_IOT%'
Cvičení 8. Výrazy (podmíněný výraz, seznamy výrazů Úkol 8.1 SELECT last_name, hire_date, job_id, CASE WHEN job_id IN ('SA_REP', 'ST_CLERK', 'SH_CLERK' THEN phone_number WHEN job_id IN ('SA_MAN', 'ST_MAN' THEN 'xxxxxxxxxx' ELSE email END kontakt FROM employees WHERE department_id IN (50, 60, 70, 80 AND hire_date < DATE '1999-1-1'
Cvičení 9. Regulární výrazy Úkol 9.1 SELECT * FROM locations WHERE NOT regexp_like (postal_code, '^[0-9A-Z]*$', 'i' Úkol 9.2 SELECT * FROM locations WHERE regexp_like (postal_code, '^[0-9]{4,6}$'
Cvičení 10. Úkol 10.1 Dotazy (poddotazy, hierarchické dotazy, vytknutý dotaz SELECT last_name, department_id FROM employees WHERE department_id IN ( SELECT department_id FROM departments WHERE location_id IN ( SELECT location_id FROM locations WHERE country_id IN ( SELECT country_id FROM countries WHERE region_id = 1 Úkol 10.2 SELECT e.last_name, d.department_name, l.country_id FROM employees e, departments d, locations l WHERE e.department_id = d.department_id AND d.location_id = l.location_id AND d.department_id IN (SELECT department_id FROM employees GROUP BY department_id HAVING COUNT (* <= 4 Úkol 10.3 /* Formatted on 2006/07/14 14:43 (Formatter Plus v4.8.6 */ WITH city5_costs AS ( SELECT l.city, COUNT (* headcount, SUM (e.salary total_salary, AVG (e.salary avg_salary FROM locations l, departments d, employees e WHERE e.department_id = d.department_id AND d.location_id = l.location_id GROUP BY l.city HAVING COUNT (* >= 5 SELECT city, avg_salary FROM city5_costs WHERE avg_salary > (SELECT SUM (total_salary / SUM (headcount FROM city5_costs ORDER BY 2 DESC Úkol 10.4 SELECT d.department_name, NVL (e.last_name, 'Neznámé' manager, NVL (l.city, 'Neznámé' city FROM departments d LEFT OUTER JOIN employees e ON d.manager_id = e.employee_id LEFT OUTER JOIN locations l ON d.location_id = l.location_id Úkol 10.5 WITH americas_emps AS (
SELECT SELECT e.* FROM employees e, departments d, locations l, countries c WHERE e.department_id = d.department_id AND d.location_id = l.location_id AND l.country_id = c.country_id AND c.region_id = 2 LPAD ('>', LEVEL, '=' uroven, e.first_name, e.last_name, e.department_id FROM americas_emps e START WITH e.manager_id IS NULL OR e.manager_id NOT IN (SELECT employee_id FROM americas_emps CONNECT BY PRIOR e.employee_id = manager_id
Cvičení 11. Úkol 11.1 Constrainty ALTER TABLE projects add ( CONSTRAINT proj_id_pk PRIMARY KEY (proj_id USING INDEX TABLESPACE users STORAGE (INITIAL 32K NEXT 32K PCTINCREASE 0 Úkol 11.2 INSERT INTO projects (proj_id, proj_desc VALUES (1, 'SEP' ALTER TABLE project_history ADD ( CONSTRAINT ph_proj_fk FOREIGN KEY (proj_id REFERENCES projects ( proj_id
Cvičení 12. Úkol 12.1 Triggery CREATE OR REPLACE TRIGGER ph_bi_trg BEFORE INSERT ON project_history FOR EACH ROW BEGIN SELECT prh_seq.nextval, SYSDATE INTO :NEW.item_id, :NEW.item_date FROM DUAL; END; Úkol 12.2 CREATE OR REPLACE TRIGGER pj_au_trg AFTER UPDATE ON projects FOR EACH ROW BEGIN INSERT INTO project_history (item_desc, proj_id VALUES ('Zmìna projektoveho záznamu ' :NEW.proj_desc, :NEW.proj_id ; END;
Cvičení 13. XML (založení a úpravy dokumentů, registrace schematu, indexování Úkol 13.1 CREATE TABLE xml_orders (order_id NUMBER NOT NULL, xo XMLTYPE INSERT INTO xml_orders (order_id, xo VALUES (1, XMLTYPE ( '<?xml version="1.0" encoding="utf-8"?>' '<n:purchaseorder xmlns:n="http://cz.ness.com/sample/purchaseorder" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" >' ' <shipto>' ' <name>jack T. Ripper</name>' ' <street>2014 Jabberwocky Rd</street>' ' <city>southlake</city>' ' <state>texas</state>' ' <zip>26192</zip>' ' </shipto>' ' <billto>' ' <name>jack T. Ripper</name>' ' <street>2014 Jabberwocky Rd</street>' ' <city>southlake</city>' ' <state>texas</state>' ' <zip>26192</zip>' ' </billto>' ' <items>' ' <item partnum="111-aa">' ' <productname>diving mask</productname>' ' <quantity>1</quantity>' ' <USPrice>69</USPrice>' ' </item>' ' <item partnum="444-dd">' ' <productname>bicycle</productname>' ' <quantity>1</quantity>' ' <USPrice>840</USPrice>' ' </item>' ' <item partnum="666-ff">' ' <productname>blue pen</productname>' ' <quantity>10</quantity>' ' <USPrice>15</USPrice>' ' </item>' ' </items>' '</n:purchaseorder>' Úkol 13.2 SELECT EXTRACTVALUE (t.xo, '//shipto/city', EXTRACTVALUE (t.xo, '//item[1]/@partnum', t.xo.extract ('//billto'.getstringval ( FROM xml_orders t
Úkol 13.3 UPDATE xml_orders SET xo = UPDATEXML (xo, '//shipto/zip/text(', 1111, 'xmlns:n=http://cz.ness.com/sample/purchaseorder' WHERE order_id = 1 Úkol 13.4 BEGIN dbms_xmlschema.registerschema ('http://cz.ness.com/sample/purchaseorder', '<xsd:schema targetnamespace="http://cz.ness.com/sample/purchaseorder" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns="http://cz.ness.com/sample/purchaseorder" elementformdefault="unqualified" attributeformdefault="unqualified">' ' <xsd:annotation>' ' <xsd:documentation xml:lang="en">' 'Purchase order schema for Example.com.' 'Copyright 2000 Example.com. All rights reserved.' '</xsd:documentation>' ' </xsd:annotation>' ' <xsd:element name="purchaseorder" type="purchaseordertype"/>' ' <xsd:element name="comment" type="xsd:string"/>' ' <xsd:complextype name="purchaseordertype">' ' <xsd:sequence>' ' <xsd:element name="shipto" type="usaddress"/>' ' <xsd:element name="billto" type="usaddress"/>' ' <xsd:element ref="comment" minoccurs="0"/>' ' <xsd:element name="items" type="items"/>' ' </xsd:sequence>' ' <xsd:attribute name="orderdate" type="xsd:date"/>' ' </xsd:complextype>' ' <xsd:complextype name="usaddress">' ' <xsd:sequence>' ' <xsd:element name="name" type="xsd:string"/>' ' <xsd:element name="street" type="xsd:string"/>' ' <xsd:element name="city" type="xsd:string"/>' ' <xsd:element name="state" type="xsd:string"/>' ' <xsd:element name="zip" type="xsd:decimal"/>' ' </xsd:sequence>' ' <xsd:attribute name="country" type="xsd:nmtoken" fixed="us"/>' ' </xsd:complextype>' ' <xsd:complextype name="items">' ' <xsd:sequence>' ' <xsd:element name="item" minoccurs="0" maxoccurs="unbounded">' ' <xsd:complextype>' ' <xsd:sequence>' ' <xsd:element name="productname" type="xsd:string"/>' ' <xsd:element name="quantity">' ' <xsd:simpletype>' ' <xsd:restriction base="xsd:positiveinteger">'
' <xsd:maxexclusive value="100"/>' ' </xsd:restriction>' ' </xsd:simpletype>' ' </xsd:element>' ' <xsd:element name="usprice" type="xsd:decimal"/>' ' <xsd:element ref="comment" minoccurs="0"/>' ' <xsd:element name="shipdate" type="xsd:date" minoccurs="0"/>' ' </xsd:sequence>' ' <xsd:attribute name="partnum" type="sku" use="required"/>' ' </xsd:complextype>' ' </xsd:element>' ' </xsd:sequence>' ' </xsd:complextype>' ' <!-- Stock Keeping Unit, a code for identifying products -->' ' <xsd:simpletype name="sku">' ' <xsd:restriction base="xsd:string">' ' <xsd:pattern value="\d{3}-[a-z]{2}"/>' ' </xsd:restriction>' ' </xsd:simpletype>' '</xsd:schema>' ; END; SELECT * FROM user_xml_schemas Úkol 13.5 SELECT t.xo.isschemavalid ('http://cz.ness.com/sample/purchaseorder' is_valid FROM xml_orders t Úkol 13.6 CREATE INDEX xo_zip_ind ON xml_orders ( EXTRACTVALUE(xo, '/n:purchaseorder/shipto/zip', 'xmlns:n="http://cz.ness.com/sample/purchaseorder"' SELECT * FROM xml_orders WHERE EXTRACTVALUE (xo, '/n:purchaseorder/shipto/zip', 'xmlns:n="http://cz.ness.com/sample/purchaseorder"' = '1111'
Cvičení 14. Úkol 14.1 Export, Import exp userid=labxx/labxx@tnsname buffer=1000000 owner=(training file=exp_labxx_schema.dmp log=exp_labxx_schema.log Úkol 14.2 imp userid=labxx/labxx@tnsname file=exp_labxx_schema.dmp tables=(employees
Cvičení 15. Úkol 15.1 SQL*Loader CREATE TABLE employees_it_prog (emp_id NUMBER NOT NULL, emp_name VARCHAR2(60 NOT NULL, hire_date DATE Úkol 15.2 employees_it_prog.ctl: load data infile employees_source_text.txt into table employees_it_prog when job_id = 'IT_PROG' fields terminated by ';' optionally enclosed by '"' (emp_id, emp_name, phone_number FILLER, hire_date DATE "dd.mm.yyyy", job_id FILLER Spuštění SQL*Loaderu: sqlldr userid=labxx/labxx@tnsname control=employees_it_prog.ctl skip=1
Cvičení 16. Zámky Úkol 16.1 INSERT INTO projects (proj_id, proj_desc VALUES (200, 'Locks' a Druhá session zůstane viset příkaz nedoběhne a čeká na uvolnění zámku, který drží první session b Příkaz insert zadaný v druhé session úspěšně doběhne záznam vložený v první session byl zrušen. c Příkaz insert zadaný v první session zůstane nejprve viset. Po potvrzení (commit změn ve druhé session, příkaz zadaný v první session skončí s chybou (Duplicate key in index. Úkol 16.2 SELECT * FROM v$lock WHERE TYPE IN ('TM', 'TX' SELECT * FROM all_objects WHERE object_id IN ( <id1>, <id1>,...
Cvičení 17. Úkol 17.1 Prováděcí plány (zobrazení Otevření a spuštění souboru utlxplan.sql založena tabulka PLAN_TABLE. EXPLAIN PLAN FOR SELECT e.last_name, d.department_name, l.country_id FROM employees e, departments d, locations l WHERE e.department_id = d.department_id AND d.location_id = l.location_id AND d.department_id IN (SELECT department_id FROM employees GROUP BY department_id HAVING COUNT (* <= 4 Spuštění souboru utlxpls.sql (rozšíření délky řádky výstupu set linesize 150 Výstup: ----------------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU Time ----------------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 10 490 8 (25 00:00:01 1 TABLE ACCESS BY INDEX ROWID EMPLOYEES 10 110 1 (0 00:00:01 2 NESTED LOOPS 10 490 8 (25 00:00:01 3 NESTED LOOPS 1 38 7 (29 00:00:01 4 NESTED LOOPS 1 32 6 (34 00:00:01 5 VIEW VW_NSO_1 1 13 4 (25 00:00:01 * 6 FILTER 7 SORT GROUP BY 1 3 4 (25 00:00:01 8 TABLE ACCESS FULL EMPLOYEES 107 321 3 (0 00:00:01 9 TABLE ACCESS BY INDEX ROWID DEPARTMENTS 1 19 1 (0 00:00:01 * 10 INDEX UNIQUE SCAN DEPT_ID_PK 1 0 (0 00:00:01 11 TABLE ACCESS BY INDEX ROWID LOCATIONS 1 6 1 (0 00:00:01 * 12 INDEX UNIQUE SCAN LOC_ID_PK 1 0 (0 00:00:01 * 13 INDEX RANGE SCAN EMP_DEPARTMENT_IX 10 0 (0 00:00:01 ----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id: --------------------------------------------------- 6 - filter(count(*<=4 10 - access("d"."department_id"="$nso_col_1" 12 - access("d"."location_id"="l"."location_id" 13 - access("e"."department_id"="d"."department_id" 27 rows selected. Úkol 17.2 1. První je prováděn plný průchod tabulkou EMPLOYEES (operace 8 107 řádek 2. Záznamy jsou setříděny a groupovány podle DEPARTMENT_ID (operace 7 3. Jsou filtrovány skupiny pro které je COUNT(* <= 4 (operace 6 viz poznámka 4. Tento výsledek je zpracováván v cyklu a jsou podle vybraných DEPARTMENT_ID s využitím indexu DEPT_ID_PK (operace 10, vybírány záznamy z tabulky DEPARTMENTS (operace 11 5. V dalším cyklu jsou vybírány záznamy z indexu LOC_ID_PK podle LOCATION_ID (operace 12 viz poznámka a podle ROWID záznamy z tabulky LOCATIONS (operace 11 6. V dalším cyklu jsou vybírány záznamy z indexu (EMP_DEPARTMENT_IX podle DEPARTMENT_ID (operace 13a následně záznamy z tabulky EMPLOYEES. (operace 1
Cvičení 18. Hinty Úkol 18.1 Plán provádění: --------------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU Time --------------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 106 5088 10 (20 00:00:01 * 1 HASH JOIN 106 5088 10 (20 00:00:01 2 NESTED LOOPS 27 999 6 (17 00:00:01 3 MERGE JOIN 27 675 6 (17 00:00:01 4 TABLE ACCESS BY INDEX ROWID DEPARTMENTS 27 513 2 (0 00:00:01 5 INDEX FULL SCAN DEPT_LOCATION_IX 27 1 (0 00:00:01 * 6 SORT JOIN 23 138 4 (25 00:00:01 7 VIEW index$_join$_003 23 138 3 (0 00:00:01 * 8 HASH JOIN 9 INDEX FAST FULL SCAN LOC_COUNTRY_IX 23 138 1 (0 00:00:01 10 INDEX FAST FULL SCAN LOC_ID_PK 23 138 1 (0 00:00:01 * 11 INDEX UNIQUE SCAN COUNTRY_C_ID_PK 1 12 0 (0 00:00:01 12 TABLE ACCESS FULL EMPLOYEES 107 1177 3 (0 00:00:01 --------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id: --------------------------------------------------- 1 - access("e"."department_id"="d"."department_id" 6 - access("d"."location_id"="l"."location_id" filter("d"."location_id"="l"."location_id" 8 - access(rowid=rowid 11 - access("l"."country_id"="c"."country_id" Položku country_name získá ORACLE v kroku 11. Tabulka COUNTRIES je indexově organizovaná, tj. všechna data tabulky jsou uložena v indexu primárního klíče COUNTRY_C_ID_PK. Úkol 18.2 SELECT /*+ first_rows */... Z prováděcího plánu zmizely operace TABLE ACCESS FULL, MERGE JOIN. Preferované operace jsou NESTED LOOPS
Úkol 18.3 Např. SELECT /*+ no_use_merge(l */... Prováděcí plán: ---------------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU Time ---------------------------------------------------------------------------------------------- 0 SELECT STATEMENT 106 5088 10 (10 00:00:01 * 1 HASH JOIN 106 5088 10 (10 00:00:01 * 2 HASH JOIN 27 999 7 (15 00:00:01 3 NESTED LOOPS 23 414 3 (0 00:00:01 4 VIEW index$_join$_003 23 138 3 (0 00:00:01 * 5 HASH JOIN 6 INDEX FAST FULL SCAN LOC_COUNTRY_IX 23 138 1 (0 00:00:01 7 INDEX FAST FULL SCAN LOC_ID_PK 23 138 1 (0 00:00:01 * 8 INDEX UNIQUE SCAN COUNTRY_C_ID_PK 1 12 0 (0 00:00:01 9 TABLE ACCESS FULL DEPARTMENTS 27 513 3 (0 00:00:01 10 TABLE ACCESS FULL EMPLOYEES 107 1177 3 (0 00:00:01 ---------------------------------------------------------------------------------------------- Predicate Information (identified by operation id: --------------------------------------------------- 1 - access("e"."department_id"="d"."department_id" 2 - access("d"."location_id"="l"."location_id" 5 - access(rowid=rowid 8 - access("l"."country_id"="c"."country_id" Náklady plánu jsou stále 10, %CPU klesla na 10. Přesto pamatujte, že tato čísla jsou velmi orientační! ( Šedivá je teorie, zelený je strom života. Pro odstranění operace MERGE JOIN funguje samozřejmě i SELECT /*+ first_rows */... Celkové náklady na provádění dotazu se jím ale zhorší. Úkol 18.4 Prováděcí plán: ---------------------------------------------------------------------------------------- Id Operation Name Rows Bytes Cost (%CPU Time ---------------------------------------------------------------------------------------- 0 SELECT STATEMENT 106 11978 10 (10 00:00:01 * 1 HASH JOIN 106 11978 10 (10 00:00:01 * 2 HASH JOIN 27 2322 7 (15 00:00:01 3 NESTED LOOPS 23 989 3 (0 00:00:01 4 TABLE ACCESS FULL LOCATIONS 23 391 3 (0 00:00:01 * 5 INDEX UNIQUE SCAN COUNTRY_C_ID_PK 1 26 0 (0 00:00:01 6 TABLE ACCESS FULL DEPARTMENTS 27 1161 3 (0 00:00:01 7 TABLE ACCESS FULL EMPLOYEES 107 2889 3 (0 00:00:01 ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id: --------------------------------------------------- 1 - access("e"."department_id"="d"."department_id" 2 - access("d"."location_id"="l"."location_id" 5 - access("l"."country_id"="c"."country_id" Preferovanou operací se stal HASH_JOIN. Indexové přístupy jsou minimalizovány, protože se vybírají všechna data z tabulek.