SQL röviden (gyakorlati jegyzet) - L. Nagy Éva
Országok listája
Hungary
Debreceni Egyetem
Informatikai Kar
Programtervező informatikus
Adatbázisrendszerek
Jegyzetek
SQL röviden (gyakorlati jegyzet) - L. Nagy Éva
2007.11.28 17:46:12
Az alábbi szöveg egy formázás és képek nélküli előnézete a dokumentumnak. A tökéletes megjelenítéshez jelentkezz be, majd töltsd le a dokumentumot.
SQL röviden
Egy-egy fejezet, alfejezet végén közölt "Haladó:" ismeretek a levelezQ szakos hallgatók számára nem kötelezQ tananyag. A nappalis szakosoknak a **, *** -al jelzett témákat és utasítások szintaxisát nem kell készség szintjén tudni a dolgozatokhoz, azok hasznosak lesznek a Haladó Oracle, Haldó DBMS kurzusoknál vagy az életben a fejlesztQi munka során!
Ezen anyag az Oracle9i SQL nyelvének csak a relációs adatmodellt és elsQsorban az SQL szabványt realizáló részét mutatja be! A példák Oracle9i-ben változtatás nélkül végrehajthatók.
Oracle10g-ben való futtatáshoz a dátum-konstansokban szereplQ JAN, FEB, MÁR, stb. 3 betqs hónapnév-rövidítéseket át kell írni szabályos magyar nyelvq hónapnév-rövidítésekre és a végén még a pontot is ki kell tenni: JAN., FEBR., MÁRC., stb. A DROP TABLE utasításban pedig célszerq használni a PURGE opciót. Néhány Oracle10g kiegészítés leírása megtalálható az SQL_röviden_10g_kieg.doc fájlban.
Az SQL utasítások szintaxisának megadásánál nem törekszünk a teljességre, sok esetben nem adunk meg minden opciót, elQírást. Ezek megtalálhatók az SQL referencia kézikönyvekben. A Backus-Naur Form (BNF) szintaxisban egy szintaktikus egység vesszQvel elválasztott ismételhetQségét a rövidség miatt egyszerqen , & módon jelöljük, nem írva ki elQtte ismételten az opcionálisan ismételhetQ egységet, az alapértelmezésként vett opcionális kulcsszót pedig aláhúzással jelöljük.
Oracle9i Database Online Documentation: Oracle10g Database Online Documentation:
HYPERLINK "http://www.oracle.com/pls/db92/db92.homepage" http://www.oracle.com/pls/db92/homepage http://www.oracle.com/pls/db102/homepage
Books: SQL Reference, SQL*Plus User's Guide and Reference,
Concepts, Application Developer's Guide - Fundamentals.
Szabadon letölthetQ Oracle szoftverek: Oracle11g Database Online Documentation:
HYPERLINK "http://www.oracle.com/technology" http://www.oracle.com/technology HYPERLINK "http://www.oracle.com/pls/db111/homepage" http://www.oracle.com/pls/db111/homepage
Tartalomjegyzék
TOC \o "1-3" 1. Bevezetés PAGEREF _Toc177201863 \h 2
1.1. Alapfogalmak - gyakorlatiasan PAGEREF _Toc177201864 \h 2
1.2. Relációs adatmodell fogalmak PAGEREF _Toc177201865 \h 3
1.3. Mqveletek táblákkal (relációkkal) PAGEREF _Toc177201866 \h 4
1.4. SQL nyelv általános jellemzQi PAGEREF _Toc177201867 \h 5
1.5. Az Oracle PAGEREF _Toc177201868 \h 6
2. SELECT lekérdezQ utasítás PAGEREF _Toc177201869 \h 7
2.1. Egyszerq lekérdezés, rendezés PAGEREF _Toc177201870 \h 8
2.2. Sorok kiválasztása, lekérdezés keresési feltétellel PAGEREF _Toc177201871 \h 9
2.3. Származtatott adatok, SQL sor-függvények PAGEREF _Toc177201872 \h 12
2.4. Csoportok képzése, SQL csoport-függvények PAGEREF _Toc177201873 \h 15
2.5. Táblák összekapcsolása (Join) PAGEREF _Toc177201874 \h 17
2.6. Halmazmqveletek selectek között PAGEREF _Toc177201875 \h 21
2.7. *** Hierarchikus lekérdezés Oracle-ben PAGEREF _Toc177201876 \h 21
2.8. Beágyazott SELECT PAGEREF _Toc177201877 \h 22
3. DDL ( Adatdefiníciós nyelv ) PAGEREF _Toc177201878 \h 27
3.1. Tábla létrehozása, módosítása, törlése, integritási megszorítások PAGEREF _Toc177201879 \h 29
3.2. Nézettábla létrehozása, törlése PAGEREF _Toc177201880 \h 33
3.3. Indexek létrehozása, módosítása, törlése, nagymennyiségq adatok hatékony kezelése PAGEREF _Toc177201881 \h 35
3.4. Szekvencia Oracle-ben PAGEREF _Toc177201882 \h 39
4. DML ( Adatmanipulációs, adatkezelQ nyelv ) PAGEREF _Toc177201883 \h 39
4.1. Adatok lekérdezése - lásd 2. fejezet PAGEREF _Toc177201884 \h 40
4.2. Adatok felvitele PAGEREF _Toc177201885 \h 40
4.3. Adatok módosítása PAGEREF _Toc177201886 \h 41
4.4. Adatok törlése PAGEREF _Toc177201887 \h 43
5. DCL ( AdatvezérlQ nyelv ) PAGEREF _Toc177201888 \h 43
5.1. Tranzakcióvezérlés, konkurens adathozzáférés kezelése PAGEREF _Toc177201889 \h 43
5.2. Felhasználók kezelése, jogosultságaik szabályozása PAGEREF _Toc177201890 \h 47
6. Mellékletek PAGEREF _Toc177201891 \h 49
6.1. Mintafeladat - Oracle9i PAGEREF _Toc177201892 \h 50
6.2. *** Oracle adatbázis-kezelQ rendszer architektúrája, komponensei PAGEREF _Toc177201893 \h 51
Bevezetés
Alapfogalmak - gyakorlatiasan
Adatbázis (DB Database): egy olyan adathalmaz, amely a tényleges adatokon kívül a köztük lévQ kapcsolatokat és a rájuk vonatkozó információkat is tárolja.
Tényleges adatok: az adatbázisban nyilvántartott felhasználói adatok az üzleti, információs kívánalmaknak megfelelQen.
Adatszótár adatok (DD Data Dictionary): az adatbázis logikai szerkezetére és az adatok kezelésére vonatkozó adatok (adatok az adatokról, meta adatok), valamint a felhasználókra és a rendszer mqködtetésére vonatkozó rendszeradatok.
Adatbázis-kezelQ rendszer (DBMS Database Management System): olyan szoftver, amely az adatbázis kezelését végzi. Legfontosabb alapfeladatai:
Adatbázis és az adatbázis szerkezeti elemeinek definiálása, módosítása.
Adatok karbantartása: bevitele, módosítása, törlése.
Adatok visszakeresése: lekérdezése.
Adatbázis konzisztencia biztosítása az integritási megszorítások (szabályok) betartása révén.
Nagymennyiségq adatok hatékony kezelése: minél kisebb válaszidQ, minél kevesebb tárhely.
Konkurens adathozzáférés kezelése többfelhasználós rendszerekben, tranzakcióvezérlés.
Adatvédelem, adatbiztonság megoldása: rendszer- és adatvédelem.
Haladó: Minden DBMS-t gyártó cég igyekszik megfelelni a mai hálózatos, internetes, multimédiás, mobilos számítástechnika kihívásainak, a piaci elvárások újabb és újabb technológiai megoldásokat kényszerítenek ki, így folyamatosan bQvül a DBMS funkcionalitása:
Osztott adatbázisok kezelése.
Adatbázis-programozás: DB-ben tárolt programegységek, triggerek.
Objektumorientált eszközrendszer használata.
Internetes és mobil eszközökrQl igénybe vehetQ szolgáltatások támogatása.
Multimédiás adatok kezelése, adattárházak kialakítása, adatbányászat, térinformatika, stb.
Adatbázis-séma: az adatbázis alapjául szolgáló logikai szerkezeti elemek és szabályok leírása, annak érdekében, hogy egységesen kezelhetQ legyen egy szabványos adatbázisnyelvvel. Ezt különbözQ elvi alapokon lehet megtenni: Hierarchikus adatmodell, Hálós adatmodell, Relációs adatmodell, Objektumorientált adatmodell. A relációs adatmodellt elméletileg E. F. Codd alapozta meg 1970-ben.
Relációs adatbázis-kezelQ rendszer (RDBMS Relational Database Management System) a relációs adatmodell szabályai szerint felépített relációs adatbázist (RDB Relational Database) kezel. Legelterjedtebb!
SQL nyelv (Structured Query Language) - strukturált lekérdezQ nyelv, az RDBMS-ek szabványosított adatbázisnyelve. A nevénél sokkal többre képes!
Objektumrelációs adatbázis (ORDB Object Relational Database) és az ezt kezelQ ORDBMS rendszer a relációs adatmodell objektumorientált kiterjesztésén alapszik, a relációs és az objektumorientált technológia egyesítése.
Információs rendszer tervezése: egy információs rendszer funkcióit, tranzakcióit és adatbázisát elQször meg kell tervezni. A tervezési fázisok során különbözQ absztrakciós szintq modelleket (ER (Entity-Relationship), ODL (Object Definition Language), UML (Unified Modelling Language), stb) használva juthatunk el a végsQ, a konkrét DBMS által használt adatmodellbeli sémához: például a normalizált relációs adatbázis-sémához. A megtervezett rendszert implementálni kell, majd a cég(ek)nél bevezetni és üzemeltetni kell. Él a rendszer!
Adatbázisrendszer (DBS Database System) egymásra épülQ összetevQi (DBS=DBMS+DB+...+Felhasználók)
Hardver: az informatikai infrastruktúra alapját képezi (számítógép, hálózat, tárolók, kommunikációs berendezések, stb.)
Operációs rendszer és egyéb alapszoftverek: mqködtetik az informatikai hardvert.
DBMS: adatbázis-kezelQ rendszer, az adott informatikai platformon installált szoftver. Az adathordozókon tárolt adatbázist az operációs rendszer szolgáltatásain keresztül tudja kezelni.
Adatbázis alkalmazások, eszközök: speciális felhasználói, fejlesztQi igényeket elégítenek ki. Lehetnek a szerver gépen és/vagy a kliens gépen. Csak a DBMS-en keresztül tudják elérni a DB-t.
Rendszergazda (DBA Database Administrator): felügyeli az egész rendszer mqködését, munkáját speciális eszközök segítik. Feladatai: DBMS installálása, felhasználók felvétele, jogosultságaik kiosztása; a rendszer mqködésének figyelése, hangolása; gazdálkodás az erQforrásokkal; rendszerhibák kiküszöbölése, biztonsági mentések, helyreállítások; stb. Munkájához ismerni kell a konkrét DBMS és operációs rendszer architektúráját, mqködését.
Felhasználók: a DBA veszi fel a felhasználókat és szabályozza, hogy ki mit csinálhat a rendszerben, milyen adatokhoz férhet hozzá. Értük van az egész! A fejlesztQk speciális felhasználók.
Osztott adatbázisok (Distributed Database): több DB Szerver van (DBMS + DB), melyek hálózaton keresztül együttmqködnek. Az alkalmazás és a felhasználók számára ezek egy logikai egységet képeznek.
Relációs adatmodell fogalmak
Egy relációs adatbázis (RDB) kétdimenziós táblák (relációk) gyqjteménye, amelyben az adatok teljesítik az integritási megszorításokat. Az adatbázis sémáját (táblákat és az integritási szabályokat) a táblák adatokkal való feltöltése elQtt kell definiálni. Lásd mintafeladat! Fogalmak megfeleltetése:
Relációs adatbázis kezelQ rendszer (RDBMS):
(SQL nyelv) Relációs adatmodell elmélet: (Relációs algebra,
Reláció kalkulus) Megjegyzés Tábla (Table) reláció Névvel van azonosítva. Mindennemq tárolás alapja a tábla. Oszlop (Column) attribútum, tulajdonság Névvel van azonosítva. Egy oszlop azonos típusú adatokat tartalmaz. Oszlop típusát meg kell adni: numerikus, karakteres, dátum, stb. Sor / rekord (Row) Rekord (tuple), elQfordulás Összetartozó oszlopértékeket tartalmaz. MezQ értéke (Value) attribútum érték
NULL érték: Amíg egy mezQnek nincs definiált értéke (mert még ismeretlen vagy nincs is jelentése az adott helyzetben), addig NULL értékként kezeli az adatbázis-kezelQ, ami nem tekinthetQ sem nullának, sem más értéknek. Kezelése külön gond!
Integritási megszorítások (Constraint): Szabályok, melyek biztosítják az adatbázis konzisztenciáját (használható legyen az adatbázis, logikai ellentmondásokat ne tartalmazzon). Az elQírt szabályok betartását az RDBMS automatikusan biztosítja: nem enged meg olyan adatbázis mqveleteket, amelyek révén az adatok a szabályokat megszegnék. (Ezek SQL nyelvbeli implementálásához lásd a mintafeladatot!)
Oszlop megszorítás: értékeinek meg kell felelni az oszlop elQírt adattípusának és az értéktartományba kell esni. Oszlop kitöltési kötelezQség elQírható (NOT NULL).
ElsQdleges kulcs (Primary Key): olyan oszlop(ok) alkotják, amelyben szereplQ értékek a tábla sorait egyértelmqen azonosítják. Egy vagy több oszlop alkothatja. Értékének (több oszlop esetén azok összevont értékének) egyedinek kell lenni. (KülönbözQ sorokban lévQ kulcsértékek különbözQek.) Nem lehet NULL értékq, összetett kulcs esetén egyetlen része sem. Egy táblának csak egy elsQdleges kulcsa lehet.
Egyedi kulcs (Unique Key): Egy vagy több oszlop alkothatja. Értékének (több oszlop esetén azok összevont értékének) egyedinek kell lenni. Lehet NULL értékq, összetett kulcs esetén bármelyik része. Egy táblának több egyedi kulcsa lehet.
KülsQ (idegen) kulcs (Foreign Key) vagy hivatkozási (References) megszorítás: olyan oszlop(ok) alkotják, melyek egy másik táblával való logikai kapcsolatot valósítják meg. Ezen oszlop(ok) értéke adja meg, hogy az adott tábla (gyerek tábla) egy sora, a másik tábla (szülQ tábla) mely sorához tartozik. Egy vagy több oszlop alkothatja. A külsQ kulcs a gyerek táblában van és hivatkozik (References) a szülQ tábla elsQdleges vagy egyedi kulcsára. A hivatkozott szülQ tábla általában egy másik tábla, de lehet ugyanaz. A külsQ kulcs értéke csak létezQ szülQ kulcs értékre hivatkozhat, vagy NULL értékq lehet. A szülQ tábla olyan sora nem törölhetQ és olyan sorának kulcs értéke nem módosítható, melyre hivatkoznak gyerek sorok a gyerek táblában.
Egyéb megszorítások: az üzleti elvárásoknak megfelelQen elQírhatunk más ellenQrzéseket (Check) is.
Mqveletek táblákkal (relációkkal)
Táblákat mint a sorok (rekordok) halmazát (pontosabban multihalmazát) tekintsük. A kiinduló táblá(k)ból mqveletekkel új táblát, eredménytáblát tudunk létrehozni.
mqvelet =>
Projekció: oszlopok kiválasztása. Az eredménytáblába csak a megadott oszlopokhoz tartozó értékek kerülnek át (pl. C, A).
SELECT C, A FROM T1;
( * a tábla összes oszlopát jelöli: SELECT * FROM T1;)
Szelekció: sorok kiválasztása. Az eredménytáblába csak a szelekciós feltételnek eleget tevQ sorok kerülnek át (pl. A <> 4).
SELECT * FROM T1 WHERE A <> 4;
Táblák összekapcsolása (Join mqveletek):
- Táblák szorzása (Descartes szorzat, Cross Join): Az egyik tábla minden sorát az összes lehetséges módon összekapcsoljuk (folytatjuk) a másik tábla minden sorával. Oszlopok száma: összeadódik. Sorok száma: összeszorzódik.
SELECT * FROM T1 CROSS JOIN T2;
- Táblák osztása: nincs realizálva az SQL szabványban és a legtöbb rendszerben.
A többi összekapcsolás a táblák oszlopaira elQírt kapcsolófeltétel alapján jön létre. Szokásos elnevezések: Equijoin: egyen-összekapcsolás, a kapcsolóoszlopok értékegyenlQségén alapszik (pl. T1.A = T2.A ).
Nem Equijoin: nem egyen-összekapcsolás, a kapcsolóoszlopok egyenlQségtQl eltérQ relációján alapszik (pl. T1.A < T2.A ). (Lásd még elmélet Theta Join.)
- BelsQ összekapcsolás (Inner Join): A Descartes szorzással kapott halmaz egy részhalmaza. Az egyik tábla sorait a másik tábla csak azon soraival kapcsoljuk össze, amelyek a kapcsolófeltételnek eleget tesznek.
Kapcsolófeltétel (equijoin) legyen: T1.A = T2.A
SELECT * FROM T1 INNER JOIN T2 ON T1.A = T2.A;
Kapcsolófeltétel (nem equijoin) legyen: T1.A < T2.A
SELECT * FROM T1 INNER JOIN T2 ON T1.A < T2.A;
- KülsQ összekapcsolás (Outer Join): Nemcsak a kapcsolófeltételnek eleget tevQ sorokat adja vissza, hanem az egyik tábla olyan sorait is, amelyekhez nincs a kapcsolófeltétel alapján kapcsolódó sor a másik táblában (tehát az egyik tábla összes sora szerepel az eredményben). Ezen sorokat a belsQ join nem adná vissza. Ekkor az egyik táblából származó páratlan sorokat csupa NULL értékeket tartalmazó "üres" sorral egészíti ki. ElQ kell írni, hogy az Outer Join operátor bal (Left) vagy a jobb (Right) oldalán álló tábla összes sora legyen megtartva, de kérhetQ a kétoldali, teljes (Full) külsQ összekapcsolás is. A külsQ joinok is lehetnek equi vagy nem equijoinok!
SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.A = T2.A;
SELECT * FROM T1 RIGHT OUTER JOIN T2 ON T1.A = T2.A;
SELECT * FROM T1 FULL OUTER JOIN T2 ON T1.A = T2.A;
- Természetes összekapcsolás (Natural Join): Nem kell megadni kapcsolófeltételt. Az összekapcsolási feltétel a táblák azonos nevq oszlopainak értékegyenlQségén (equijoin) automatikusn létrejön (T1.A = T2.A). Az eredménytáblában az azonos nevq oszlop(ok) csak egyszer szerepel(nek). A természetes összekapcsolásra is elQírható a külsQ join.
SELECT * FROM T1 NATURAL JOIN T2;
Halmazmqveletek:
A tábláknak azonos számú és típuskompatíbilis oszlopokat kell tartalmazni, azaz unió kompatíbiliseknek kell lenni. Oracle-ben az eredménytábla oszlopainak nevét az elsQ tábla szolgáltatja.
UNION - Egyesítés eredménye: minden olyan sor, amely legalább az egyik táblában elQfordul, sor duplikáció nincs.
UNION ALL - Egyesítés eredménye: a táblákban elQforduló összes sor. Sor duplikációt megenged. (Csak ez!)
INTERSECT - Metszet eredménye: mindkét táblában elQforduló közös sorok.
MINUS - Kivonás eredménye: az elsQ táblából elhagyjuk a második táblában elQforduló sorokat.
halmazmqvelet =>
SELECT * FROM T3 UNION SELECT * FROM T4;
SELECT * FROM T3 UNION ALL SELECT * FROM T4;
SELECT * FROM T3 INTERSECT SELECT * FROM T4;
SELECT * FROM T3 MINUS SELECT * FROM T4;
Eredménytáblák:
SQL nyelv általános jellemzQi
Az SQL nyelv a relációs adatbázis-kezelQ rendszerek (pl. Oracle, MS SQL Server, INGRES, INFORMIX, DB2, SYBASE, NOVELL XQL, PROGRESS, stb.) szabványos adatbázis nyelve. A relációs adatmodell szabályai szerint felépített adatbázisok kezelésére szolgál.
JellemzQi:
Nem algoritmikus: Deklaratív jellegq, azaz lényegében azt fogalmazhatjuk meg vele, hogy mit akarunk csinálni, a hogyant azaz a feladat megoldási algoritmusát nem kell a felhasználónak megadni. Nincsenek benne az algoritmikus nyelvekben megszokott utasítások (ciklusok, feltételes elágazások, I/O utasítások).
Teljes nyelv - adat függetlenség:
Fizikai függetlenségi szint: megváltoztatható az adatbázis belsQ fizikai tárolási és ábrázolási módja anélkül, hogy módosítani kellene az adatok relációs modellbeli sémáját és az SQL utasításokat. A fizikai szint ismerete nélkül is lehet dolgozni SQL-ben. Ez a platformfüggetlenség teszi lehetQvé az adatbázis és az alkalmazások "hordozhatóságát".
Logikai függetlenségi szint: megváltoztatható (korlátozott mértékben) az adatok relációs modellbeli sémája (pl. új oszlopok, integritási megszorítások, indexek felvétele egy táblához) anélkül, hogy módosítani kellene a meglévQ SQL utasításokat. Egy mqködQ információs rendszernél a séma kisebb változtatására szükség lehet az üzemeltetési évek során.
Halmazorientált: Táblákat mint a sorok (rekordok) halmazát (pontosabban multihalmazát) tekintjük. Az utasításban megfogalmazott feltételnek eleget tevQ összes sor részt vesz a mqveletben.
Szabványos: Illeszkedik az ANSI SQL szabványhoz: SQL89 (SQL1), SQL92 (SQL2), SQL99 (SQL3 - ez már az objektumrelációs alapelveket is magába foglalja). Egy szabványnak kötelezQ, ajánlott, szabadon választott részei vannak. A szabványban van egy SQL utasításcsoport, amelyet minden implementációnak kötelezQ megvalósítani, de mindegyik implementáció plusz lehetQséget is nyújthat, azaz felülrQl kompatibilis a szabvánnyal.
Ezen anyag az Oracle9i SQL nyelvének csak a relációs adatmodellt és elsQsorban az SQL szabványt realizáló részét mutatja be!
Fontosabb használati módjai:
Önállóan fejlesztQ eszközökben. Pl: SQL*Plus, iSQL*Plus, Oracle*Developer (Form, Report készítQ).
Beágyazva procedurális programozási nyelvekbe. Például: C/C++, ADA, PASCAL, FORTRAN, COBOL befogadó gazdanyelvekbe, melyeket elQször elQfordítóval (precompiler) kell lefordítani.
PL/SQL (az Oracle saját procedurális nyelve, az SQL nyelv procedurális kiterjesztése) és Java nyelvekben. Ezen nyelvekben írt programegységek tárolhatók és futtathatók az Oracle adatbázis szerveren.
SQL nyelv utasításainak fQbb csoportjai (résznyelvek):
DDL Adatdefiníciós nyelv (Data Definition Language).
Adatbázis és az adatbázis szerkezeti elemek kialakítása, kezelése:
CREATE, ALTER, DROP, RENAME, (Oracle: TRUNCATE)
DML Adatmanipulációs nyelv (Data Manipulation Language).
Adatok karbantartása (bevitele, módosítása, törlése), lekérdezése:
INSERT, UPDATE, DELETE, SELECT, (Oracle: MERGE)
Megj: a SELECT utasítást korábban szokás volt önálló DQL (Data Query Language)
lekérdezQ résznyelvnek is nevezni.
DCL AdatvezérlQ nyelv (Data Control Language).
Tranzakcióvezérlés, zárolások: COMMIT, ROLLBACK, SAVEPOINT, LOCK
Adatvédelem, felhasználói hozzáférés szabályozása: GRANT, REVOKE
Egyéb nem szabványosított utasítások, eszközök: Tárolási elQírások, mqködési körülmények beállítása, adatbázis mentése, visszatöltése, helyreállítása, exportja, importja, stb.
Nyelv elemei: karakterkészlet (jelkészlet), kulcsszavak, elválasztó jelek, azonosítók, konstansok (literálok), függvények, mqveleti jelek (operátorok), kifejezések, utasítások.
Lexikális konvenciók: az SQL utasítások írhatók kis- és nagybetqvel, egy vagy több sorba. Az SQL utasítás végét az eszközökben általában a ; (pontosvesszQ) jelzi, de a ; nem része az SQL utasításnak, csak az utasítás végrehajtását váltja ki.
Megjegyzések (comment) elhelyezése:
/* több soron áthúzódható megjegyzés */
-- sor végéig tartó megjegyzés
Az Oracle
Az Oracle cég relációs adatbázis-kezelQ rendszere a világon és Magyarországon is az egyik legelterjedtebb. 1979-tQl van a piacon, DBMS termékeinek verziói az ..., Oracle7, Oracle8i, Oracle9i, Oracle10g nevet viselik. A legutóbbi három verzió mindegyike objektumrelációs, internetes és osztott adatbázis-kezelés lehetQségekkel is rendelkezik. A legújabb Oracle10g, pedig az Oracle DB-szerverek "Grid Computing" hálózati architektúrába szervezett együttesének dinamikus együttmqködését teszi lehetQvé: képes egyesíteni a különbözQ számítógép-kapacitásokat, integrálható az adat- és az alkalmazáshasználat. Az Oracle cég a DBMS mellett még tervezQ- és fejlesztQeszközöket, valamint "kulcsrakész" alkalmazásokat is készít.
SQL*Plus és iSQL*Plus fejlesztQ eszközök
Az SQL*Plus karakteres, parancssoros felületet, az iSQL*Plus pedig grafikus, internetes felhasználói felületet biztosít az Oracle DB-szerverrel való munkához. A megadott SQL parancsokat továbbítják az Oracle DB-szerverhez végrehajtásra, majd a szervertQl visszakapott eredményt formázva megjelenítik.
Háromféle parancsot fogadnak el interaktívan vagy parancsfájlból (SQL szkript fájl, kiterjesztése .sql):
SQL*Plus, iSQL*Plus saját, eszközspecifikus parancsait. Ezek nem lesznek továbbítva a DB-szervernek és nem lesznek tárolva az eszköz úgynevezett SQL pufferében. Csak néhány SQL*Plus eszközspecifikus parancs nem adható ki iSQL*Plus-ban.
SQL parancsokat (utasításokat), az utolsót az SQL pufferben tárolja.
PL/SQL névnélküli blokkokat (programok), az utolsót az SQL pufferben tárolja.
SQL*Plus: Kétrétegq kliens/szerver architektúra. Elosztott feldolgozás (Distributed Processing).
iSQL*Plus: Internetes alkalmazás. Nem kell a kliensen installálni Oracle eszközt, egy Web-böngészQbQl az URL cím megadásával indíthatjuk az alkalmazást. Háromrétegq alkalmazás-szerveres architektúra.
Néhány SQL*Plus, iSQL*Plus parancs:
A parancsok rövidíthetQk és kis-, nagybetq mindegy, nem fontos ; -vel zárni. Az eszközökben sok parancs elérhetQ menübQl (SQL*Plus) vagy kezelQgombbal (iSQL*Plus).
DESC[RIBE] objektum -- adatbázisbeli objektum definíciójának lekérdezése.
L[IST] -- kilistázza az SQL puffer tartalmát.
/ vagy: R[UN] -- SQL puffer tartalmát végrehajtja.
SET változó érték -- az eszköz környezeti (rendszer-) változóinak beállítása, pl.
SET PAUSE {ON | OFF} vagy SET PAGESIZE {24 | n} vagy SET ECHO {ON | OFF}
SHOW {ALL | változó} -- a környezeti változó(k) értékének lekérdezése.
@url_cím vagy: STA[RT] url_cím -- parancsfájl végrehajtása.
@fájlnév[.kit] vagy: STA[RT] fájlnév[.kit] -- parancsfájl végrehajtása, csak SQL*Plus-ban!
REM[ARK] megjegyzés -- sor végéig tartó megjegyzés a parancsfájlban
EXIT -- kilépés az eszközbQl.
SELECT lekérdezQ utasítás
Egy vagy több tábla vagy nézettábla tartalmát kérdezhetjük le, de használhatjuk beépítve más SQL utasításban is (alselect). Megvalósíthatók vele a korábban megadott tábla (reláció) mqveletek.
Legáltalánosabb formája a következQ:
SELECT ... oszlopok kiválasztása (projekció) (6)
FROM ... táblák megadása, összekapcsolása (join) (1)
[WHERE ... ] sorok kiválasztása (szelekció) (3)
[[START WITH ...] CONNECT BY ...] hierarchia felépítése (2)
[GROUP BY ... ] sorok csoportosítása (4)
[HAVING ... ] csoportok közül válogatás (5)
[{UNION | UNION ALL | INTERSECT | MINUS} select_utasítás ] ...
halmazmqveletek (7)
[ORDER BY ... ] eredménysorok rendezése (8)
[FOR UPDATE & ] kiválasztott sorok zárolása (9)
Az utasításrészek (záradékok) megadási sorrendje kötött. A kiértékelést a ()-ben megadott sorrendben kell követni. Egy konkrét adatbázis-kezelQ a saját optimalizációs módszere szerint tervezi meg az utasítások végrehajtásának menetét, ami ettQl a sorrendtQl eltérhet, de az eredmény ugyanaz. Az utasítás általános alakja elég bonyolult, így csak fokozatosan adjuk meg a részletesebb szintaktikát és szemantikát.
Egyszerq lekérdezés, rendezés
SELECT [ ALL | DISTINCT | UNIQUE ] { [ tábla.]* | sql_kifejezés [ [AS] o_aliasnév] } ,...
FROM tábla1 [t_aliasnév1 ] [join_tábla2]...
[ORDER BY {sql_kifejezés | o_aliasnév [ASC | DESC] } ,... ];
A FROM záradékban adjuk meg, hogy mely táblákból akarunk adatokat lekérdezni, a SELECT után pedig, hogy mely oszlopok, vagy milyen számított értékeket alkossák az eredménytáblát. Az opcionális ORDER BY részben az eredménysorok rendezését írhatjuk elQ. Ha nincs elQírva rendezés a DBMS nem garantál semmilyen sorrendet az eredménytábla soraira. Viszont, ha az utasítás végrehajtásához implicit rendezést alkalmaz, akkor az eredménysorokat is rendezve kaphatjuk vissza.
ALL Alapértelmezés: az összes sort visszaadja.
DISTINCT vagy UNIQUE: Csak az egymástól különbözQ sorokat adja vissza. A sorduplikáció megszüntetését implicit rendezéssel oldja meg a rendszer.
* A tábla összes oszlopát jelenti.
o_aliasnév A lekérdezés eredménytáblájában oszlopnévként nem az oszlop vagy sql_kifejezés valódi neve, hanem az o_aliasnév jelenik meg. Csak az ORDER BY záradékban használható még.
Használható az "o_aliasnév" alak is a többszavas neveknél és a kis- nagybetqs jelölés megtartására.
t_aliasnév A tábla másodlagos, rövid neve. Bárhol az utasításban használható a táblanév helyett. Az o_aliasnév és a t_aliasnév csak az adott utasítás belsejében érvényes.
sql_kifejezés az SQL nyelv szabályai szerint összeállított kifejezés. Legegyszerqbb esetben egy oszlop neve, de állhat itt oszlopnevek, konstansok (literálok) és függvényhívások összekapcsolva aritmetikai operátorokkal ( *, /, +, - ) vagy a konkatenáló karakteres operátorral ( || ), zárójelezés is megengedett.
konstans vagy literál. Adattípusa lehet: numerikus, karakteres, dátum. A karakteres típus megkülönbözteti a kis- és nagybetqt. Pl: 1234.56, 25E-3, 'TetszQleges Karaktersor'
Dátum konstans (ami valójában egy karakteres konstans) formátuma függ a munkamenet (Session) alapértelmezett dátumformátumától és nyelvétQl:
Pl. 'DD-MON-YY', 'YY-MON-DD', 'RR-MON-DD', 'RR-MM-DD'
Ez a dokumentum az Oracle munkamenet alapértelmezett beállításait használja: a magyar nyelvet és az intelligensen kerekítQ 'RR-MON-DD' dátumformátumot!
Oracle9i dátumok: '74-MÁR-21', '1974- MÁR-21', '04- MÁR-21', '2004- MÁR-21'
Oracle10g dátumok: '74-MÁRC.-21', '1974- MÁRC.-21', '04- MÁRC.-21', '2004- MÁRC.-21'
Megj: A munkamenet alapértelmezett beállításai egy DD tábla alapján megtekinthetQ:
SELECT * FROM nls_session_parameters;
függvény KésQbb ismertetjük.
oszlopnév [tábla.]oszlopnév vagy [t_aliasnév.]oszlopnév
MinQsített név kell, ha egy oszlopnév az utasítás több táblájában is elQfordul.
-- Összes alkalmazott összes adata:
SELECT * FROM alkalmazott;
-- Összes alkalmazott néhány adata:
SELECT a_nev, beosztas, fizetes FROM alkalmazott;
-- Összes telephely összes adata 2 oszlopban
-- T_KOD oszlop legyen összefqzve T_NEV-el, közte 4 kötQjellel.
SELECT t_kod || '----' || t_nev AS telep, varos FROM telephely;
-- KülönbözQ BEOSZTAS-ok lekérdezése:
SELECT DISTINCT beosztas FROM alkalmazott;
-- KülönbözQ T_KOD, BEOSZTAS párok lekérdezése:
SELECT DISTINCT t_kod, beosztas FROM alkalmazott;
-- Tábla aliasnév jól használható a hosszú táblanevek rövidítésére.
-- A telephely és az alkalmazott táblák belsQ joinja.
-- Jelenleg csak formailag nézzük: ugyanazon utasítás van kétféleképpen leírva:
SELECT a_kod, a_nev, telephely.t_kod, t_nev, varos
FROM alkalmazott INNER JOIN telephely ON alkalmazott.t_kod= telephely.t_kod;
SELECT a_kod, a_nev, T.*
FROM alkalmazott A INNER JOIN telephely T ON A.t_kod=T.t_kod;
NULL érték: Olyan érték, amely nem ismert, nincs megadva vagy nem értelmezhetQ. Nem tekinthetQ sem nullának, sem más értéknek. Bármelyik típusú oszlop tartalmazhat NULL értéket, amelyre nem írtuk elQ a NOT NULL vagy PRIMARY KEY megszorítást. Az utasításokban több helyen szerepelhet a NULL kulcsszó.
NULL érték kezelése: Nem célszerq számolni vele: ha egy kifejezésben szerepel NULL operandus, akkor definiálatlan (NULL) lesz a kifejezés eredménye, vagy ha egy függvény argumentuma NULL, akkor a függvény értéke is az lesz. Kivétel a konkatenáló kifejezés és függvény. A legtöbb csoportfüggvény pedig egyszerqen kihagyja a NULL értékeket. Az NVL függvényt kell használnunk ahhoz, hogy átmenetileg konvertáljunk egy NULL értékq oszlop vagy kifejezés értékét egy kezelhetQ értékké:
NVL(sql_kifejezés, helyettesítQ_sql_kifejezés)
A függvény eredménye azonos az elsQ argumentum által meghatározott értékkel, ha az nem NULL, különben a második argumentum értékét adja vissza. Minden típusra alkalmazható.
-- Összes alkalmazott neve konkatenálva a belépés dátumával, fizetése, prémiuma
-- és a fizetés, prémium összege. Nézzük meg a NULL értékkel való mqveletek eredményét!
SELECT a_nev || '---' || belepes AS "Név és Belépés", fizetes, premium,
fizetes + premium AS rossz_jövedelem, fizetes + NVL(premium, 0) AS jó_jövedelem
FROM alkalmazott;
Eredménysorok rendezése (ORDER BY záradék):
ElQírhatjuk, hogy az eredménytábla sorai mely sql_kifejezés értékei szerint legyenek rendezve elsQdlegesen, mely szerint másodlagosan, stb. Egy-egy megadott rendezési szempont alapértelmezésben növekvQ (ASC), DESC hatására csökkenQ lesz a sorrend. A rendezés értelmezve van minden adattípusnál. A NULL érték Oracle-ben igen nagy értéket képvisel.
-- Összes alkalmazott néhány adata T_KOD szerint növekvQleg rendezve:
SELECT t_kod, a_nev, beosztas FROM alkalmazott
ORDER BY t_kod;
-- Összes alkalmazott néhány adata T_KOD szerint csökkenQleg,
-- azon belül pedig A_NEV szerint növekvQleg rendezve:
SELECT t_kod, a_nev, beosztas FROM alkalmazott
ORDER BY t_kod DESC, a_nev;
-- Rendezés oszop aliasnév használatával
SELECT t_kod, a_nev, fizetes+NVL(premium, 0) jövedelem FROM alkalmazott
ORDER BY jövedelem;
-- NULL értéket tartalmazó oszlopok szerinti rendezés:
SELECT a_nev, premium, belepes FROM alkalmazott
ORDER BY premium, belepes DESC;
*** Haladó: az opcionális ASC vagy DESC után a NULLS FIRST vagy NULLS LAST kulcsszavakkal explicit módon elQírható, hogy a NULL értékek elsQként vagy utolsóként jelenjenek meg.
-- NULL értéket tartalmazó oszlopok szerinti rendezés:
SELECT a_nev, premium, belepes FROM alkalmazott
ORDER BY premium NULLS FIRST, belepes DESC NULLS LAST;
Sorok kiválasztása, lekérdezés keresési feltétellel
SELECT ...
FROM ...
[WHERE feltétel]
& ;
Az opcionális WHERE záradékkal a tábla sorai közül válogathatunk, ha nincs WHERE rész, akkor az összes sor részt vesz a további mqveletekben vagy az eredménytáblában.
A feltétel egy SQL nyelv szabályai szerint összeállított logikai kifejezés: csak azok a sorok vesznek részt a további mqveletekben vagy az eredménytáblában amelyekre a feltétel értéke igaz (True), amelyekre a feltétel értéke hamis (False) vagy ismeretlen (Unknown), azok nem!
A feltételben SQL kifejezéseket értékelünk ki klasszikus relációs operátorok, speciális SQL hasonlító operátorok segítségével, a klasszikus logikai operátorokkal pedig összetett logikai kifejezések állíthatók össze. Mindegyik adattípus szerepelhet a hasonlító feltételekben, de ha az egyik operandus NULL értékq, akkor a legtöbb esetben az eredmény ismeretlen (Unknown) lesz, kivétel az IS [NOT] NULL null-érték vizsgáló operátor.
SQL-ben nincs logikai adattípus, logikai konstans, de valójában egy háromértékq (True, False, Unknown) logikát használ. A rendszerekben általában különbözik az sql_kifejezés NULL értéke és a feltétel (logikai kifejezés) ismeretlen (Unknown) értéke.
Egyszerq feltételek tipikus formái:
sql_kifejezés relációs_operátor {sql_kifejezés | (skalár_értéket_adó_alselect)}
Kifejezések értékének összehasonlítása.
relációs_operátor (théta operátor): =, !=, <>, <, >, <=, >=
skalár_értéket_adó_alselect: pontosan egy sort és abból is egy oszlopot ad vissza, azaz egy skalár érték lesz az eredmény. Ha nincs visszaadott sor, akkor értéke NULL. Példákat lásd a Beágyazott SELECT fejezetben.
sql_kifejezés [NOT] BETWEEN sql_kif1 AND sql_kif2
kif1 és kif2 közé esés (zárt intervallum: kif1 <= sql_kifejezés <= kif2).
sql_kifejezés [NOT] LIKE 'karakterminta'
Karaktermintára való illeszkedés. Dzsóker karakterek:
% tetszQleges hosszú karaktersorra illeszkedés az adott pozíciótól
_ tetszQleges karakterre illeszkedés az adott pozícióban
sql_kifejezés IS [NOT] NULL
NULL értékkel való egyezés vizsgálat. True vagy False az eredmény.
(sql_kifejezés = NULL eredménye mindig Unknown.)
-- Azon alkalmazottak néhány adata akikre teljesül a WHERE feltétel:
-- beosztása ELADO
SELECT a_kod, a_nev, beosztas FROM alkalmazott
WHERE beosztas = 'ELADO';
-- egy adott dátum után léptek be
SELECT a_kod, a_nev, belepes FROM alkalmazott
WHERE belepes > '01-JAN-01';
-- jövedelme nagyobb egy értéknél
SELECT a_kod, a_nev, fizetes+NVL(premium, 0) jövedelem FROM alkalmazott
WHERE fizetes+NVL(premium, 0) > 200000;
-- fizetésére teljesül a 90000<=fizetés<=110000 feltétel
SELECT a_kod, a_nev, fizetes, premium FROM alkalmazott
WHERE fizetes BETWEEN 90000 AND 110000;
-- a neve K betqvel kezdQdik.
SELECT a_kod, a_nev, fizetes, premium FROM alkalmazott
WHERE a_nev LIKE 'K%';
-- a nevének 2. betqje: a
SELECT a_kod, a_nev, fizetes, premium FROM alkalmazott
WHERE a_nev LIKE '_a%';
-- június hónapban léptek be a vállalathoz:
SELECT a_kod, a_nev, belepes FROM alkalmazott
WHERE belepes LIKE '%JÚN%';
-- a prémium értéke definiálatlan (NULL)
SELECT a_kod, a_nev, fizetes, premium FROM alkalmazott
WHERE premium IS NULL;
-- helytelen: nem ad vissza egyetlen sort sem, feltétel értéke mindig Unknown
SELECT a_kod, a_nev, fizetes, premium FROM alkalmazott
WHERE premium = NULL;
"Halmazos" feltételek tipikus formái:
"Halmaz" lehet:
(sql_kifejezés ,...) -- Kifejezéslista, mely leggyakrabban konstanslista.
(alselect) -- Több sort és abból egy vagy több oszlopot is visszaadhat,
vagy egyetlen sort sem ad vissza.
Példákat lásd a Beágyazott SELECT fejezetben.
[NOT] EXISTS (alselect)
Az alselect visszaad-e legalább egy sort? True vagy False az eredmény.
sql_kifejezés [NOT] IN (halmaz)
A megadott halmazban szerepel-e az sql_kifejezés értéke? ElQfordulás vizsgálat.
sql_kifejezés relációs_operátor {ANY | SOME} (halmaz)
Teljesül-e a reláció a halmaz valamely (legalább egy) elemére?
( =ANY azonos az IN relációval, ANY és SOME azonos (ANY a ( logikai kvantor))
sql_kifejezés relációs_operátor ALL (halmaz)
Teljesül-e a reláció a halmaz minden egyes (összes) elemére?
( <>ALL azonos a NOT IN relációval (ALL a ( logikai kvantor))
(sql_kifejezés ,...) egyezés_vizsgáló_operátor (halmaz)
Egyezik (nem egyezik) a kifejezéslista értéksora a halmazban lévQ értéksorok
valamelyikével vagy mindegyikével?
egyezés_vizsgáló_operátor: [NOT] IN, =ANY, <>ANY, =ALL, <>ALL
-- Azon alkalmazottak néhány adata akikre teljesül a WHERE feltétel:
-- beosztása IGAZGATO vagy EGYEB
SELECT a_kod, a_nev, fizetes, beosztas FROM alkalmazott
WHERE beosztas IN ('IGAZGATO', 'EGYEB');
-- fizetése nem egyezik meg a felsorolt értékek egyikével sem:
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes NOT IN (90000,100000,80000);
-- fizetése nagyobb a felsorolt értékek mindegyikénél (azok maximumánál):
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes > ALL (90000,100000,80000);
-- fizetése nagyobb a felsorolt értékek valamelyikénél (azok minimumánál):
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes > ANY (90000,100000,80000);
-- fizetés, prémium értékpár elQfordul egy számpárokkal megadott halmazban
SELECT a_nev, fizetes, premium FROM alkalmazott
WHERE (fizetes, NVL(premium, 0)) IN ((60000,50000),(60000, 0));
Összetett keresési feltételek:
Az eddigi feltételeket a klasszikus logikai operátorokkal kapcsolhatjuk össze.
Logikai operátorok: NOT, AND, OR
Igazságtáblázatok: A kiértékelés "rövidzár" módon történik, azaz csak addig értékeli ki a kifejezést, ameddig annak értéke el nem dQl.
AND True False Unknown OR True False Unknown NOT True True False Unknown True True True True True False False False False False False True False Unknown False True Unknown Unknown False Unknown Unknown True Unknown Unknown Unknown Unknown
-- Alkalmazottak, akiknél a fizetés<80000 vagy fizetés>120000
-- és nem SZALLITO vagy ELADO a beosztásuk:
SELECT a_nev, beosztas, fizetes FROM alkalmazott
WHERE fizetes NOT BETWEEN 80000 AND 120000 AND beosztas NOT IN('SZALLITO', 'ELADO');
-- Alkalmazottak, akiknél a prémium nincs megadva vagy a 10-es telephelyen dolgoznak:
SELECT a_nev, premium, t_kod FROM alkalmazott
WHERE premium IS NULL OR t_kod='10';
-- Megoldandó:
-- 1. Azon telephelyek, amelyek kódja [30, 50] zárt intervallumba esik
-- és a nevében szerepel az ABC!
-- 2. Azon alkalmazottak, akiknél a fizetés és prémium összege kisebb mint 200000 és
-- a nevük nem K betqvel kezdQdik!
A mqveletek precedenciája (kiértékelés sorrendje):
Megadjuk az operátor csoportokat a precedenciájuk csökkenQ sorrendjében, ettQl zárójelezéssel lehet eltérni. Azonos precedenciájú mqveletek esetén a balról-jobbra szabály érvényes.
1. Aritmetikai operátorok ( *, /, +, - ). Közöttük a sorrend és a kötési irány a szokásos.
2. Karakteres operátor ( || )
3. Összehasonlító operátorok ( =, !=, <>, <, >, <=, >=,
[NOT] IN, ANY, ALL, [NOT] BETWEEN, [NOT] EXISTS, [NOT] LIKE, IS [NOT] NULL ).
Precedenciájuk azonos.
4. Logikai operátorok ( NOT, AND, OR ) Közöttük a sorrend és a kötési irány a szokásos.
Származtatott adatok, SQL sor-függvények
Származtatott adatok azok, amelyeket a tábla adatbázisban tárolt adataiból lehet kiszámítani SQL kifejezések segítségével. Az SQL kifejezés oszlopnevek, konstansok és függvényhívások összekapcsolva aritmetikai operátorokkal (*, /, +, -) vagy konkatenáló karakteres operátorral ( || ), zárójelezés is megengedett. Nagyon sok függvény van, részletes leírásuk megtalálható a referencia kézikönyvekben.
Típusai:
Sor-függvények (Row Functions): soronként végeznek mqveletet és soronként egy értéket adnak vissza.
Csoport-függvények (Aggregate Functions): a sorok egy-egy csoportján végeznek mqveletet és csoportonként egy értéket adnak vissza. (Ezeket egy külön fejezetben ismertetjük.)
Sor-függvények jellemzQi:
Alakja: fv_név (arg1, & )
Többségük a legtöbb programozási nyelvben megtalálható. Egy vagy több argumentumuk lehet, melyek helyére híváskor megfelelQ típusú sql_kifejezés írható. A függvényhívások tetszQleges mélységben egymásba ágyazhatók. A függvénynevek egy része túlterhelt, azaz ugyanazon függvényt meghívhatunk különbözQ típusú és számú argumentummal.
Ha az argumentumok valamelyike NULL, akkor NULL lesz a függvény értéke is. Csak néhány kivétel van: NVL, CONCAT, stb.
Sor-függvények típusai: aritmetikai (numerikus), karakteres, dátum, konverziós és egyéb függvények.
Egy egyszerq sor függvény kipróbálásához az Oracle-ben a DUAL rendszertáblát használhatjuk, amelynek egy oszlopa és egy sora van. (A használatához lényegtelen, hogy DUMMY az oszlopnév és X érték van a sorban.) SELECT fv_név (arg1,
) ,
FROM DUAL;
Aritmetikai függvények: ABS, POWER, SQRT, SIGN, ROUND, TRUNC, MOD, FLOOR, CEIL, EXP, LN, LOG, SIN, COS, TAN, stb.
POWER (3, 2) ( 9 -- hatványozás
ROUND (45.923, 2) ( 45.92 -- kerekítés
ROUND (45.923) ( 46
ROUND (45.923, -1) ( 50
TRUNC (45.923, 2) ( 45.92 -- csonkolás
TRUNC (45.923) ( 45
TRUNC (45.923, -1) ( 40
MOD (1600, 300) ( 100 -- osztás maradéka
Karakteres függvények: LOWER, UPPER, INITCAP, LENGTH, SUBSTR, LPAD, RPAD, LTRIM, RTRIM, CHR, ASCII, CONCAT, stb.
INITCAP ('alma alma') ( Alma Alma -- szókezdQ nagybetq
UPPER ('alma') ( ALMA -- nagybetqsít
LOWER('AlMa') ( alma -- kisbetqsít
LENGTH ('alma') ( 4 -- karaktersor hossza
SUBSTR ('alma', 2, 3) ( lma -- részkaraktersor kiemelés
INSTR ('almaxyalmaxy', 'xy') ( 5 -- részkaraktersor keresés
REPLACE ('almaxyalmaxy', 'xy', '*') ( alma*alma* -- részkaraktersor helyettesítés
LPAD ('alma', 6, '*') ( **alma -- balról kiegészít, adott hosszra
RPAD ('alma', 6, '*') ( alma** -- jobbról kiegészít, adott hosszra
LTRIM ('***alma*', '*') ( alma* -- balról leszed adott karaktereket
RTRIM ('*alma***', '*') ( *alma -- jobbról leszed adott karaktereket
TRANSLATE ('Ádám Éva','ÁÉá','AEa') ( Adam Eva -- átkonvertál adott karaktereket
CONCAT('Alma', NULL) ( Alma -- összefqz ( || ) két karaktersort
-- Azon alkalmazottak, akiknek Ede a keresztneve, a név nagy kezdQbetqsen legyen kiírva:
SELECT a_kod, INITCAP(a_nev), beosztas FROM alkalmazott
WHERE UPPER(a_nev) LIKE '% %EDE%';
Dátum függvények, dátumaritmetika:
A teljes dátum és idQ tárolásra kerül az adatbázisban speciális belsQ formában:
év (4 számjeggyel), hónap, nap, óra, perc, másodperc
A dátum megadási és megjelenítési formátuma, nyelve, idQzónája, stb. munkamenetenként állítható.
Az adatszótárból (DD) pedig lekérdezhetQk az aktuális alapértelmezett beállítások:
SELECT * FROM nls_session_parameters;
2000. év elQtt néhány évvel az Oracle-ben csak a következQ alapértelmezett dátumformátumok voltak:
'DD-MON-YY' pl.: '23-MAR-94' angol nyelven
'YY-MON-DD' pl.: '94-MÁR-23' magyar nyelven, ezekbQl az 1900-as években 1994-03-23 lesz.
Ugyanis az ilyen dátumformátum szerint megadott dátumoknál az évszázadot (az év elsQ két számjegye) az aktuális évszázadnak (SYSDATE évének elsQ két számjegye), az idQpontot pedig éjfélnek veszi.
2000. év környékén (az ezredfordulón) sok gondot okozott a két számjeggyel megadott év kezelése. Az eddigi dátumformátumokat használva 2000-ben (vagy késQbb) az elQzQ dátumokból 2094-03-23 lenne. Az Oracle-ben a probléma megoldására egy, az évet intelligensen kerekítQ formátumelemet vezettek be és az alapértelmezett dátumformátum is ezt használja: 'RR-MON-DD'. Ebben az esetben az évszázad (az év elsQ két számjegye) speciális kerekítéssel (Round) való képzése a következQ:
A 2 számjeggyel megadott év: 00-49 50-99 Az aktuális év utolsó 2 számjegye: 00-49 Aktuális évszázad ElQzQ évszázad 50-99 KövetkezQ évszázad Aktuális évszázad Például: 'RR-MON-DD' formátumot használva 2000. év elQtti vagy utáni közel 50 évben (mint aktuális SYSDATE évben) a '94-MÁR-23' dátum mindig 1994-03-23, a '04-MÁR-23' dátum pedig mindig 2004-03-23 dátum lesz. Az idQpont mindkét esetben éjfél.
Dátumaritmetika: dátumok kivonása -- eredmény napokban (egy szám)
dátumhoz nap (szám) hozzáadása, kivonása -- eredmény dátum
dátumok összehasonlítása.
Dátum függvények: SYSDATE, ADD_MONTHS, MONTHS_BETWEEN, LAST_DAY, TRUNC, ROUND
SYSDATE ( aktuális dátum és idQ
ADD_MONTHS ('74-JÚN-21', 2) ( 74-AUG-21 hónap hozzáadás
MONTHS_BETWEEN ('95-SZE-01', '94-JAN-11') ( 19.6774194 hónapok száma
NEXT_DAY(SYSDATE, 'Péntek') ( dátumhoz legközelebbi péntek dátuma
LAST_DAY(SYSDATE) ( dátum hónapjának utolsó napja
LAST_DAY(SYSDATE)-SYSDATE ( hány nap van hátra a hónapból
-- Néhány mqvelet a rendszerdátummal:
SELECT SYSDATE, SYSDATE+7, SYSDATE-7, SYSDATE+12/24, NEXT_DAY(SYSDATE, 'Szombat'),
ADD_MONTHS(SYSDATE,2), LAST_DAY(SYSDATE)-SYSDATE
FROM DUAL;
-- Néhány mqvelet a belépés dátumával:
SELECT a_nev, belepes, SYSDATE-belepes, MONTHS_BETWEEN(SYSDATE, belepes),LAST_DAY(belepes)
FROM alkalmazott;
-- SzökQévet jól kezeli-e a rendszer:
SELECT LAST_DAY('00-FEB-01'), LAST_DAY('04-FEB-01'), LAST_DAY('1900-FEB-01') FROM DUAL;
Konverziós függvények:
TO_CHAR (numerikus_kifejezés, 'szám_formátum')
TO_NUMBER ('numerikus_karaktersor_nem_alapértelmezett_formában', 'szám_formátum')
TO_CHAR (dátum_kifejezés, 'dátum_formátum')
TO_DATE ('dátum_kararaktersor_nem_alapértelmezett_formában', 'dátum_formátum')
Implicit adatkonverzió: a rendszer ha tudja, akkor szükség esetén automatikusan átalakítja az egyik típusú adatot egy másik típusra:
SELECT a_nev, belepes, t_kod, fizetes+'10' FROM alkalmazott
WHERE belepes BETWEEN '00-jan-01' AND '2002-Jan-01' OR t_kod>40;
Explicit adatkonverziót kell használni, ha a rendszer nem tudja a konverziót automatikusan elvégezni, vagy ha az eredménytábla oszlopainak alapértelmezett formátuma nem megfelelQ.
Szám formátumban használható elemek: 9 (hasznos számjegy helye), 0 (bevezetQ zérusok kiírása),
D (tizedespont karakter), G (ezredes csoportelválasztó karakter), L (pénznem szimbólum), RM (római számos, csak 1-3999 számtartományban) megjelenítés, stb.
SELECT a_nev, fizetes, TO_CHAR(fizetes, '09G999G999D99L'),TO_CHAR(fizetes/10000, 'RM')
FROM alkalmazott;
Dátum formátumban használható elemek:
Century (évszázad), Year (év), Month (hónap), Day (nap), Hour (óra), Minute (perc), Second (másodperc), Week (hét), Quarter (negyedév), stb. (Year helyett a már említett Round is használható.)
Az angol szavak kezdQbetqjét használjuk a dátumelemek számokkal való leírásának megformázásához (CC, YYYY, YY, RRRR, RR, MM, RM (római számos hónap), DD, HH24, HH12, HH12 AM, HH12 PM, MI, SS, WW, Q). Egyes dátumelemek (Year, Month, Day ) teljes szöveges kiírását vagy annak rövidítését (MON, DY) is kérhetjük, valamint a kis- vagy nagybetqs írásmód is jelölhetQ (month, mon, day, dy). Stb.
-- Belépés dátumának sok-sok eleme:
SELECT a_nev, TO_CHAR(belepes, 'CC -- YYYY.MM.DD -- HH24:MI:SS -- Day -- Q WW')
FROM alkalmazott;
Haladó:
-- Rendszerdátumból amit csak lehet betqvel írassunk ki:
SELECT SYSDATE, TO_CHAR(SYSDATE, 'Year Month RM Day --- MON DY') FROM DUAL;
-- Adott dátumok (pl. születésnapunk és 1848. márc. 15.) napját írassuk ki betqvel:
-- TO_DATE kell, mert TO_CHAR számként akarná kezelni a dátum karaktersort
SELECT TO_CHAR(TO_DATE('84-DEC-31', 'RR-MON-DD'), 'YYYY.MM.DD DAY'),
TO_CHAR(TO_DATE('1848.03.15', 'YYYY.MM.DD'), 'YYYY.RM.DD Day') FROM DUAL;
-- Dátumok kerekítése, csonkítása: évre, hónapra, napra
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'),
ROUND(SYSDATE, 'YYYY'), TRUNC(SYSDATE, 'YYYY'),
ROUND(SYSDATE, 'MM'), TRUNC(SYSDATE, 'MM'),
TO_CHAR(ROUND(SYSDATE), 'YYYY-MM-DD HH24:MI:SS'),
TO_CHAR(TRUNC(SYSDATE), 'YYYY-MM-DD HH24:MI:SS')
FROM DUAL;
** Egyéb függvények: USER, NVL, GREATEST, LEAST, DECODE, stb. Bármilyen adattípusra alkalmazhatók. Az argumentum nélküli USER az aktuális felhasználó azonosítóját adja.
-- (sql_kif1, sql_kif2, ...) legnagyobb, legkisebb eleme
SELECT a_nev, fizetes, premium, belepes, GREATEST(fizetes, 1.75*NVL(premium,0)),
LEAST (belepes, '00-JAN-01') FROM alkalmazott;
-- DECODE függvény egy CASE szelektoros kifejezésként mqködik
SELECT a_nev, beosztas,
DECODE(beosztas, 'IGAZGATO', 'FQnök', 'ELADO', 'Árus', 'Egyéb') AS Foglalkozás1,
CASE beosztas WHEN 'IGAZGATO' THEN 'FQnök'
WHEN 'ELADO' THEN 'Árus'
ELSE 'Egyéb' END AS Foglalkozás2
FROM alkalmazott;
** CASE kifejezések: újabban az SQL szabványban és az Oracle-ben is megengedettek, és szinte minden olyan helyen állhat, ahol sql_kifejezés áll a szintaxisban, sQt még mqvelet is végezhetQ vele:
CASE szelektoros:
Az elsQ olyan WHEN ág eredm_kifejezését adja, melyre a szelektor_kifejezés=hasonlító_kifejezés igaz. Ha nincs ilyen ág és nincs ELSE ág sem, akkor NULL az eredmény. CASE feltételes:
Az elsQ olyan WHEN ág eredm_kifejezését adja, melyre a feltétel igaz. Ha nincs ilyen ág és nincs ELSE ág sem, akkor NULL az eredmény. CASE szelektor_kifejezés
WHEN hasonlító_kifejezés THEN eredm_kifejezés
[WHEN hasonlító_kifejezés THEN eredm_kifejezés]
[ELSE eredm_kifejezés]
END CASE
WHEN feltétel THEN eredm_kifejezés
[WHEN feltétel THEN eredm_kifejezés]
[ELSE eredm_kifejezés]
END
-- CASE példa: CASE feltételes
SELECT a_nev, fizetes, premium,
1000 + CASE WHEN premium > 100000 THEN premium
WHEN premium IS NULL THEN 0
ELSE fizetes END AS "1000 + CASE prémium",
CASE WHEN premium > 100000 THEN 'Nagy prémium volt'
WHEN premium IS NULL THEN 'Null prémium volt'
ELSE 'Fizetést kapta meg prémiumnak' END AS "Megjegyzés"
FROM alkalmazott;
*** További függvények a NULL érték kezelésére az SQL szabványban és az Oracle-ben:
NVL(sql_kif1, sql_kif2) CASE WHEN sql_kif1 IS NOT NULL THEN sql_kif1 ELSE sql_kif2 END
NVL2(sql_kif1, sql_kif2, sql_kif3)
CASE WHEN sql_kif1 IS NOT NULL THEN sql_kif2 ELSE sql_kif3 END
COALESCE(sql_kif1, ...) a kifejezéslistából az elsQ nem NULL kifejezést adja vissza, ha mind NULL
értékq, akkor az eredmény is NULL lesz. Az NVL függvény általánosítása.
NULLIF(sql_kif1, sql_kif2) CASE WHEN sql_kif1=sql_kif2 THEN NULL ELSE sql_kif1 END
pl. NULLIF (0, x-x) ha x nem NULL, akkor NULL lesz az eredmény, egyébként 0.
Csoportok képzése, SQL csoport-függvények
SELECT ...
FROM ...
...
[GROUP BY sql_kifejezés ,... ]
[HAVING csoportkiválasztási_feltétel]
;
A GROUP BY a kiválasztott sorok csoportosítására, HAVING pedig a csoportok közötti válogatásra szolgál. A csoportokon csoport-függvényekkel mqveletek (számolások) végezhetQk. Ha nincs GROUP BY záradék, akkor egyetlen csoportot képez az összes sor.
A GROUP BY után megadott sql_kifejezések (melyek legtöbbször oszlopnevek) határozzák meg azt, hogy a sorok csoportosítása mely oszlop értéke szerint történjen elsQdlegesen, majd azon belül mely oszlop szerint másodlagosan, stb.
Az opcionális HAVING részben adható meg a csoportok közüli szelektálási feltétel.
Egy csoportot képeznek azon sorok, amelyekben a GROUP BY után álló csoportképzQ oszlop értéke (több oszlop esetén azok összevont értéke) azonos. A rendszer a végrehajtás során implicit rendezést hajt végre a csoportképzQ oszlopok szerint. Egy-egy csoportból csak egy összesített információt tartalmazó sor, a "csoportazonosítóhoz" tartozó "gyqjtQsor" lesz visszaadva. Azon sorok is részt vesznek a csoportosításban, ahol csoportképzQ oszlop értéke NULL.
SELECT, HAVING és ORDER BY részben csak a következQk szerepelhetnek:
- GROUP BY -ban szereplQ oszlopok (vagy sql_kifejezések ugyanolyan formában),
- csoportfüggvények, argumentumuk tetszQleges sql_kifejezés is lehet,
- paraméter nélküli függvények (pl. SYSDATE, USER) és konstansok.
Csoportfüggvények: A sorok egy-egy csoportján végeznek számításokat, csoportonként egy értéket állítanak elQ. Egyszeres mélységben egymásba ágyazhatók. Csak a SELECT, HAVING, ORDER BY záradékokban használhatók, a WHERE feltételben és a JOIN ON feltételben nem!
Alakja: fv_név ( [ DISTINCT | ALL ] sql_kifejezés)
fv_név: COUNT, AVG, SUM, MIN, MAX, STDDEV, VARIANCE, stb.
COUNT, MIN, MAX minden argumentumtípussal mqködik, a többi csak numerikussal.
DISTINCT csak a különbözQ értékeket veszi figyelembe, ALL az összest.
A csoportfüggvények a számolásnál kihagyják a NULL értékeket. Tehát ha egy csoportban nincs sor, vagy minden érték NULL, az eredmény is NULL lesz. Kivétel a COUNT(sql_kifejezés) függvény, amely ekkor 0-át ad vissza.
A COUNT függvényt * argumentummal is meghívhatjuk, mely azonos lesz a COUNT(1) eredményével:
COUNT(*) Az összes sor száma, a NULL értékek is számítanak. Ha nincs sor, akkor 0-át ad.
Példák: Ha nincs GROUP BY záradék, akkor egyetlen csoportot képez az összes sor. Ha a SELECT listában van csoportfüggvény, akkor más oszlopok egyedi értékei nem kérdezhetQk le.
-- Összes alkalmazott száma, fizetések összege, átlaga, minimuma, maximuma:
SELECT COUNT(*), SUM(fizetes), AVG(fizetes), MIN(fizetes), MAX(fizetes)
FROM alkalmazott;
-- Összes VEZETO beosztású alkalmazott száma, fizetések összege, átlaga, minimuma,
-- maximuma:
SELECT COUNT(*), SUM(fizetes), AVG(fizetes), MIN(fizetes), MAX(fizetes)
FROM alkalmazott WHERE beosztas='VEZETO';
-- A csoportfüggvények a NULL értéket kihagyják, ezért szükség esetén az
-- NVL függvényt kell alkalmazni az argumentumban.
-- Összes alkalmazott száma, nem NULL prémiumok száma, nem NULL prémiumok átlaga,
-- összes alkalmazott prémiumának átlaga:
SELECT COUNT(*), COUNT(premium), AVG(premium), AVG(NVL(premium,0)) FROM alkalmazott;
-- Az alkalmazott táblában szereplQ különbözQ beosztások és a
-- különbözQ telephelykódok darabszáma:
SELECT COUNT(DISTINCT beosztas), COUNT(DISTINCT t_kod) FROM alkalmazott;
Példák: GROUP BY csoportosítás, HAVING csoportok közül való válogatás.
-- Határozzuk meg az alkalmazottak telephelyenkénti csoportjaira (csoportosítás
-- t_kod szerint) a létszámot, a fizetések összegét és az átlagfizetést:
-- (t_kod mellett más oszlop lekérdezése hibás lenne.)
SELECT t_kod, COUNT(*) létszám, SUM(fizetes) összeg, AVG(fizetes) átlag FROM alkalmazott
GROUP BY t_kod;
-- Csak a 80000-nél nagyobb fizetésq alkalmazottak vegyenek részt a csoportosítási
-- mqveletben és rendezzük az eredménysorokat t_kod szerint csökkenQleg:
SELECT t_kod, COUNT(*) létszám, SUM(fizetes) összeg, AVG(fizetes) átlag
FROM alkalmazott
WHERE fizetes>80000
GROUP BY t_kod
ORDER BY t_kod DESC;
-- Csak azon csoportokat írassuk ki, ahol az átlagfizetés 120000-nél nagyobb,
-- vagy legalább öten vannak:
SELECT t_kod, COUNT(*) létszám, SUM(fizetes) összeg, AVG(fizetes) átlag
FROM alkalmazott
GROUP BY t_kod
HAVING AVG(fizetes)>120000 OR COUNT(*) >= 5;
-- Határozzuk meg az alkalmazottak telephelyenként, azon belül beosztásonként
-- képzett csoportjaira a létszámot, az átlagfizetést és az átlagprémiumot:
SELECT t_kod, beosztas, COUNT(*), AVG(fizetes), AVG(NVL(premium, 0))
FROM alkalmazott
GROUP BY t_kod, beosztas;
Haladó:
Egymásba ágyazott csoportfüggvények: a belsQ csoportfüggvény a megszokott módon számol, a külsQ csoportfüggvény viszont a csoportok eredménysorain végzi a számítást:
-- A t_kod szerinti csoportok max fizetéseinek vegyük az átlagát:
-- (Itt már t_kod, max(fizetes) nem írható ki.)
SELECT AVG(MAX(fizetes)) átlag_max_fiz FROM alkalmazott
GROUP BY t_kod;
Hozzunk össze egy eredménytáblába különbözQ szintq csoportosításokat: Több különbözQ GROUP BY záradékos SELECT unió-kompatibilissé tett eredményét egyesítsük UNION ALL -al.
-- Határozzuk meg az alkalmazottak telephelyenkénti csoportjaira (csoportosítás
-- t_kod szerint) a létszámot és a fizetések szummáját. Jelenjen meg az eredménytáblában
-- az összes alkalmazott létszáma és fizetésük szummája is (mint végösszesen).
SELECT t_kod, COUNT(*) létszám, SUM(fizetes) szum_fiz FROM alkalmazott
GROUP BY t_kod
UNION ALL
SELECT 'ÖSSZ', COUNT(*), SUM(fizetes) FROM alkalmazott;
*** GROUP BY kiterjesztése Oracle-ben:
Oracle újabb verzióiban lehetQség van az eddigi normál-csoportosításon túl olyan szuper-csoportosítások megadására is, amelyek a normál csoportosítás "gyqjtQsorai" mellett még különbözQ fajta számítási fokozatoknak megfelelQ szupergyqjtQ-sorokat is visszaadnak.
GROUP BY {sql_kif ,... | GROUPING SETS( (sql_kif ,...) ,...)
| CUBE(sql_kif ,...) | ROLLUP(sql_kif ,...)}
GROUPING SETS ((sql_kif ,...) ,...) egyenként elvégzi a listákon elQírt kifejezések szerint a normál csoportosításokat, majd az eredménysorok UNION ALL operátorral egyesítve lesznek.
-- A t_kod, beosztas szerinti csoportokra végzett számítások mellett
-- jelenjen meg a t_kod szerinti összegfokozat és a végösszesen is.
-- Ugyanezt adja a ROLLUP(t_kod, beosztas)
SELECT t_kod, beosztas, SUM(fizetes), COUNT(*) FROM alkalmazott
GROUP BY GROUPING SETS((t_kod, beosztas),(t_kod), ());
-- t_kod, beosztas szerinti csoportokra végzett számítások mellett
-- jelenjen meg a t_kod szerinti összegfokozat,
-- a beosztas szerinti összegfokozat és a végösszesen is.
-- Ugyanezt adja a CUBE(t_kod, beosztas)
SELECT t_kod, beosztas, SUM(fizetes), COUNT(*) FROM alkalmazott
GROUP BY GROUPING SETS((t_kod, beosztas),(t_kod), (beosztas), ());
ROLLUP (sql_kif1, ..., sql_kifN) elvégzi a csoportosításokat az elsQ N, N-1, N-2, ..., 0 darab sql_kif szerint. Ezek közül az elsQ N darab sql_kif szerinti adja az eddigi normál-csoportosítást, a többi pedig a szuper-csoportokat adja. Összesen N+1 darab különbözQ csoportosítás van végrehajtva, majd egyesítve.
SELECT t_kod, beosztas, SUM(fizetes), COUNT(*) FROM alkalmazott
GROUP BY ROLLUP(t_kod, beosztas);
CUBE (sql_kif1, ..., sql_kifN) elvégzi a csoportosításokat az sql_kif -ek összes lehetséges kombinációja szerint. Ezek közül az elsQ N darab sql_kif szerinti adja az eddigi normál-csoportosítást, a többi pedig a szuper-csoportokat adja. Összesen 2N darab különbözQ csoportosítás van végrehajtva, majd egyesítve.
SELECT t_kod, beosztas, SUM(fizetes), COUNT(*) FROM alkalmazott
GROUP BY CUBE(t_kod, beosztas);
Mindhárom esetben a szuper-csoportok eredménysoraiban hiányzik egy vagy több csoportosító oszlopérték, amely szerepel a normál-csoportokban. Ezt a rendszer egy speciális NULL értékkel reprezentálja, amelyet egy speciális függvénnyel tudunk kezelni:
GROUPING(sql_kif) = 1 ha sql_kif speciális NULL érték,
= 0 egyéb érték és a normál NULL esetén.
Ez a függvény jól használható a szupercsoportosításból származó sorok közül való szelektálásra (pl. HAVING GROUPING(sql_kif)=1) és az eredmény megszépítésére, a nem látszó speciális NULL helyére értelmes szöveget írva.
-- Mindegyik korábbi példa eredménye azonos módon szépíthetQ meg:
SELECT DECODE(GROUPING(t_kod), 1, 'Össz t_kód', t_kod) AS kod,
NVL(DECODE(GROUPING(beosztas), 1, 'Össz beosztás', beosztas),'null') AS beosztás,
SUM(fizetes), COUNT(*)
FROM alkalmazott
-- GROUP BY GROUPING SETS((t_kod, beosztas),(t_kod), ())
-- GROUP BY ROLLUP(t_kod, beosztas)
-- GROUP BY GROUPING SETS((t_kod, beosztas),(t_kod), (beosztas), ())
GROUP BY CUBE (t_kod, beosztas)
-- HAVING GROUPING(t_kod)=1 OR GROUPING(beosztas)=1 -- csak a szupersorok
ORDER BY t_kod, beosztas;
Táblák összekapcsolása (Join)
Ha több táblából akarunk adatokat visszanyerni, akkor ezt leggyakrabban a táblák összekapcsolásával tudjuk megoldani, de egy tábla önmagával is összekapcsolható (Self Join). Meg kell adni az összekapcsolandó táblákat, az összekapcsolás típusát és a kapcsolófeltételt. Az SQL szabványban és az Oracle9i-tQl kezdve mindezt a FROM záradékban tehetjük meg!
SELECT &
FROM tábla1 [t_aliasnév1]
-- 1. Descartes szorzat. Kapcsolófeltétel lehet hozzá a WHERE részben.
[ , tábla2 [t_aliasnév2] ]
[ CROSS JOIN tábla2 [t_aliasnév2]]
-- 2. kapcsolófeltétel alapján táblák (egyen vagy nem egyen) összekapcsolása: belsQ v. külsQ join. Legáltalánosabb!
[ [join_típus] JOIN tábla2 [t_aliasnév2] ON kapcsolófeltétel ] &
-- 3. egyen-összekapcsolás, a táblák azonos nevq megadott oszlopa(i) alapján: belsQ vagy külsQ join.
[ [join_típus] JOIN tábla2 [t_aliasnév2] USING(oszlop ,& )] &
-- 4. egyen-összekapcsolás, a táblák összes azonos nevq oszlopa(i) alapján: belsQ vagy külsQ join.
[ NATURAL [join_típus] JOIN tábla2 [t_aliasnév2] ] &
[WHERE kapcsolófeltétel {AND | OR} egyéb_feltétel]
& ;
join_típus ::= INNER | {LEFT | RIGHT | FULL } [OUTER]
A join_típust ha nem adjuk meg, akkor alapértelmezésként belsQ (INNER) join, továbbá a bal-, jobb- vagy kétoldali külsQ (OUTER) összekapcsoláshoz elegendQ a LEFT, RIGHT vagy FULL kulcsszó megadása.
A join mqveletben szereplQ táblák száma nincs korlátozva. A táblák valódi és nézettáblák egyaránt lehetnek. Az oszlopneveket minQsíteni kell, ha több táblában van azonos nevq oszlop.
A különbözQ joinok keverhetQk. Zárójelezéssel térhetünk el az alapértelmezett balról-jobbra kiértékeléstQl. A belsQ join asszociatív, a külsQ join nem. Például:
FROM a NATURAL LEFT OUTER JOIN b LEFT OUTER JOIN c ON b.c1 = c.c1
FROM a NATURAL LEFT OUTER JOIN (b LEFT OUTER JOIN c ON b.c1 = c.c1)
A relációs modellben a táblák közötti kapcsolat megvalósítása külsQ kulccsal (kapcsolóoszloppal) történik. Ezzel adható meg, hogy az egyik tábla (szülQ tábla) egy adott sorához, egy másik tábla (gyerek tábla) mely sorai tartoznak. A gyakorlatban legtöbbször a tábláknak a külsQ kulcsban definiált oszlopok egyen-összekapcsolási (equijoin) feltétel szerinti összekapcsolására van szükség. (Lásd korábban a külsQ kulcs pontos leírását!)
-- 1. Descartes szorzat (Cross Join vagy kereszt szorzás): Az egyik tábla minden sorát az összes lehetséges módon összekapcsoljuk (folytatjuk) a másik tábla minden sorával. Oszlopok száma: összeadódik. Sorok száma: összeszorzódik. Nincs kapcsolófeltétel.
SELECT * FROM telephely CROSS JOIN alkalmazott;
SELECT * FROM telephely, alkalmazott;
-- 2. kapcsolófeltétel alapján táblák (egyen vagy nem egyen) összekapcsolása: belsQ vagy külsQ join.
A táblák összekapcsolása az ON kapcsolófeltétel alapján történik. Legáltalánosabb! Szokásos elnevezések:
Equijoin: egyen-összekapcsolás, a kapcsolóoszlopok értékegyenlQségén alapszik.
Nem Equijoin: nem egyen-összekapcsolás, a kapcsolóoszlopok egyenlQségtQl eltérQ relációján alapszik. (Lásd még elmélet Theta Join.)
[ INNER ] JOIN: BelsQ összekapcsolás. Az egyik tábla sorait a másik tábla csak azon soraival kapcsoljuk össze, amelyek a kapcsolófeltételnek eleget tesznek.
-- Egyen-összekapcsolás.
-- Telephelyek adatsora mellett jelenjen meg az ott dolgozó alkalmazottak adatsora:
-- (Alternatív megfogalmazás: Alkalmazottak adatsora mellett a telephelyének adatsora.)
SELECT * FROM telephely T INNER JOIN alkalmazott A ON T.t_kod = A.t_kod;
-- Nem egyen-összekapcsolás. Egyben példa tábla önmagával való joinjára is (Self Join).
-- Telephelyek adatsora mellett jelenjen meg a nagyobb kódú telephelyek adatsora:
SELECT * FROM telephely X INNER JOIN telephely Y ON X.t_kod < Y.t_kod;
-- Az elözQ két feladat más megoldása: Descartes szorzat és WHERE-ben kapcsolófeltétel:
SELECT * FROM telephely T CROSS JOIN alkalmazott A
WHERE T.t_kod = A.t_kod;
SELECT * FROM telephely T, alkalmazott A
WHERE T.t_kod = A.t_kod;
SELECT * FROM telephely X CROSS JOIN telephely Y
WHERE X.t_kod < Y.t_kod;
SELECT * FROM telephely X, telephely Y
WHERE X.t_kod < Y.t_kod;
{LEFT | RIGHT | FULL } [OUTER] JOIN: KülsQ összekapcsolás. Nemcsak a kapcsolófeltételnek eleget tevQ sorokat adja vissza, hanem az egyik tábla olyan sorait is, amelyekhez nincs a kapcsolófeltétel alapján kapcsolódó sor a másik táblában (tehát az egyik tábla összes sora szerepel az eredményben). Ezen sorokat a belsQ join nem adná vissza. Ekkor az egyik táblából származó páratlan sorokat csupa NULL értékeket tartalmazó "üres" sorral egészíti ki. ElQ kell írni, hogy a JOIN operátor bal (LEFT) vagy a jobb (RIGHT) oldalán álló tábla összes sora legyen megtartva, de kérhetQ a kétoldali, teljes (FULL) külsQ összekapcsolás is.
-- Telephelyek adatsora mellett jelenjen meg az ott dolgozó alkalmazottak adatsora.
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez még nincs alkalmazott:
SELECT * FROM telephely T LEFT OUTER JOIN alkalmazott A ON T.t_kod = A.t_kod;
SELECT * FROM alkalmazott A RIGHT OUTER JOIN telephely T ON T.t_kod = A.t_kod;
-- Telephelyek adatsora mellett jelenjen meg a nagyobb kódú telephelyek adatsora.
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez nincs ilyen telephely:
SELECT * FROM telephely X LEFT OUTER JOIN telephely Y ON X.t_kod < Y.t_kod;
(Haladó megjegyzés: az Oracle9i elQtti verziókban nem voltak meg a szabvány kulcsszavas operátorai a különbözQ joinokra, a külsQ joint a WHERE-beli kapcsolófeltételben megadott (+) operátorral lehetett csak elQírni. Lásd késQbb.)
-- 3. egyen-összekapcsolás, a táblák azonos nevq megadott oszlopa(i) alapján: belsQ vagy külsQ join.
A USING(oszlop ,& ) részben kell megadni, hogy a táblák mely azonos nevq oszlopa(i) alapján legyen összeállítva az egyen-összekapcsolási feltétel. Ezen oszlopok csak egyszer jelennek meg az eredménytáblában, és táblanévvel vagy tábla aliasnévvel nem minQsíthetQk sehol az utasításban. ElQírhatjuk, hogy belsQ vagy külsQ joint kérünk.
-- Telephelyek adatsora mellett jelenjen meg az ott dolgozó alkalmazottak adatsora:
SELECT * FROM telephely INNER JOIN alkalmazott USING(t_kod);
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez még nincs alkalmazott:
SELECT * FROM telephely LEFT OUTER JOIN alkalmazott USING(t_kod);
-- 4. egyen-összekapcsolás, a táblák összes azonos nevq oszlopa(i) alapján: belsQ vagy külsQ join.
Természetes összekapcsolás: Nem kell megadni kapcsoló oszlopokat és kapcsolófeltételt. A táblák összes azonos nevq oszlopait használva lesz összeállítva az egyen-összekapcsolási feltétel. Ezen oszlopok csak egyszer jelennek meg az eredménytáblában, és táblanévvel vagy tábla aliasnévvel nem minQsíthetQk sehol az utasításban. ElQírhatjuk, hogy belsQ vagy külsQ joint kérünk.
-- Telephelyek adatsora mellett jelenjen meg az ott dolgozó alkalmazottak adatsora.
SELECT * FROM telephely NATURAL INNER JOIN alkalmazott;
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez még nincs alkalmazott:
SELECT * FROM telephely NATURAL LEFT OUTER JOIN alkalmazott;
Példák: KettQnél több tábla is összekapcsolható, az összekapcsolással nyert eredménytábla soraira egyéb szqrQfeltételek is alkalmazhatók, a sorok csoportosíthatók, válogathatunk az eredménytábla oszlopai közül, az eredménysorok rendezhetQk. Lásd még a SELECT záradékok kiértékelési sorrendjét.
-- Telephelyek adatai és az ott dolgozó alkalmazottak néhány adata.
-- Rendezés telephelykódonként, azon belül névsor szerint növekvQ:
SELECT T.*, a_nev, a_kod, beosztas, fizetes
FROM telephely T JOIN alkalmazott A ON T.t_kod = A.t_kod
ORDER BY T.t_kod, a_nev;
-- ElQzQ, plusz: Azon a telephelyek is legyenek kiírva, ahol még nem dolgozik senki:
SELECT T.*, a_nev, a_kod, beosztas, fizetes
FROM telephely T LEFT JOIN alkalmazott A ON T.t_kod = A.t_kod
ORDER BY T.t_kod, a_nev;
-- Telephelyek adatai és az ott dolgozó ELADO beosztású alkalmazottak néhány adata.
-- BelsQ joinnál beosztas='ELADO' lehet az ON kapcsolófeltételben, vagy a WHERE részben.
SELECT T.*, a_nev, a_kod, beosztas, fizetes
FROM telephely T JOIN alkalmazott A ON T.t_kod = A.t_kod
WHERE beosztas='ELADO';
-- ElQzQ, plusz: Azon a telephelyek is legyenek kiírva ahol nincs ELADO alkalmazva.
-- KülsQ joinnál a helyes megoldáshoz beosztas='ELADO' a kapcsolófeltételben legyen.
SELECT T.*, a_nev, a_kod, beosztas, fizetes
FROM telephely T LEFT JOIN alkalmazott A ON T.t_kod = A.t_kod AND beosztas='ELADO';
-- Alkalmazottak kódját, nevét, és telephelyének kódját, nevét, városát:
-- Csak azokat, akik telephelyének nevében szerepel 'ABC' karaktersor és városuk BUDAPEST
SELECT a_kod, a_nev, T.* FROM alkalmazott A JOIN telephely T ON T.t_kod = A.t_kod
WHERE t_nev LIKE '%ABC%' AND varos='BUDAPEST';
-- Telephely városonkénti csoportokra az alkalmazottak létszámát és átlagfizetését:
SELECT varos, COUNT(*) letszam, AVG(fizetes) atlag_fiz
FROM telephely T JOIN alkalmazott A ON T.t_kod = A.t_kod
GROUP BY varos;
-- Az alkalmazottak és a közvetlen fQnökük néhány adata (tábla önmagával való joinja)
SELECT X.a_kod, X.a_nev, 'fQnöke:', Y.a_kod, Y.a_nev
FROM alkalmazott X JOIN alkalmazott Y ON X.fonok = Y.a_kod;
Haladó:
2-nél több tábla joinja:
-- Az alkalmazottak és közvetlen fQnökük, valamint közvetlen fQnökük telephelyének adatai:
SELECT X.a_kod, X.a_nev, 'fQnöke:', Y.a_kod, Y.a_nev, Y.t_kod, T.t_nev, T.varos
FROM alkalmazott X JOIN alkalmazott Y ON X.fonok = Y.a_kod
JOIN telephely T ON Y.t_kod = T.t_kod;
-- Megoldandó:
-- 1. ElQzQ feladat kiegészítése: Az összes alkalmazott jelenjen meg! (Szabó Pál is!)
-- 2. Írassuk ki az összes alkalmazott nevét, telephelyének adatait, valamint
-- a közvetlen fQnöke nevét!
A külsQ joinnal elQállt csupa NULL értéket tartalmazó sorrészt "tudatosan" kezelhetjük és a számolásnál az ott lévQ NULL értékekre is gondolni kell.
-- Azon telephelyek, amelyeken még nincs alkalmazott:
-- Nem ez lesz a legtipikusabb megoldás, lásd még a beágyazott select fejezetet.
SELECT T.* FROM telephely T LEFT JOIN alkalmazott A ON T.t_kod = A.t_kod
WHERE a_kod IS NULL;
-- Az alkalmazottak és közvetlen fQnökük adatai:
-- Akinek nincs fQnöke az is jelenjen meg a fQnök kódja és neve helyén '----' karakterrel
SELECT X.a_kod, X.a_nev , NVL(Y.a_kod, '----') f_kod, NVL(Y.a_nev, '----') f_nev
FROM alkalmazott X LEFT JOIN alkalmazott Y ON X.fonok = Y.a_kod;
-- Telephely kódonkénti csoportokra az alkalmazottak létszámát és a fizetések szummáját.
-- A telephelyek minden adata legyen kiírva. (Megj. GROUP BY -ban T.t_kod már elvégzi
-- a szükséges csoportosítást, azon belül t_nev, varos újabb csoportokat nem hoz létre,
-- de fel kell venni, hogy a SELECT után beírható legyen.)
SELECT T.t_kod, t_nev, varos, COUNT(*) letszam, SUM(fizetes) szum_fiz
FROM telephely T JOIN alkalmazott A ON T.t_kod = A.t_kod
GROUP BY T.t_kod, t_nev, varos;
-- ElQzQ, plusz: Az összes telephely jelenjen meg. Azon telephelyeknél, ahol nem dolgozik
-- senki a létszám és a fizetések szummája 0 legyen az eredményben.
SELECT T.*, COUNT(a_kod) letszam, SUM(NVL(fizetes,0)) szum_fiz
FROM telephely T LEFT JOIN alkalmazott A ON T.t_kod = A.t_kod
GROUP BY T.t_kod, t_nev, varos;
-- Telephely kódonkénti csoportokra az ott dolgozó SZALLITO és VEZETO beosztású
-- alkalmazottak létszámát és átlagfizetését. A telephelyek kódja és városa legyen kiírva.
-- Azon telephelyek is jelenjenek meg, ahol nincs SZALLITO és VEZETO beosztású dolgozó,
-- ezeknél a létszám és az átlag 0 legyen az eredményben:
SELECT T.t_kod, varos, COUNT(a_kod) letszam, AVG(NVL(fizetes,0)) atlag_fiz
FROM telephely T LEFT JOIN alkalmazott A ON T.t_kod = A.t_kod
AND beosztas IN ('SZALLITO', 'VEZETO')
GROUP BY T.t_kod, varos;
** Oracle (+) jeles külsQ join: Az Oracle9i elQtt (és egyes más implementációkban) nem voltak meg a szabvány kulcsszavas operátorai a különbözQ joinokra, a kapcsolófeltételt és külsQ join (+) operátort a WHERE záradékban lehetett megadni az egyéb szelekciós feltétellel együtt, ami nehezíti az olvashatóságot. Ha egy táblára vonatkozóan szerepel a (+) operátor, akkor arra a táblára kulcsszavas join nem adható!
SELECT ...
FROM tábla1 [t_aliasnév1], tábla2 [t_aliasnév2] ,...
[ WHERE kapcsolóoszlop1 [(+)] hasonlító_operátor kapcsolóoszlop2 [(+)]
[ AND további_kapcsolófeltétel] [ {AND | OR} egyéb_feltétel] ]
;
A FROM után vesszQvel elválasztva adjuk meg az összekapcsolandó táblákat, a WHERE záradékban pedig a kapcsolófeltétel(eke)t az egyéb szelekciós feltételekkel. A külsQ join jele: (+). Oracle-ben azon táblából származó oszlopot jelöljük meg (+) jellel, a külsQ join mqveleti jelével, amely táblából csupa NULL értékeket tartalmazó sorral való kiegészítést kérünk. MindkettQt megjelölni nem lehet. Fontos: tehát azon tábla összes sora lesz megtartva, amelybQl származó oszlop nincsenek megjelölve (+) jellel, teljesen függetlenül a reláció bal vagy jobboldalán való elhelyezkedéstQl! Összetett külsQ kulcsok alapján elQírt vagy egyéb összetett kapcsolófeltétel esetén minden részfeltételben fel kell tüntetni a (+) jelet. KülsQ join jele nem megengedett OR vagy IN feltételben, ekkor hibajelzést kapunk.
Néhány korábbi külsQ joinos feladat megoldása:
-- Telephelyek adatsora mellett jelenjen meg az ott dolgozó alkalmazottak adatsora.
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez még nincs alkalmazott:
-- WHERE T.t_kod = A.t_kod (+) -- ugyanazt az eredményt adná
SELECT * FROM telephely T, alkalmazott A
WHERE A.t_kod (+) = T.t_kod;
-- Telephelyek adatsora mellett jelenjen meg a nagyobb kódú telephelyek adatsora.
-- Jelenjenek meg azon telephelyek is (pl. t_kod=50), amelyekhez nincs ilyen telephely:
SELECT * FROM telephely X, telephely Y
WHERE X.t_kod < Y.t_kod (+);
-- Azon telephelyek adatsora, ahol nem dolgozik senki:
SELECT T.* FROM telephely T, alkalmazott A
WHERE T.t_kod = A.t_kod (+) AND a_kod IS NULL;
-- Telephelyek adatai és az ott dolgozó ELADO beosztású alkalmazottak néhány adata.
-- Azon a telephelyek is legyenek kiírva ahol nincs ELADO alkalmazva.
SELECT T.*, a_nev, a_kod, beosztas, fizetes
FROM telephely T, alkalmazott A
WHERE T.t_kod = A.t_kod (+) AND beosztas (+) = 'ELADO';
Halmazmqveletek selectek között
Lekérdezések kompatíbilis eredménytáblái (táblák oszlopainak száma egyezik és típus szerint is rendre kompatibilisek) halmazmqveletekkel kapcsolhatók össze. Oracle-ben az eredménytábla oszlopainak nevét az elsQ tábla szolgáltatja.
select_utasítás [halmazmqvelet select_utasítás] ... [ORDER BY ...];
halmazmqvelet:
UNION - Egyesítés eredménye: minden olyan sor, amely legalább az egyik táblában elQfordul, sor duplikáció nincs.
UNION ALL - Egyesítés eredménye: a táblákban elQforduló összes sor. Sor duplikációt megenged. (Csak ez!)
INTERSECT - Metszet eredménye: mindkét táblában elQforduló közös sorok.
MINUS - Kivonás eredménye: az elsQ táblából elhagyjuk a második táblában elQforduló sorokat.
A szabványban EXCEPT kulcsszó van erre.
Oracle-ben jelenleg a halmazmqveletek precedenciája azonos, a kiértékelés balról jobbra (leírási sorrendben) történik, de zárójelezéssel más sorrendet lehet elQírni. (Egyes implementációkban és a szabványban az INTERSECT precedenciája nagyobb a többinél!)
UNION, INTERSECT, MINUS esetén nincs sorduplikáció és ekkor a rendszer implicit módon rendez.
-- Vegyük az unióját (vagy a metszetét vagy a különbségét) a telephely táblából származó
-- t_kod értékek halmazának és az alkalmazott táblából származó t_kod értékek halmazának:
-- Unió, nincs sorduplikáció:
SELECT t_kod FROM telephely UNION SELECT t_kod FROM alkalmazott;
-- Unió, sorduplikáció nincs megszüntetve (csak ennél!):
SELECT t_kod FROM telephely UNION ALL SELECT t_kod FROM alkalmazott ORDER BY t_kod;
-- Metszet: azon telephelykódok, amelyeken van alkalmazott:
SELECT t_kod FROM telephely INTERSECT SELECT t_kod FROM alkalmazott;
-- Különbség: azon telephelykódok, amelyeken nincs alkalmazott:
SELECT t_kod FROM telephely MINUS SELECT t_kod FROM alkalmazott;
Haladó: Ha egy SQL implementációban nincs realizálva a külsQ join vagy annak nem mindegyik típusa, akkor halmazok egyesítésével elQ lehet állítani. Például az Oracle korábbi verzióiban lévQ (+) jeles külsQ join nem engedte meg a kétoldali (Full) összekapcsolást:
-- Az alkalmazottak és a közvetlen fQnökük/beosztottjuk néhány adata.
-- Azon alkalmazottak is jelenjenek meg, akiknek nincs fQnökük.
-- Azon alkalmazottak is jelenjenek meg, akiknek nincs beosztottjuk.
-- A szabvány kulcsszavas joinjával:
SELECT X.a_kod, X.a_nev, 'fQnöke:', Y.a_kod, Y.a_nev
FROM alkalmazott X FULL JOIN alkalmazott Y ON X.fonok = Y.a_kod;
-- *** FULL JOIN halmazok egyesítésével:
SELECT X.a_kod, X.a_nev, 'fQnöke:', Y.a_kod, Y.a_nev -- INNER JOIN sorok
FROM alkalmazott X, alkalmazott Y WHERE X.fonok = Y.a_kod
UNION ALL
SELECT X.a_kod, X.a_nev, 'fQnöke:', NULL, NULL -- LEFT OUTER JOIN -hoz plusz sorok
FROM alkalmazott X WHERE NOT EXISTS (SELECT * FROM alkalmazott Y WHERE X.fonok = Y.a_kod)
UNION ALL
SELECT NULL, NULL, 'fQnöke:', X.a_kod, X.a_nev -- RIGHT OUTER JOIN -hoz plusz sorok
FROM alkalmazott X WHERE NOT EXISTS (SELECT * FROM alkalmazott Y WHERE X.a_kod = Y.fonok);
*** Hierarchikus lekérdezés Oracle-ben
Az Oracle lehetQvé teszi, hogy a táblákban kódolt hierarchikus adatokat a hierarchiának megfelelQ sorrendben lekérdezzük. Ez nem része a szabványnak.
SELECT ... [, LEVEL] ,...
FROM tábla1 [t_aliasnév1] [join_tábla2] ...
...
[ [START WITH feltétel]
CONNECT BY {PRIOR sql_kifejezés hasonlító_operátor sql_kifejezés
| sql_kifejezés hasonlító_operátor PRIOR sql_kifejezés}
[{AND | OR} egyéb_feltétel] ]
[ORDER SIBLINGS BY ... ];
START WITH: azon sorokat veszi kiinduló csomópontoknak, amelyre a feltétel igaz. Ha nincs megadva, az összes sort veszi.
CONNECT BY: specifikálja a kapcsolatot a szülQ és a gyerek sorok között, amely alapján a tábla sorait hierarchiába lehet kapcsolni. A PRIOR operátoros kifejezés reprezentálja a szülQt, elQször ez lesz kiértékelve a START WITH kiválasztott soraira, majd a másik oldali kifejezés és az egyéb feltételek a tábla összes sorára. Azon sorok lesznek a gyerek sorok, amelyekre a feltétel igaz. A gyereksorokra ez rekurzív módon folytatódik. A fabejárási irányt határozzuk meg ezáltal.
LEVEL: pszeudo oszlop, amely lehetQvé teszi annak a szintnek a lekérdezését, amelyen az egyes adatok a hierarchiában szerepelnek.
Végrehajtási sorrend: táblák joinja, hierarchia felépítése, WHERE szelekció, stb. ORDER SIBLINGS BY segítségével rendezhetjük egy-egy szinten a testvérsorokat (közös a szülQ).
-- Alkalmazottak fa-szerkezetq lekérdezése a gyökér felQl indulva.
-- (fQnök => beosztott irány) Pl. a_kod=1001 -es összes beosztottja:
SELECT LEVEL, a_nev, t_kod, beosztas, a_kod, fonok
FROM alkalmazott
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok;
-- ElQzQ feladat szépítve és szintenként névsorba rendezve:
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, t_kod, beosztas, a_kod, fonok
FROM alkalmazott
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok
ORDER SIBLINGS BY a_nev;
-- Több csomópontból indulva:
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, t_kod, beosztas, a_kod, fonok
FROM alkalmazott
START WITH beosztas = 'VEZETO' CONNECT BY PRIOR a_kod = fonok;
-- Levelek felQl indulva (beosztott => fQnök irány). Pl. a_kod=1007 -es összes fQnöke:
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, t_kod, beosztas, a_kod, fonok
FROM alkalmazott
START WITH a_kod ='1007' CONNECT BY a_kod = PRIOR fonok;
-- Szintenkénti létszám és átlagfizetés:
SELECT LEVEL, COUNT(*), AVG(fizetes) FROM alkalmazott
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok
GROUP BY LEVEL;
További tanulmányozásra alkalmas feladatok:
-- A WHERE feltétel a hierarchia felépítés után szelektál
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, A.t_kod, beosztas, a_kod, fonok, varos
FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod
WHERE beosztas <> 'VEZETO'
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok;
-- A CONNECT BY egyéb_feltétele a hierarchia felépítés közben fejti ki hatását
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, A.t_kod, beosztas, a_kod, fonok, varos
FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok AND beosztas <> 'VEZETO';
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, A.t_kod, beosztas, a_kod, fonok, varos
FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok AND varos = 'DEBRECEN';
-- Ha a hierarchia felépítés közben a rendszer hurkot észlel, akkor hibát jelez.
SELECT LEVEL, LPAD('-', 5*LEVEL, '-') || a_nev nev, A.t_kod, beosztas, a_kod, fonok, varos
FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod
START WITH a_kod ='1001' CONNECT BY PRIOR a_kod = fonok OR beosztas <> 'VEZETO';
Beágyazott SELECT
Az SQL nyelvben megengedett, hogy egy SELECT utasításban (vagy más SQL utasításban) allekérdezés (alselect) elQforduljon, az egymásba ágyazási mélység maximálva van (Oracle9i-ben max. 255). A legtöbb esetben zárójelbe kell tenni. Típusai: egyszerq és korrelált (vagy kapcsolt) típus.
Egyszerq típus: a belsQ SELECT önmagában is kiértékelhetQ és belülrQl kifelé haladva lesznek a lekérdezések feldolgozva. A kiértékelés menete:
a belsQ SELECT egyszer kiértékelQdik és egy, vagy több sort vagy oszlopértéket átad a külsQ SELECT-nek,
a külsQ SELECT ezen értékek alapján összeállítja az eredményt.
Korrelált (kapcsolt) típus: a belsQ SELECT olyan, a külsQ SELECT-beli oszlopra történQ hivatkozást tartalmaz, amely miatt a belsQ önmagában nem kiértékelhetQ. A kiértékelés menete:
a külsQ SELECT átad egy sort (vagy annak oszlopait) a belsQnek,
a belsQ SELECT így már kiértékelhetQ, visszaadja az eredménysort vagy sorokat,
a külsQ SELECT elvégzi a további értékelést.
Ez ismétlQdik a külsQ SELECT minden sorára, míg összeáll az eredmény. Tehát egy ciklus van elrejtve
az utasításban, ami miatt idQigényesebb lehet a végrehajtása.
Amennyiben a külsQ és a belsQ SELECT is ugyanazt a táblát használja, a belsQ SELECT csak aliasnévvel tud a külsQ SELECT táblájára hivatkozni.
Hol használhatunk alselectet:
SELECT több szintaktikus egységében vagy záradékában:
WHERE feltételben, HAVING feltételben, START WITH feltételben,
FROM záradékban, tábla helyett (Inline View),
skalár értéket adó alselect (a legtöbb implementációban) használható szinte minden olyan helyen, ahol a szintaxisban sql_kifejezés szerepel, sQt még mqvelet is végezhetQ vele.
Más SQL utasításokban: INSERT, DELETE, UPDATE, CREATE TABLE, CREATE VIEW,
CREATE MATERIALIZED VIEW
Alselect feltételekben:
Mindig zárójelbe kell tenni. Korrelált is lehet. (A korábbi verziókban alselect csak a hasonlító operátor jobb oldalán állhatott, jelenleg nincs ilyen megkötés.)
Egyszerq feltételben csak skalár értéket adó alselect lehet, amely pontosan egy sort és abból is egy oszlopot ad vissza, azaz egy skalár érték lesz az eredmény. Ha nincs visszaadott sor, akkor értéke NULL. Ha több sort vagy több oszlopot ad vissza, akkor hibát jelez a rendszer.
sql_kifejezés relációs_operátor (skalár_értéket_adó_alselect)
Teljesül-e a reláció ( =, !=, <>, <, >, <=, >= ) ?
"Halmazos" feltételben lévQ alselect több sort és abból egy vagy több oszlopot is visszaadhat, vagy egyetlen sort sem ad vissza. Itt a halmazt az alselect adja és nem egy konstanslista.
[NOT] EXISTS (alselect_akárhány_oszloppal)
Az alselect visszaad-e legalább egy sort? True vagy False az eredmény.
sql_kifejezés [NOT] IN (alselect_egy_oszloppal)
A megadott halmazban szerepel-e az sql_kifejezés értéke? ElQfordulás vizsgálat.
sql_kifejezés relációs_operátor {ANY | SOME} (alselect_egy_oszloppal)
Teljesül-e a reláció a halmaz valamely (legalább egy) elemére?
sql_kifejezés relációs_operátor ALL (alselect_egy_oszloppal)
Teljesül-e a reláció a halmaz minden egyes (összes) elemére?
(sql_kifejezés ,...) egyezés_vizsgáló_operátor (alselect_a_kifejezéslistával_egyezQ_számú_oszloppal)
Egyezik (nem egyezik) az sql_kifejezéslista értéksora a halmazban lévQ értéksorok
valamelyikével vagy mindegyikével? ( [NOT] IN, =ANY, <>ANY, =ALL, <>ALL )
Példák nem korrelált alselectre:
-- Azon alkalmazottak, akiknek fizetése megegyezik a_kod=1006 alkalmazott fizetésével:
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes = (SELECT fizetes FROM alkalmazott WHERE a_kod ='1006');
-- Az a_kod=9999 nem létezQ alkalmazott: alselect NULL értéket ad vissza,
-- a feltétel értéke mindig ismeretlen lesz => nincs visszaadott sor:
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes = (SELECT fizetes FROM alkalmazott WHERE a_kod ='9999');
-- Azon alkalmazottak, akiknek fizetése nagyobb az összes alkalmazott átlagfizetéstQl:
SELECT * FROM alkalmazott
WHERE fizetes > (SELECT AVG(fizetes) FROM alkalmazott);
-- Azon alkalmazottak, akik legkésQbb léptek be:
SELECT * FROM alkalmazott
WHERE belepes = (SELECT MAX(belepes) FROM alkalmazott);
-- Azon alkalmazottak, akik fizetése egyezik a 30-as telephelyen dolgozók
-- valamelyikének a fizetésével:
SELECT a_kod, a_nev, fizetes, t_kod FROM alkalmazott
WHERE fizetes IN (SELECT DISTINCT fizetes FROM alkalmazott WHERE t_kod ='30');
-- Azon alkalmazottak, akik fizetése nagyobb a 30-as telephelyen dolgozók
-- fizetésének mindegyikénél:
SELECT a_kod, a_nev, fizetes, t_kod FROM alkalmazott
WHERE fizetes > ALL (SELECT DISTINCT fizetes FROM alkalmazott WHERE t_kod ='30');
SELECT a_kod, a_nev, fizetes, t_kod FROM alkalmazott
WHERE fizetes > (SELECT MAX(fizetes) FROM alkalmazott WHERE t_kod ='30');
-- Azon alkalmazottak, akiknél a beosztas, fizetes értékpár elQfordul egy értékpárokkal
-- megadott halmazban, melyet az alselect szolgáltat:
SELECT a_kod, a_nev, beosztas, fizetes, t_kod FROM alkalmazott
WHERE (beosztas, fizetes) IN
(SELECT beosztas, fizetes FROM alkalmazott WHERE t_kod ='40');
-- Határozzuk meg az alkalmazottak telephelyenkénti csoportjaira a létszámot,
-- a fizetések összegét, és az átlagfizetést egészre kerekítve. Csak azon csoportokat
-- írassuk ki, ahol az átlagfizetés nagyobb mint az összes dolgozó átlagfizetése:
SELECT t_kod, COUNT(*) létszám, SUM(fizetes) összeg, ROUND(AVG(fizetes)) átlag
FROM alkalmazott
GROUP BY t_kod
HAVING AVG(fizetes) > (SELECT AVG(fizetes) FROM alkalmazott);
Példák korrelált alselectre: (Néhányhoz adható nem korreláltos megoldás is.)
-- Azon telephelyek, amelyeken még nincs alkalmazott.
-- Továbbfejlesztés: azon telephelyek, amelyeken van alkalmazott.
-- ( Elméletben félig anti-összekapcsolásnak (antisemijoin) ill.
-- félig összekapcsolásnak (semijoin) nevezik ezeket.)
SELECT * FROM telephely T
WHERE NOT EXISTS (SELECT * FROM alkalmazott WHERE T.t_kod = t_kod);
SELECT * FROM telephely
WHERE t_kod NOT IN (SELECT DISTINCT t_kod FROM alkalmazott);
-- Azon alkalmazottak, akik fizetése nagyobb az azonos telephelyen dolgozók
-- átlagfizetésétQl.
-- Analóg feladat: Azon alkalmazottak, akik fizetése kisebb a velük azonos beosztásúak
-- átlagfizetésétQl.
SELECT * FROM alkalmazott X
WHERE fizetes > (SELECT AVG(fizetes) FROM alkalmazott WHERE t_kod = X.t_kod);
SELECT * FROM alkalmazott X
WHERE fizetes > (SELECT AVG(fizetes) FROM alkalmazott
GROUP BY t_kod HAVING t_kod = X.t_kod);
-- A legkisebb fizetésq alkalmazott(ak) beosztásonként.
-- Miért nem jelenik meg a NULL beosztás?
-- Analóg feladat: A legkésQbb belépett alkalmazott(ak) telephelyenként.
SELECT * FROM alkalmazott X
WHERE fizetes = (SELECT MIN(fizetes) FROM alkalmazott WHERE beosztas = X.beosztas);
SELECT * FROM alkalmazott
WHERE (beosztas, fizetes) IN (SELECT beosztas, MIN(fizetes)
FROM alkalmazott GROUP BY beosztas);
-- Megoldandó alselecttel vagy joinnal:
-- Készítsünk listát azon alkalmazottakról, akik telephelyének városa nem BUDAPEST!
Haladó:
-- A legalacsonyabb átlagfizetésq beosztás, a NULL beosztásúakat hagyjuk ki:
-- Mi lenne az eredmény, ha a NULL beosztásúakkal is dolgozunk?
SELECT beosztas, AVG(fizetes) FROM alkalmazott
WHERE beosztas IS NOT NULL
GROUP BY beosztas
HAVING AVG(fizetes) = (SELECT MIN(AVG(fizetes)) FROM alkalmazott
WHERE beosztas IS NOT NULL GROUP BY beosztas);
A kifejezéslistával vagy alselecttel elQállított halmazok tartalmazhatnak NULL értéket is. A kiértékeléshez a halmazos összehasonlító operátorokat alkotó kifejezések át vannak alakítva:
IN, relációs_operátor ANY -- OR-al összekapcsolt egyszerq feltételek sorozata
NOT IN, relációs_operátor ALL -- AND-el összekapcsolt egyszerq feltételek sorozata
Így az igazságtábla alapján nem meglepQek a következQ eredmények:
1 IN (1, NULL) => True (mert: 1=1 OR 1=NULL => True)
1 NOT IN (2, NULL) => Unknown (mert: 1<>2 AND 1<>NULL => Unknown)
1 IN (alselect_mely_nem_ad_vissza_sort) => False (mert üres az alselect eredménytáblája!)
1 NOT IN (alselect_mely_nem_ad_vissza_sort) => True (mert üres az alselect eredménytáblája!)
x >= (SELECT MAX(y) FROM t) és az x >= ALL (SELECT y FROM t) feltételek
nem mindig azonosak, mert a MAX(y) a NULL-t kihagyja, a másik nem.
-- Azon alkalmazottak, akik nem fQnökök (nincs beosztottjuk):
-- Analóg feladat: Azon alkalmazottak, akik valamilyen szinten fQnökök.
-- Az elsQ megoldás alselectjébe miért kell a WHERE fonok IS NOT NULL záradék?
SELECT * FROM alkalmazott
WHERE a_kod NOT IN (SELECT DISTINCT fonok FROM alkalmazott WHERE fonok IS NOT NULL);
SELECT * FROM alkalmazott X
WHERE NOT EXISTS (SELECT * FROM alkalmazott WHERE X.a_kod=fonok);
-- Alselect_mely_nem_ad_vissza_sort: mi lesz az eredmény?
SELECT * FROM telephely WHERE t_kod IN (SELECT t_kod FROM alkalmazott WHERE 1 = 2);
SELECT * FROM telephely WHERE t_kod NOT IN (SELECT t_kod FROM alkalmazott WHERE 1 = 2);
-- Megoldandó:
-- 1. A korábbi korrelált és nem korrelált feladatsorban elsQsorban a fizetéssel dolgoztunk,
-- ami NOT NULL. Fogalmazzuk át a feladatokat prémiumra és oldjuk meg azokat.
-- Mi lehet a legkézenfekvQbb megoldás?
Újabban a skalár_értéket_adó_alselect a legtöbb SQL utasításban használható, ahol sql_kifejezés áll a szintaxisban, sQt még mqvelet is végezhetQ vele:
-- Írassuk ki az alkalmazottak néhány adatát, valamint az alkalmazottal azonos
-- beosztásúak átlagfizetésébQl számolt értéket kerekítve:
SELECT a_kod, a_nev, beosztas, fizetes, ROUND(( SELECT AVG(fizetes) FROM alkalmazott
WHERE X.beosztas = beosztas) + 1000) AS "Csop fiz + 1000"
FROM alkalmazott X;
Inline View - utasításban elhelyezett nézettábla (virtuális tábla):
Az újabb verziókban a SELECT utasításban a tábla helyén állhat zárójelbe tett, nem korrelált alselect, melyet tábla aliasnévvel célszerq ellátni. Az utasításban ezzel az aliasnévvel hivatkozhatunk az alselect eredménytáblájára. Ha az alselect SELECT listája kifejezést tartalmaz, akkor oszlop aliasnévvel kell ellátni, mely az alselect eredménytáblájának oszlopnevét adja. Tehát hasonlóan definiáljuk és használjuk mint egy nézettáblát. (Nézettábla: nem valódi, virtuális tábla, lásd a CREATE VIEW utasítást.) Ez újabb típusú feladatok megoldására és más megoldások kialakítására ad lehetQséget. (Megjegyzés: Inline View nemcsak a SELECT-ben szerepelhet a tábla helyett, hanem az INSERT, DELETE, UPDATE utasításokban is.)
-- Azon alkalmazottak, akik fizetése több mint a velük azonos beosztásúak átlagfizetése.
-- Írassuk ki az azonos beosztásúak átlagfizetését is:
SELECT a_kod, a_nev, X.beosztas, fizetes, cs_atlag
FROM alkalmazott X JOIN (SELECT beosztas, AVG(fizetes) cs_atlag FROM alkalmazott
GROUP BY beosztas) CS
ON X.beosztas = CS.beosztas AND fizetes > cs_atlag;
-- *** Írassuk ki, hogy egy-egy telephelyen dolgozó csoportok létszáma és fizetése
-- hány %-át teszi ki az összes alkalmazott létszámának és fizetésének:
SELECT A.t_kod "Telephely", (A.csop_szam / B.ossz_szam) * 100 AS "% létszám",
(A.csop_fiz / B.ossz_fiz) * 100 AS "% fizetés"
FROM (SELECT t_kod, COUNT(*) csop_szam, SUM(fizetes) csop_fiz
FROM alkalmazott GROUP BY t_kod) A,
(SELECT COUNT(*) ossz_szam, SUM(fizetes) ossz_fiz
FROM alkalmazott) B;
Oracle Pszeudo oszlop: nincs a táblában tárolva, úgy viselkedik mint egy normál oszlop, a rendszer határozza meg az értékét: ROWID -- a tábla sorának fizikai tárolási címe, a sorok belsQ azonosítója.
ROWNUM -- SQL utasításoknál a tábla sorának a DB-bQl való kiolvasási sorszáma (1, 2, stb.).
Úgynevezett Top-N (elsQ N darab legkisebb/legnagyobb) lekérdezés készíthetQ a ROWNUM és az Inline View segítségével.
-- Alkalmazottak adatai és az elérhetQ pszeudo oszlopok:
SELECT ROWNUM, ROWID,a_kod, a_nev, fizetes FROM alkalmazott;
-- Csak a ROWNUM szerinti elsQ 3 alkalmazottat írjuk ki:
SELECT ROWNUM, a_kod, a_nev, fizetes FROM alkalmazott WHERE ROWNUM <= 3;
-- Legyünk óvatosak: a következQ nem ad vissza sort (a feltétel soha nem lesz igaz):
SELECT ROWNUM, a_kod, a_nev, fizetes FROM alkalmazott WHERE ROWNUM > 1;
-- Rendezés után már nem biztos, hogy ROWNUM növekvQleg vannak a sorok:
SELECT ROWNUM, a_kod, a_nev, fizetes FROM alkalmazott
ORDER BY fizetes;
*** Top-N lekérdezések megoldása: használjunk tábla helyett alselectet (Inline View), mely rendez. Ekkor a virtuális tábla rendezett sorai lesznek beszámozva a ROWNUM-al (1, 2, stb.).
-- Írassuk ki az elsQ 3 legkisebb különbözQ fizetést:
SELECT fizetes FROM (SELECT DISTINCT fizetes FROM alkalmazott ORDER BY fizetes)
WHERE ROWNUM <= 3;
-- Az elsQ 3 legkisebb fizetéssel rendelkezQ alkalmazott:
-- (3-nál több is lehet: mintapélda alapján az 50000, 60000, 90000 fizetésqek.)
SELECT a_kod, a_nev, fizetes FROM alkalmazott
WHERE fizetes IN (SELECT fizetes
FROM (SELECT DISTINCT fizetes FROM alkalmazott ORDER BY fizetes)
WHERE ROWNUM <= 3);
SELECT a_kod, a_nev, X.fizetes
FROM (SELECT fizetes FROM (SELECT DISTINCT fizetes FROM alkalmazott ORDER BY fizetes)
WHERE ROWNUM <= 3) X JOIN alkalmazott Y ON Y.fizetes=X.fizetes;
-- ElözQ feladat Inline View nélküli megoldásai:
-- Alapgondolat: Akik fizetésétQl >= különbözQ fizetésq alkalmazottak száma <=3.
SELECT a_kod, a_nev, fizetes FROM alkalmazott X
WHERE 3 >= (SELECT COUNT(DISTINCT fizetes) FROM alkalmazott WHERE X.fizetes >= fizetes);
SELECT X.a_kod, X.a_nev, X.fizetes
FROM alkalmazott X JOIN alkalmazott Y ON X.fizetes >= Y.fizetes
GROUP BY X.a_kod, X.a_nev, X.fizetes HAVING COUNT(DISTINCT Y.fizetes)<=3;
*** Táblák (relációk) osztása: nincs megvalósítva az SQL szabványban és az Oracle-ben sem. Az eddigi lehetQségekkel kell megoldani a táblák osztását. Két erre alkalmas táblán mutatunk be egy-két megoldást.
-- Pilóták repülQgéptípushoz tartozó jogosítványait tartalmazó tábla
CREATE TABLE pilota_jogsi
(pilota VARCHAR2(10), gep VARCHAR2(10), PRIMARY KEY (pilota, gep));
-- Hangárban lévQ repülQgéptípusok
CREATE TABLE hangar (gep VARCHAR2(10) PRIMARY KEY );
-- Adatokkal feltöltés
INSERT INTO pilota_jogsi VALUES ('p1', 'F-17');
INSERT INTO pilota_jogsi VALUES ('p2', 'B-52');
INSERT INTO pilota_jogsi VALUES ('p3', 'B-52');
INSERT INTO pilota_jogsi VALUES ('p3', 'F-14');
INSERT INTO pilota_jogsi VALUES ('p4', 'B-52');
INSERT INTO pilota_jogsi VALUES ('p4', 'F-14');
INSERT INTO pilota_jogsi VALUES ('p4', 'F-17');
INSERT INTO hangar VALUES ('B-52');
INSERT INTO hangar VALUES ('F-14');
Feladat: Határozzuk meg azon pilótákat, akik a hangárban lévQ összes géppel képesek felszállni.
Maradékos osztás: a pilótának több géphez is lehet jogsija, mint amennyi gép a hangárban van.
pilota_jogsi maradékos_osztás hangar => (p3), (p4)
Pontos osztás: a pilótának pontosan annyi jogsija van, mint amennyi gép a hangárban van.
pilota_jogsi pontos_osztás hangar => (p3)
-- Maradékos osztás: NOT EXISTS-ek egymásba ágyazásával
-- Pilóták, akikhez egyetlen olyan gép sincs a hangárban, amelyet ne tudna vezetni.
SELECT DISTINCT pilota FROM pilota_jogsi P1
WHERE NOT EXISTS (SELECT * FROM hangar H WHERE NOT EXISTS
(SELECT * FROM pilota_jogsi P2
WHERE P1.pilota = P2.pilota AND P2.gep=H.gep));
-- Maradékos osztás: NOT EXISTS és halmazmqveletes alselect.
-- Vonjuk le a hangárban lévQ gépekbQl azokat, amelyeket a pilóta tud vezetni.
SELECT DISTINCT pilota FROM pilota_jogsi P1
WHERE NOT EXISTS (SELECT gep FROM hangar MINUS
SELECT gep FROM pilota_jogsi P2 WHERE P1.pilota = P2.pilota );
-- Maradékos osztás: táblákra JOIN, GROUP BY, HAVING-el keresett számosságú csoportok
SELECT P.pilota FROM pilota_jogsi P JOIN hangar H ON P.gep=H.gep
GROUP BY P.pilota
HAVING COUNT(P.gep)=(SELECT COUNT(gep) FROM hangar);
-- Pontos osztás: táblákra LEFT JOIN, GROUP BY, HAVING-el keresett számosságú csoportok
SELECT P.pilota FROM pilota_jogsi P LEFT JOIN hangar H ON P.gep=H.gep
GROUP BY P.pilota
HAVING COUNT(P.gep)=(SELECT COUNT(gep) FROM hangar)
AND COUNT(H.gep)=(SELECT COUNT(gep) FROM hangar);
Továbbfejlesztés-1: több (h1, h2,...) hangár van:
PILOTA_JOGSI (pilota, gep) HANGAR_TART(hangar, gep)
Határozzuk meg azon pilóta, hangár párokat, amelyekre igaz, hogy
a pilóta tudja vezetni a hangárban lévQ gépek bármelyikét.
a pilóta tudja vezetni a hangárban lévQ gépek valamelyikét.
Továbbfejlesztés-2: több hangár van és a pilóták is be lehetnek osztva hangárokhoz:
PILOTA_JOGSI (pilota, gep) HANGAR_TART(hangar, gep) BEOSZTAS(pilota, hangar)
Kik azok a pilóták, akiknek olyan a hangárbeosztása, hogy
bármely hangárban lévQ gépek bármelyikét tudja vezetni. (vagy: egyikét sem tudja vezetni.)
bármely hangárban van olyan gép, melyet tud vezetni. (vagy: melyet nem tud vezetni.)
van olyan hangár, amelyben lévQ gépek bármelyikét tudja vezetni. (vagy: egyikét sem tudja vezetni.)
van olyan hangár, amelyben lévQ gépek valamelyikét tudja vezetni. (vagy: valamelyikét nem tudja vezetni.)
DDL ( Adatdefiníciós nyelv )
Miután megterveztük egy információs rendszer relációs adatmodellbeli sémáját, azt az SQL DDL utasításokkal implementáljuk, majd a rendszer üzemeltetése, müködtetése során a sémán korlátozott mértékben változtatásokat hajthatunk végre, vagy egyes elemeket törölhetünk.
DDL utasítások: az adatbázis és az adatbázis-objektumok (sémaelemek)
definiálása (létrehozása) - CREATE, törlése - DROP,
definíciók módosítása - ALTER, átnevezése - RENAME.
AlapvetQ SQL szabványos relációs adatbázis-objektumok:
Tábla - TABLE: a felhasználói adatok tárolására szolgál, sorokból és oszlopokból áll.
Nézettábla -VIEW: más táblákból, nézettáblákból levezetett virtuális tábla. Adatokat nem tárol.
Index - INDEX: lekérdezéseket gyorsító objektum, karbantartásuk idQigényes.
Szinonima - SYNONYM: objektumok alternatív neve.
Haladó: További SQL szabványos vagy Oracle adatbázis-objektumok:
Szekvencia - SEQUENCE: egyedi értéket generáló objektum Oracle-ben.
Materializált nézettábla (pillanatfelvétel): MATERIALIZED VIEW : más táblákból, nézettáblákból származtatott adatok tárolására szolgáló tábla. Az adatok frissítése állítható.
Programegységek: függvények (FUNCTION), eljárások (PROCEDURE), csomagok (PACKAGE), triggerek (TRIGGER), melyek PL/SQL vagy Java procedurális nyelven készülnek.
Objektumrelációs kiterjesztés: Felhasználó által definiált típusok (kollekciótípus, objektumtípus attribútumokkal és metódusokkal) és mqveletek: TYPE, OPERATOR.
Felhasználók és a jogosultságaik kezelése: USER, PROFILE, SCHEMA, ROLE, stb.
Adatbázis és a logikai szerkezet kialakítása: DATABASE, TABLESPACE, DATABASE LINK, stb.
Mqködési egységek paramétereinek kezelése: SYSTEM (rendszer), SESSION (felhasználó munkamenete), stb.
Minden objektum definíciója a DD-ben tárolódik. Egyes objektumok (TABLE, INDEX, MATERIALIZED VIEW) adatok tárolására szolgálnak, így létrehozásuknál tárolási elQírások is megadhatók, melyeket itt nem részletezünk, mivel ezek nem részei az SQL szabványnak, továbbá ismerni kellene hozzá az Oracle belsQ tárolási mechanizmusát.
Objektumok azonosítói: max. 30 hosszúak, betqvel kell, hogy kezdQdjenek és A-Z, 0-9, _, #, $ karaktereket tartalmazhatnak. Kis- és nagybetq között nem tesz különbséget a rendszer. Nem lehet objektumnévként használni az SQL utasításokban használt kulcsszavakat és az Oracle Szerver fenntartott szavait
Séma (SCHEMA): Objektumok névvel ellátott gyqjteménye. Oracle-ben a felhasználó létrehozásakor (CREATE USER) a felhasználóhoz automatikusan létrejön egy séma-objektum, amely a felhasználó által definiált adatbázis objektumokat foglalja magába. Oracle-ben a séma neve azonos a felhasználói névvel, Q a tulajdonosa a sémában lévQ objektumoknak és ezekkel az objektumokkal bármit csinálhat. Egy séma két azonos típusú objektumának a neve nem lehet ugyanaz.
Az objektumok létrehozásához megfelelQ rendszerjogokkal (privilégium) kell rendelkezni. Akinek van olyan rendszerjoga még más sémájában is definiálhat objektumokat, vagy ha rendelkezik a megfelelQ objektum-hozzáférési jogokkal, akkor használhat más sémájában lévQ objektumokat. Az utasításokban explicit módon meg kell adni a séma nevét, ha nem a saját sémánkban lévQ objektumra hivatkozunk. Hasonló mondható el osztott adatbázisok esetén: ha van hozzá jogunk, akkor használhatunk másik adatbázisban lévQ objektumokat.
Objektumhivatkozás formája: [séma.]objektumnév[@db_link]
séma: séma neve. Ha elmarad, akkor a felhasználó (aki bejelentkezett a rendszerbe) saját sémájában lévQ objektumra hivatkozik.
db_link: adatbázis kapcsolati azonosító, a távoli adatbázisra való hivatkozást adja. Ha elmarad, akkor a lokális adatbázisban lévQ (amelyik adatbázisba elQször bejelentkezett) objektumra van hivatkozás. (A db_link a CREATE DATABASE LINK utasítással definiálandó.)
-- KISS felhasználó sémájában lévQ tábla lekérdezése a helyi adatbázisban
-- (ha van hozzá jogunk):
SELECT * FROM kiss.telephely;
-- Az ORACLE.OKTATAS.BUDAPEST.HU adatbázisban, KISS felhasználó sémájában
-- lévQ tábla lekérdezése (ha van hozzá jogunk):
SELECT * FROM kiss.telephely@oracle.oktatas.budapest.hu;
Szinonima: objektumok, hosszú objektumhivatkozások alternatív neve.
Létrehozása:
CREATE [PUBLIC] SYNONYM szinonima_név FOR objektum_hivatkozás;
Törlése: DROP SYNONYM szinonima_név;
-- Szinonima definiálása
CREATE SYNONYM teleph FOR HYPERLINK mailto:nagy.telephely@oktatas.budapest.com; kiss.telephely@oracle.oktatas.budapest.hu;
-- Szinonima használatával kérdezzük le a távoli adatbázis tábláját
SELECT * FROM teleph;
Megtehetjük például azt, hogy szinonimát használva írjuk az SQL utasításokat, és szükség esetén csak a szinonima definícióját változtatjuk. Osztott adatbázisok esetén, megfelelQ szinonimák kialakításával a felhasználók és a fejlesztQk úgy érzékelhetik, mintha az objektumok egyetlen adatbázisban lennének (nem kell tudni, hogy melyik objektum hol található, kinek a tulajdonában van).
Adatszótár (DD: Data Dictionary)
Táblák és nézettáblák gyqjteménye, az adatbázis-objektumok definícióinak tárolására szolgálnak. Ezen rendszertáblák az adatbázis létrehozásakor jönnek létre, a rendszer tartja karban, a felhasználók csak olvashatják. Az Oracle-ben a DD táblák tulajdonosa a SYS nevq DBA felhasználó, a többi felhasználó a DD nézettábláit használja.
Oracle-ben a több mint 1000 db. DD tábla és nézettábla elnevezéseiben prefixek segítik az eligazodást:
USER_ azon objektumok, amelyeknek a felhasználó a tulajdonosa.
(Pl. USER_OBJECTS, USER_TABLES; vagy ezek rövidítései: OBJ, TABS)
ALL_ azon objektumok, amelyekhez a felhasználónak hozzáférési jogosultsága van,
de azok más tulajdonában is lehetnek. (Pl. ALL_OBJECTS, ALL_TABLES)
DBA_ az adatbázisban lévQ összes objektum, SELECT ANY TABLE jog kell hozzá.
(Pl. DBA_OBJECTS, DBA_TABLES)
egyéb DICTIONARY vagy DICT - elérhetQ DD táblák, nézettáblák neve és leírása
V$VERSION - adatbázis-kezelQ szoftver verziója
GLOBAL_NAME - adatbázis globális neve
NLS_DATABASE_PARAMETERS - adatbázis permanens NLS paraméterei
NLS_SESSION_PARAMETERS - munkamenet nyelvi (NLS) beállításai
SESSION_PRIVS - munkamenethez rendelt rendszerjogok (Privilege)
-- Néhány DD tábla lekérdezése
SELECT * FROM V$VERSION;
SELECT * FROM GLOBAL_NAME;
SELECT * FROM NLS_SESSION_PARAMETERS;
SELECT * FROM SESSION_PRIVS;
SELECT * FROM USER_OBJECTS;
SELECT * FROM USER_TABLES;
-- Egy konkrét objektum definícióját lekérdezQ [i]SQL*Plus parancs
DESCRIBE alkalmazott
*** Haladó: A fejezethez kapcsolódó DD táblák, prefix: USER_ vagy ALL_ vagy DBA_
A felhasználó sémájában lévQ objektumok definícióit tartalmazó DD táblák:
USER_OBJECTS vagy OBJ -- összes objektum
USER_TABLES vagy TABS -- táblák
USER_TAB_COLUMNS vagy COLS -- táblák oszlopai
USER_CONSTRAINTS -- megszorítások
USER_INDEXES vagy IND -- indexek
USER_IND_COLUMNS -- indexek kulcsait alkotó oszlopok
USER_VIEWS -- nézettáblák
(van egy LONG típusú oszlopa, [i]SQL*Plus ne csak 80 karaktert írjon ki: SET LONG 4000 )
USER_MVIEWS -- materializált nézettáblák
USER_SEQUENCES vagy SEQ -- szekvenciák
USER_SYNONYMS vagy SYN -- szinonimák
USER_TAB_COMMENTS -- megjegyzések táblákhoz
USER_COL_COMMENTS -- megjegyzések tábla oszlopokhoz
USER_CLUSTERS -- klaszterek
USER_TAB_PARTITIONS -- táblák partíciói
USER_IND_PARTITIONS -- indexek partíciói
Tábla létrehozása, módosítása, törlése, integritási megszorítások
Tábla létrehozása: meg kell adni a tábla oszlopainak nevét, típusát és az integritási megszorításokat. Példaként lásd a mintatáblákat létrehozó CREATE TABLE utasításokat.
CREATE TABLE táblanév
( {oszlopnév típus [(méret)] [DEFAULT sql_kifejezés] [oszlopmegszorítás ...] },
[ táblamegszorítás] ,& )
[tárolási és egyéb elQírások]
[AS alselect];
típus [(méret)]: az oszlop adattípusa. Az oszlop értékeinek meg kell felelni az oszlop adattípusának és az értéktartományba kell esni. Az Oracle elQredefiniált, beépített (Built-in) adattípusai és értéktartományok:
CHAR[(m)] Fix hosszú karaktersor, 1<=m<=2000, default érték: 1.
Szóközzel egészíti ki a megadott méretre.
VARCHAR2(m) Változó hosszú karaktersor, 1<=m<=4000, méret megadása kötelezQ. Szóközzel nem
VARCHAR(m) egészíti ki a megadott méretre. (VARCHAR szemantikája a jövQben változni fog!)
CHAR esetén: 'A '='A' igaz;
VARCHAR2 esetén: 'A '='A' hamis, de 'A '>'A' igaz.
NUMBER[(p [,s])] Egész és valós számok, értéktartomány: 1E-130 .. 1E127,
de csak maximum 38 decimális jegy precizitással (pontossággal) tud tárolni.
NUMBER - lebegQpontos valós számok, p=38 decimális jegy precizitással.
NUMBER(p), NUMBER(p, s) - fixpontos egész és valós számok:
p: precizitás, összes decimális számjegyek száma: 1<=p<=38
s: skálatényezQ: -84<=s<=127, default érték: 0.
Ha s>=0, akkor a tizedesponttól jobbra esQ jegyek számát adja, azaz ennyi tizedesjegyre kerekíti a tároláshoz megadott adatokat.
Ha s<0, akkor a tizedesponttól balra az s-dik jegyre lesz kerekítve a kezelt érték.
DATE Dátum és idQ (év, hónap, nap, óra, perc, másodperc): idQszámítás elQtti 4712. január 1. és idQszámítás szerinti 9999. december 31. közötti tartományban.
** Egyéb TIMESTAMP - idQbélyeg, a dátum és idQ kiegészítve a másodperc törtrészével.
RAW - bináris adatok, max. 4000 byte.
LONG ill. LONG RAW - hosszú karakteres ill. bináris adatok, max. 2Gbyte.
CLOB ill. BLOB - (Large Object) multimédiás adatok, max. 4Gbyte.
** Egyes más adattípusok az SQL szabvánnyal vagy más DBMS-el való kompatibilitás miatt vannak:
CHARACTER(m) azonos CHAR(m)
CHARACTER VARYNG(m) azonos VARCHAR2(m)
INTEGER azonos NUMBER(38)
REAL, FLOAT azonos NUMBER
NUMERIC(p,s), DECIMAL(p,s) azonos NUMBER(p,s)
DEFAULT sql_kifejezés: alapértelmezett érték az oszlop számára, amelyet az INSERT-nél akkor kap meg, ha az oszlop nem kap explicit értéket. De a DEFAULT kulcsszóval is hivatkozhatunk rá az INSERT, UPDATE utasításokban. Az sql_kifejezésben itt csak konstansok és argumentum nélküli függvényhívások (SYSDATE, USER, ...) lehetnek.
AS alselect: tábla definiálása és adatokkal feltöltése egy létezQ tábla alapján. Az oszlopdefinícó ekkor el is maradhat, mert azokat az alselect szolgáltathatja: az alselectbQl oszlopnév, típus, méret és a NOT NULL megszorítás kerül át az új táblába. De elQírhatók az új táblára új oszlopnevek, default értékek és megszorítások, azonban oszlop típus és külsQ kulcs megszorítás itt nem adható meg, ezek ALTER TABLE -ben adhatók meg.
-- Tábla definiálása és adatokkal feltöltése
CREATE TABLE telep1
AS SELECT t_nev, varos FROM telephely WHERE t_kod < 30;
-- Tábla definiálása, sorok átkerülése letiltva
CREATE TABLE telep2
AS SELECT t_nev, varos FROM telephely WHERE 1 = 2;
-- Táblák létrejöttének ellenQrzése:
SELECT * FROM telep1;
SELECT * FROM telep2;
DESCRIBE telep1
-- Táblák törlése
DROP TABLE telep1;
DROP TABLE telep2;
Integritási megszorítások (CONSTRAINT): Szabályok, melyek biztosítják az adatbázis konzisztenciáját (használható legyen az adatbázis, logikai ellentmondásokat ne tartalmazzon). Az elQírt szabályok betartását az RDBMS automatikusan biztosítja: nem enged meg olyan adatbázis mqveleteket, amelyek révén az adatok a szabályokat megszegnék.
Haladó megjegyzés: Ha egy üzleti, vagy mqködési szabályt nem tudunk leírni a DDL lehetQségeivel, akkor az alkalmazás fejlesztésénél kell annak betartásáról gondoskodni, de erre ad lehetQséget az SQL szabványos TRIGGER is. (Trigger = elsüt, kivált.) A TRIGGER-ek speciális, adatbázisban tárolt programok, amelyek megadott tábla vagy nézettábla karbantartó (INSERT, DELETE, UPDATE) utasításainak végrehajtása elQtt vagy után vagy helyett automatikusan aktivizálódnak és módosíthatják, kiegészíthetik azok hatását, összetett ellenQrzések végeztethetQk el segítségükkel. Van utasításonként egyszer végrehajtandó utasítás szintq trigger, és a soronként végrehajtandó sor szintq trigger.
Egy megszorítás a szintaktikai elhelyezése szerint lehet oszlop vagy tábla szintq: Az egy oszlopot érintQ megszorításokat megadhatjuk közvetlenül az oszlop definíciója után (vesszQt nem kell tenni közéjük), míg a több oszlopot érintQ megszorításokat (pl. összetett kulcsok, több oszlop összehasonlítása) csak tábla szintq megszorításként írhatjuk elQ (vesszQvel elválasztott önálló tétel).
Megszorítások általános alakja:
[CONSTRAINT megszorításnév] megszorítás [megszorítás_állapot ...]
megszorításnév: azonosítja a megszorítást. Ha nem adunk meg nevet, akkor a rendszer generál egy azonosító nevet SYS_Cn formátumban. Hibajelzésekben jelenik meg ez a név, valamint az ALTER TABLE utasításban használhatjuk.
megszorítás_állapot: a megszorítási szabály mqködtetéséhez kapcsolódó jellemzQ. Például be- vagy kikapcsolt (ENABLE, DISABLE) állapot. Alaphelyzetben a megszorítások be vannak kapcsolva (ENABLE).
megszorítás:
[NOT] NULL - az oszlopba kerülhet-e NULL érték, az oszlopnak kötelezQ-e értéket adni? Csak oszlop szinten írható elQ. Alapértelmezés: NULL megengedett.
UNIQUE(oszlop ,...) -egyedi kulcs megszorítás. Egy vagy több oszlop alkothatja. Értékének (több oszlop esetén azok összevont értékének) egyedinek kell lenni. Lehet NULL értékq, összetett kulcs esetén bármelyik része. Egy táblának több egyedi kulcsa lehet.
PRIMARY KEY(oszlop ,...) - elsQdleges kulcs megszorítás. (UNIQUE + NOT NULL)
Az oszlop(ok)ban szereplQ értékek a tábla sorait egyértelmqen azonosítják. Egy vagy több oszlop alkothatja. Értékének (több oszlop esetén azok összevont értékének) egyedinek kell lenni. (KülönbözQ sorokban lévQ kulcsértékek különbözQek.) Nem lehet NULL értékq, összetett kulcs esetén egyetlen része sem. Egy táblának csak egy elsQdleges kulcsa lehet.
[FOREIGN KEY(gyerek_oszlop ,...)]
REFERENCES szülQ_tábla [(szülQ_oszlop ,...)] [ON DELETE {CASCADE | SET NULL}]
KülsQ (idegen) kulcs vagy hivatkozási megszorítás: olyan oszlopo(ka)t jelölünk ki, melyek egy másik táblával való logikai kapcsolatot valósítják meg. Ezen oslz< B D J V
n
Ú
Ü
Þ
ú
6
\
J
L
® J\^`ìòö ÊÐ
.æü ñãÕɾ²¾²¾²¾ª¾¾²¾²¾²¾²¾²¾|¾¾²¾²¾²¾¾p¾h/ghHF1>*CJaJhGhHF15CJaJ hHF1CJaJ hGhHF1CJ
aJ
h/ghHF1B*CJaJph hý4CJaJh/ghHF15CJaJ h/ghHF1CJaJhHF1h
T6CJ
aJ
hBWh
T5CJ$OJQJhBWhDH5CJ$OJQJhBWhgx55CJ$OJQJ,Ü
Þ
L
^` ¸® ë $
*,¦,÷òíííííííåÜÜÏÄÜí¿º³¬
ÆÀë&
Æàë&
gdþuÔ$a$
$
&
Fa$gdHF1
n7^n`7gdHF1h`hgdHF1
&
FgdHF1gdHF1gd
T $a$gdDH bË Ì @× þþþ "$bf¸ºÒ 2 8 @ A H I J V ~ ª « ¬ ® ¯ µ · Ä Æ õèõßÕËżŬˡ¡ËÅËÅÅwË¡ËÅÅnÅ_ShHF10J1B*CJ phh=GhHF10J1B*CJ phh=GhHF1CJ -j)hbôhHF1CJ Uh }hHF1CJ hMghHF1CJ hHF10J#CJ hbôhHF10J#CJ -jhbôhHF1CJ Uhu'(hHF1CJ
hHF1CJ jhHF1CJ Uh$}hHF15CJ hi0#hHF1CJ h¿TChHF156CJ ]h¿TChHF15CJ Æ é ê ë ó ö "#$ 8>ªÀîðò24>@X¨¬®°
(ðäÛðäðäðÒÌÒÌÃ¹Ì°Ì ¹¹Ì¹ÌÃÌ
¹z¹Ìo_-hBWh±v¾5CJOJQJaJ hGhHF1CJ
aJ
h&WìhHF10J#CJ -j;h&WìhHF1CJ U hbôhHF10J#CJ -jBhbôhHF1CJ Uh }hHF1CJ jhHF1CJ UhµEhHF1CJ
hHF1CJ hi0#hHF1CJ h=GhHF1CJ hHF10J1B*CJ phh=GhHF10J1B*CJ ph!(*,.JLPRfh ¢¤¦®°ìî"$&(*,46pr¦ïäÑÃѺªºººªpºº_ºppºº jÑhë\
FHº¼¾ÀÂÄÌÎâä "&(\^ïáØáÉ½ÉØáØ¬áØáɽɨáØáØáÉÉØáØ|áØáÉØlØáØ-hÞ5;CJaJmHnHu jÅhë\Ä"j¹ M--
Ü h!X"Ð"n#$r$â$L%È%@&&É& 'øøøøñøøøøøøøøñøøøøñøøøøñøøñø
Æàë&
ÆÀë&
¤¦âä
JKefghijno³´µ·¸¹½¾èéïáØáȼØáØáØá¼ØáØáØá}ØáØláØá¼ØáØ j¹hë\
,-GHIKLMQR>@tvx|~ØÚ ------"-$-H-J-~---ïáØáÉ½ÉØáØ¬áØáɽɨáØáØáÉÉØáØ|áØáÉÉØáØká j*
hë\
hë\
hë\
Ð Ò Ô Ø Ú Ü ä æ &!(!\!^!`!d!f!h!p!r!""L"N"P"T"V"X"`"b"""öèÙöÉöèö¸èöèɬÙöèöèöèÙ¬ÙöèöèöèÙ¬ÙöèöyèöèÙ¬Ùöè j
hë\
hë\
hë\
hë\
$ $0$2$f$h$j$n$p$r$z$|$ $¢$Ö$öå×ö×Èö¸ö×ö§×ö׸Èö×ö×ö×ÈÈö×öy×ö×ÈÈö×ö jhë\
hë\
%
%@%B%D%H%J%L%P%R%%%¼%¾%À%Ä%Æ%È%Ð%Ò%-& &:&;&<&>&?&@&D&E&x&y&&&ïáØáÉ½ÉØáØ¬áØáÉØØáØáØá½ÉØáØzáØáɽɨáØi jhë\
hë\
'
'X(Z((((((((( (òéòÚéÊéòé¹òéòÊÚéòéòéòÚÚéòéòéòÚxieh=Gh(ph>>CJOJQJaJ$jhBWhgx55CJ$OJQJU júhë\
&
F
Æ a$gd]¦ $a$gd±
&
F
Æ gd]¦gd± gdt $$1$gd4:$a$
ÆÀë&
(Ì(î(ð()
)")(*J*++>+B+f+++&,@,B,V,Z,x,,è,ê, -(-b-æ-.(.E.¤./0R0°01Z1^1j1ùõùéÛéÐéÐÅéÛéнеЪÅÐÅÐéÛéÐÐÐwwoÐ h'mCJaJ hã{bCJaJ hBWhã{bCJaJ h5,àCJaJhì*h± 5CJaJhE0Fh± 5CJaJ hBWh9BÅCJaJ h¿TCCJaJ h
'¸CJaJ hBWhé_ÆCJaJ hBWh± CJaJhBWh± 5>*CJaJhBWh± 5CJaJhj2
hBWh± (j1¨1º1¼1Þ1î1"4L4¢4¤4¦4ä4ü4þ4Ü56>6F6H6d6f6¦6¶6p7r7Ì78\88¾8Ø8à8L9N99 9¶9¸9ì9V::õêõêßÔɾÉÔ³ÔÉÔɨÉÔtfhBWheN5>*CJaJhê64heN5CJaJ heNCJaJ hBWheNCJaJhBWheN5CJaJheN5CJaJ h(phEWCJaJ h(ph!X½CJaJ h(ph4:CJaJ h(phé_ÆCJaJ h(ph± CJaJ h(ph¿TCCJaJ hBWh± CJaJ hBWhuÚCJaJ(5H6N9â:<º=èAªBC
&
F
Æ ÿ^`ÿgd]¦¤(@&gd(p¤
&
F
Æ gd]¦:::®:¾:à:â:è:,;<<b>ô>4?6?8?@¾@ð@A
A
AæAòæÚÏÇÏòÚÏÚòÚÏÚòÚÏ»ÇÏÇÏÇÏǯ¤¯¤ÇÇǤǤÏÇÏÇxÇÏÇheN5CJaJhE0FheN5CJaJ h¯TQheNCJaJh¯TQheN5CJaJ hwheNCJaJh²zheN5CJaJh+#OheN5CJaJ heNCJaJ hBWheNCJaJhBWheN5CJaJhì*heN5CJaJhBWheN5>*CJaJ/æAèA B B8BjBlBB¦B¨BªB¼BCðC*CJaJ h²zCJaJ hO#CJaJ hE0FCJaJh¯TQ5CJaJ hBWhE0FCJaJhBWhE0F5CJaJ h± CJaJh¿TC5CJaJhU
hU
5CJaJ hU
CJaJ hBWh± CJaJhBWh± 5>*CJaJhBWh± 5CJaJ hBWheNCJaJ"ZHIØIJ*J4J`JJ²JÄKÆK LL:LdLfLMMM M¢M¦MªM¬M®M°M²M´M¶M¸MºM¼M¾MÀMÂMÄMÆMÈMÌMÐMÒMÖMÜMõíõåõÝõÑõÉÁõÑõÑõ¸¥¸¥¸¥¸¸¥¸¸¥¸¥¸¥¸¸¥¸l¸$jhBWh¸4UCJ
UmHnHu$jhBWhþuÔCJ
UmHnHu$jhBWh!X½CJ
UmHnHu$jhBWh± CJ
UmHnHuhBWh± CJ
hO#CJaJ h'mCJaJhBWhE0F5CJaJ h@CJaJ hÐ2QCJaJ hQ!
CJaJ hBWhE0FCJaJ*¼MÀMÆMÊMÌMÒMØMÚMÜMàMäMæMèMêMìMîM(N~PPØPðPxQQúúúúúúúúúúúúúúîéúúÝÔÈÔ
$$Ifa$gd©\
$IfgdPO
$$Ifa$gd>>gdt
$-^-a$gd¸4Ugd± ÜMÞMàMâMèMêMìMîM(N0NTN|NNNN N¶N8O
aJ
hE0FCJaJ hBWh}WcCJaJ hBWh!X½CJaJheNh'5CJaJ h'CJaJhBWh± 5CJaJh@h± 5CJaJ hBWh± CJaJ
hBWh± h(ph¸4UCJaJhBWh!X½CJ
$jhBWh!X½CJ
UmHnHuhBWh± CJ
$jhBWh¸4UCJ
UmHnHuPÔPÖPØPðPQ
QQ&Q*QPQTQbQdQxQQQ¢QÀQîQ6RHRRÌR
S@SxSSSSS°S¸SºSÄSÔSîS2T>TBT^TlTTTTªTõîõåõÛõÛõåÕÌÃåõå½å´å½å«å«½«½«å½å¢å´å½ååshBWh± 5CJaJ hì*hE0FCJ
aJ
h©\
h'mCJ
heNCJ h©\
hO#CJ h©\
heNCJ h©\
h¨%CJ h©\
hÖuCJ
hÖ5?CJ h©\
húlCJ h©\
hÎAvCJ
h©\
CJ h©\
hO#5CJ h©\
h± CJ
h©\
5CJ h©\
h± 5CJ -QQ°QÀQ4Rzmm]$¤( ¤($Ifa$gdÖu
¤( ¤($IfgdPOkdw$$IfFÖÖFºÿ
5&Ì
*Ö0ÿÿÿÿÿÿ ö{&ööÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿ4Ö
Faö4R6RVRRSzmm]$¤( ¤($Ifa$gd¨%
¤( ¤($IfgdPOkd( $$IfFÖÖFºÿ
5&Ì
*Ö0ÿÿÿÿÿÿ ö{&ööÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿ4Ö
FaöSS¸SðS@Tzmm]$¤( ¤($Ifa$gdÖu
¤( ¤($IfgdPOkdÙ $$IfFÖÖFºÿ
5&Ì
*Ö0ÿÿÿÿÿÿ ö{&ööÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿ4Ö
Faö@TBTlTTTzmmm
¤( ¤($IfgdPOkd$$IfFÖÖFºÿ
5&Ì
*Ö0ÿÿÿÿÿÿ ö{&ööÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿ4Ö
FaöTTTvVxVYÞZ^Þ_ªerfzuuuuaaaaa
&
F
Æhäþ^`äþgd]¦gd± kd;$$IfFÖÖFºÿ
5&Ì
*Ö0ÿÿÿÿÿÿ ö{&ööÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿÖ
ÿÿÿ4Ö
Faö
ªTUUUUHVXVvVxVÈVWÜWX`XYYYºYZ ZÚZÞZ[[>[P[Ø[0\\\t\\´\¶\õêõÞõÓõÈÞõ½õ½õµõÞõªõ}r}g_gT hBWh#úCJaJ húlCJaJ hBWh´<CJaJ hBWhYC-CJaJ hBWhñiCJaJ hBWhªv¾CJaJhBWhªv¾5CJaJ hBWh|R@CJaJ hBWh4 UCJaJ hÐ2QCJaJ hBWh} CJaJ hì*h± CJ
aJ
hBWhÖuCJaJhBWh± 5CJaJ hBWh!X½CJaJ hBWh± CJaJ ¶\º\]^8^^¸^¼^Ô^Ö^ì^ _ ____<_P__Ü_Þ_ê_ü_"`.`D`F`v`x`z`õêßÓȽ²ª²½Èê½È½È½êߢxmxaV hBWh± CJaJhÏ üh± 5CJaJ hBWhÏ üCJaJhÏ ühÏ ü5CJaJhÏ ü5CJaJh5,à5CJaJhBWh± 5CJaJ h©\
CJaJ húlCJaJ hBWhúlCJaJ hBWh4 UCJaJ hBWh|R@CJaJhBWh|R@5CJaJ hBWhªv¾CJaJ hBWh#úCJaJ hBWh´<CJaJz`¬`ì`a aa*a2a6alaa°aâaìaüa4b8bzb|b~bb¦bºbÀbÆbÈbÞbàbôbcc@crc~cäcæc&d2ddddªdêdìde@eDeeªeõêßõÔõÔßɾ¶É¾¶É¾Ô«ßõ«ßõÔõß««ß«ß«ßßßß~¶~¶~¶~¶ hBWhÏ üCJaJ hBWh4%CJaJ hBWh´<CJaJh5,àh#ú5CJaJ hBWh#úCJaJ hÏ üCJaJ hBWh4_CJaJ hBWh a
CJaJ hBWh7CJaJ hBWh± CJaJ hBWh?(]CJaJ hBWhgYUCJaJ0ªeÒeZfdflfnfrftf¸f
gDgügþghhhbhphÄhÈhÊhÎhÐhÒhÔhÖhóèÜèÑèÆ¿è·è¢¿ó¿z¿odUJB hªOËCJ
aJ
hBWhÿUîCJ
aJ
jhªOËhªOËCJ
UaJ
hBWhÿ¨CJ
aJ
hBWh± CJ
aJ
hBWh± 5(jhBWhÇCJUaJmHnHu hBWh± CJaJ(jhBWh± CJUaJmHnHu hHF1CJaJ
hBWh± h°HÛhªOËCJaJ hBWh!X½CJaJhÐ2Qh± 5CJaJ hBWh± CJaJhBWh± 5CJaJrftf¸füghhÊhÌhÎhÐhÔhÖhØhÊiôibjfj^kkkòkôkÚlúl÷òíííííííííííäßßíäÚÔíÎä@&gd¯TQ@&gd± gdÿ¨gd x³7`7gdÅIgd± gdt $a$gd¸4UÖhØhìhiiri¼iÄiÈiÊiôiøiúi
CJaJ hì*hÿUîCJ
aJ
jhì*h¬ `CJ
UaJ
hBWh x³CJ OJQJ^J hBWh x³CJaJhBWh± CJ OJQJ hBWh L¾CJaJh'CJ OJQJ h'CJaJ hBWh± CJaJ hBWhÿUîCJaJ hBWhßiICJaJhBWh± 5CJaJ hªOËh± CJ
aJ
kk kÐkìkòkôk-ll®lØlÙlÚlùlúlûl
mFmImJmKmLmMmõæÚÌÚÁÚ¶«¶ ¶~rg_gW~A+jhBWhÿ¨5CJUaJmHnHu hqe>CJaJ h°HÛCJaJ h°HÛh°HÛCJaJh°HÛh°HÛ5CJaJ hªOËhªOËCJ
aJ
h± CJ OJQJhBWh± CJ OJQJ hBWhÿ¨CJaJ hBWh»>7CJaJ hBWh± CJaJ hªOËh± CJ
aJ
hBWh± 5>*CJaJhBWh± 5CJaJjhBWh¬ `CJUaJ hì*h± CJ
aJ
úlûlKmLmZopp4rrúrnsÌsÎsyyryÞyJzLzö|:}úõõððõêáØÐÇõðÂÂÂÂõ¼²
71$`7gd»>71$gd»>7gd
AÜ7`7gdÅI $a$gd x³7`7gdv $@&a$gd x³@&gd¯TQgd¯TQgd± gdªOË MmOmcmn>nnnn¤n¦nÎnoToVoXoZo\ofoxoo¨oÒop"pHpLpppppØpqqÈqèqõéõÝõÒõÝõÇõÒõÒ¼¡ÝõÇõõÒõõnbWW hBWh± CJaJhBWh± 5CJaJ(jhBWhªOËCJUaJmHnHu hªOËhqe>CJ
aJ
h'CJaJ hBWhszCJaJhBWhlf5CJaJjhªOËhªOËCJ
UaJ
hBWhÿ¨CJaJ hBWh}WcCJaJ hBWhlfCJaJhBWhqe>5CJaJh'hqe>5CJaJ hBWhqe>CJaJ"èq2r4rTrVrlrxrrúrs:sPslsnsÌsÎsÐsÒstt¨t´tâtðvþv@wTwjwõêõßÔßõÇßÔ¼ßõDZsõh]h]h]RG hBWh¾g*CJaJ hBWhÂ%CJaJ hBWhLNdCJaJ hBWh»>7CJaJhBWh± 5CJaJ0jhBWh»>7CJOJQJUaJmHnHu0jhBWh°HÛCJOJQJUaJmHnHu hªOËh4:CJ
aJ
hBWh4:CJaJhBWh± CJ OJQJ hBWhlfCJaJ hBWh x³CJaJ hBWhDHCJaJ hBWh± CJaJjwzwww¬w¶wÈwÊwÚwöw4x6x\xdxxÐxØxäxêxìxyyy2y4yPyRyryyyºy¼y¾yôy
zõêÞêÞõÓêõËêõ¿õ´©¡´´êzpzfzYzYzpzYhBWhkäCJ OJQJh¯TQCJ OJQJhÏ üCJ OJQJhBWh± CJ OJQJhBWh
AÜCJOJQJaJ hBWhÿUîCJaJ hÐ2QCJaJ hBWhÐ2QCJaJ hBWh L¾CJaJhBWhÂ%5CJaJ hÖ5?CJaJ hBWh
AÜCJaJhBWh± 5CJaJ hBWh± CJaJ hBWhÂ%CJaJ"
z
z(z*z8zHzJzLzNz¨z\{{{¤{¾{Î{Ò{è{ê{|ö|:}<}Z}öéßéÒ˼£vnfn^SHÒ= h(ph± CJaJ hBWh L¾CJaJ hBWhÐ2QCJaJ hv>îCJaJ h.CJaJ hÐ2QCJaJ hBWh
AÜCJaJ hBWhlfCJaJ hBWh± CJaJhBWh± 5CJaJ0jhBWh± CJOJQJUaJmHnHuh°HÛhL,ÖCJOJQJaJ
hBWh± hBWh± CJ OJQJh¯TQCJ OJQJhBWhkäCJ OJQJhÏ üCJ OJQJ:}<}^}Ú~¾"ÞæèjlnprÐ.êì úôïââÑâúúúúúúúÈÈÈÈú7`7gd4:gdÑ s7`7gdÅI
Æ3 7^7`gdºC
7^7`gdºCgdºC@&gd± gd± Z}\}^}:~D~\~Ö~Ø~Ú~è~¼Ô¦ .VZÞàâäæèöêßÔÌßÁ¶ª¶ª¶ª¶ª¶ª¶x_PChBWh± CJ OJQJh(ph± CJOJQJaJ0jh(phÅICJOJQJUaJmHnHu0jh(ph7]CJOJQJUaJmHnHu0jh(phÇCJOJQJUaJmHnHuhBWhä
5CJaJ hBWhä
CJaJ hBWh
AÜCJaJ h¯TQCJaJ hBWh.>«CJaJ hBWh± CJaJhBWh± 5CJaJhÃMÎ5CJaJè$>Nbdhjnprêìîòô ùíæßù×ʽ°£r]G<-h]NSh]NSCJOJQJaJ hBWhÑ sCJaJ+jh]NSh]NS5CJUaJmHnHu(jh]NSh]NSCJUaJmHnHu(jh]NSh}"ACJUaJmHnHuhBWhÑ sCJOJQJaJhBWhÑ sCJ OJQJhBWhW.
CJ OJQJhBWh.>«CJ OJQJhBWhPOCJ OJQJhBWh± CJ OJQJhBWhÑ s5
hBWhÅI
hBWh&ÃhBWhÑ s5CJaJ
hBWhÑ s "$&(dZ\rÜ ØZ\øóóóóóóóóóîìììäÜÓÓÉÁ¸<^
&
FgdºC
&
F1$gd-c
¤^¤gd-c
&
Fgd-c
&
FgdºCgdtgd± ¤`bdjprv|ÌÖâ²
¶
XZ\pñä×Êüü±¥±±v±ncn[PDhBWhb]À5CJaJ hÔS)hÔS)CJaJ h/)CJaJ hBWhSCJaJ hSCJaJh]NShx:ö5CJaJ hBWh.>«CJaJh]NSh.>«5CJaJh]NShgx55CJaJhBWhgx55CJaJ hBWhgx5CJaJ
hBWhgx5
hBWh± hBWhÑ sCJ OJQJhBWh± CJ OJQJhBWh]NSCJ OJQJh]NSh± CJOJQJaJprvªºÖØÚÜö X:ÖØ¸ F&FPª´¸ÀõéÝÒÊ¿·¿·¯¦¦|¦peeé¿Z¿N¿Nh3hgx55CJaJ hBWh8mCJaJ hBWh-c
CJaJhWbh-c
5CJaJ hövªh-c
CJaJ h-c
CJaJ hºCh-c
CJaJhövªh-c
5CJaJh-c
5CJaJ hAZcCJaJ h3CJaJ hBWhgx5CJaJ hSCJaJ hBWh.>«CJaJhBWh.>«5CJaJhBWhgx55CJaJ h3hgx5CJaJÀÄú8<>ÊÌ>brtzÂZ\x¶ÜTVXZ¦õíõâõâõâõâ×â×â×âÌÀ²§²À²ÀÀ²ÀÀ
ymahÔS)h
vñ5CJaJhÔS)hgx55CJaJhBWhgx55CJaJ hBWhgx5CJaJh36CJaJh¿TCh356CJaJ h356CJaJhBWh356CJaJhBWh36CJaJ hBWhb]ÀCJaJ hBWhb]ÀCJaJ hBWhgx5CJaJ h.CJaJ hBWhO ¶CJaJ"\XZZÀRTÂ.ºH¿B¢(úîìÕÀÀ¹´«ìì«ì¢¢¢«´$7`7a$7`7gd/)gd/) ¤gd/)
&
F
Æ ¤feþ^e`þgd]¦
&
F
Æ ¤feþ¤^e`þgd]¦
$<^
vñCJaJ ¢¾ÀÂÈÌÎøú,.24d ´ôö +,01=>GHK®¾¿õøúûÿ BJLNrt|~öêßêÔÉßêßêßêÉ߾ɳßÉß«£ßê³ßêßêßê³ß³ß«£ÔßêßêßêßêßßÔßêÔ³ßêßêßê hBWhQNÒCJaJ h.CJaJ h ´CJaJ hBWh.½CJaJ hBWh¼ZCJaJ hBWhb]ÀCJaJ hBWh/)CJaJ hBWhgx5CJaJhBWhgx55CJaJh©\
5CJaJ< ¢¨Êà&(*ª´ò6tÌ
$ h n ¨ à $¡.¡N¡¡¡º¡¾¡À¡Ü¡ä¡ú¡õêõâÚêÏÄõê¸êõêõêÄꬸêâê¸ê¡êâ¡êõ
ymaheShk'5CJaJheSh`mV5CJaJheSh{
5CJaJheS5CJaJ heSCJaJ hBWh{
CJaJ hBWhk'CJaJhBWh9BÅ5CJaJhBWhgx55CJaJ hBWh/)CJaJ hBWhÎÜCJaJ h.CJaJ h3CJaJ hBWhgx5CJaJ hBWh.½CJaJ&(ª
n R¢4£H£æ¨è¨>©«5¬!gµ¶®®òçããÛÖÑÑÇÁ¶©gd8Ê
$<^
&
F*$gdºC
$$
&
F*$gd(F´
$$¤<*$gd(F´1$gdk' ¤x*$1$gdk'gdÂ@=gdt $a$gd
T ¤x
7 ¤x^7gd/)
77^7`7gd/)ú¡þ¡¢P¢R¢j¢2£4£H£b£d£t£v£¤L¤X¤¤¤ª¤´¤À¤Ä¤È¤õíõâÖâËĹ¢¹¹{peYMB h]NShÂ@=CJaJh]NShÂ@=5CJaJh]NSh°Q:5CJaJ h]NSh°Q:CJaJ h]NSh8ÊCJaJ h]NSh& CJaJ hBWhC7CJaJ h ´CJaJh35CJaJ h3h3CJaJhBWh8Ê5CJaJ hBWh8ÊCJaJ
hBWhÂ@= h» :h&ÃCJaJhBWhgx55CJaJ hBWhgx5CJaJ h.CJaJ hBWhk'CJaJȤԤڤú¤*¥f¥h¥z¥¥¥´¥Ò¥î¥ð¥ô¥ö¥
¦ ¦,¦@¦F¦\¦h¦|¦¦ª¦î¦§§,§0§¨ ¨¨B¨óçÜÑÆ»ÑưÆÑ¥Ñ¥¥¥°¥¥|¥¥|¥tiai h(F´CJaJ hBWh& CJaJ hÅpICJaJ hBWhiÜCJaJ hBWh}WcCJaJ hp[4CJaJ hBWhP!3CJaJ hBWhTCJaJ hBWh7C®CJaJ hBWh1wCJaJ hBWhõ,mCJaJ hBWhC7CJaJ hBWh8ÊCJaJh$}h8Ê5CJaJh$}hÂ@=5CJaJ"B¨Z¨¨¨¨¨ä¨æ¨è¨©*©6©:©<©>©D©T©©¢©¤©¶©¸©Ä©Ô©ì©î©ª(ªBªFªxª|ª¸ªøªøíøíøíâ×É»ÉÉ É É y ly aV hBWh°Q:CJaJ hBWh ÅCJaJhBWh Å@ýÿCJaJhBWhßc|@ýÿCJaJhBWh°Q:@ýÿCJaJhBWhx:ö@ýÿCJaJhBWh7C®@ýÿCJaJhBWh Å5@ýÿCJaJhBWhßc|5@ýÿCJaJhBWh7C®5@ýÿCJaJ h» :hßc|CJaJ hBWhÂ@=CJaJ hBWh& CJaJ h.CJaJ!øª«"«<«H««º«Ø«ò«ú«
¬ ¬¬¬¬¬¬.¬2¬5¬@¬I¬O¬P¬h¬õêõêõÜÏøá¡~sgZÏLÏ>h¾,h7C®5@ýÿCJaJh(F´h7C®5@ýÿCJaJhBWh Å@ýÿCJaJhBWhû 55CJaJ hBWhû 5CJaJhwóhþuÔ5CJaJ hBWhþuÔCJaJhBWhþuÔ5CJaJhBWh7C®5CJaJ hBWh7C®CJaJ h*Eàh7C®CJaJh*Eàh7C®5CJaJhBWh7C®@ýÿCJaJh*Eàh7C®5@ýÿCJaJ hBWhx:öCJaJ hBWh ÅCJaJh¬k¬q¬r¬¬¬¬¬°¬³¬Æ¬Ê¬Ð¬Ñ¬Ô¬Ö¬ë¬ü¬ !$,-012>?RSgv~¢´µóæóÙæÙϵϵóÏÙóÙæÙó§æµ
µæó§æxæµkóhBWhT@ýÿCJaJhBWhßc|@ýÿCJaJh]NS@ýÿCJaJh¾,@ýÿCJaJh¾,hx:ö5@ýÿCJaJh¾,h7C®5@ýÿCJaJhBWhû 5@ýÿCJaJhBWhp Õ@ýÿCJaJhp Õ@ýÿCJaJhBWh Å@ýÿCJaJhBWhx:ö@ýÿCJaJhBWh7C®@ýÿCJaJ&µ¶¿®V®®¬®®®°®²®´®¸®¼®Ð®Ò®@¯R¯¯¯ê¯L°N°õéÞÓÈÓ½¨xlÓaÓVaVÓA(jh(ph-`CJUaJmHnHu hBWhû 5CJaJ hBWhPbwCJaJhBWh8Ê5CJaJh¼Lh& 5CJaJhBWh& 5CJaJhBWh±v¾5>*CJaJhBWhPbw5>*(jhBWh& @ýÿUaJmHnHu hBWh& CJaJ hBWh}WcCJaJ hBWh8ÊCJaJ hBWhßc|CJaJhBWhßc|5CJaJ h(ph8ÊCJaJ®®²®´®¶®¸®º®¼®L°P°R°T°V°X°Z°\°^°¦°î±C²u²±² ³Z³¢³ñ³úúúúúúúúúúúúúúúúõððèèØèÐ $a$gdñ $j ©^j `©a$gdÓr $a$gdØ<â gdØ<âgd-`gd8ÊN°P°R°T°V°X°Z°\°^°¦°"±(±>±B±f±v±ê±ì±î±
²@²A²M²N²j²s²t²u²v²w²y²~²õîçß×ÌÁ¶ªªvmcvZmPPvh|.öh©\
5CJ h|.öh°Q:CJ h|.öh 5CJ h|.öh°uÊCJ h|.öhØ<âCJ h|.öhØ<â5CJ hBWh CJaJ hBWhØ<âCJaJ hBWh-`CJaJhBWh-`5CJaJ hL,Öh-`CJaJ h¼Lh-`CJ
aJ
h¼Lh¼LCJ
aJ
h¼LCJ
aJ
h-`CJ
aJ
hBWh8Ê
hBWh-` h(ph-`CJaJ-~²²²²²²¯²°²Ç²³³ ³
³³³³³ ³!³&³'³5³6³7³C³D³S³V³X³Y³Z³o³p³t³u³ ³¡³¢³õëõëâÙÐõǾõ¶«««¶¶xl¶ldëõÇâÇÐõ hÓrCJaJhVgãhÓr>*CJaJh$}>*CJaJ hVgãhÓrCJaJ h$}CJaJ h$}h$}CJaJh$}h$}>*CJaJ hVgãh$}CJaJ h<
CJaJh|.öhñCJ h|.öhØ<âCJ h|.öh°uÊCJ h|.öh°Q:CJ h|.öh CJ h|.öh©\
5CJ h|.öhØ<â5CJ %¢³¶³»³Ô³ï³ð³´´P´°´À´Ä´Ø´µµ<µLµ|µ~µµ´µ¬¶··4···â·è·ì·ü·¸"¸)¸*¸-¸/¸;¸^¸õìõìãõìõìÙÐÙÐÊÐÀãÀµ®££|£|£|£qi£|£|£ hwóCJaJ hBWhjE CJaJhBWhgx55CJaJ hºCCJaJ hW`·CJaJ hBWh¨mæCJaJ hBWhgx5CJaJ
hBWhgx5 h(ph-`CJaJh|.öh°uÊ5CJ
h¸?CJ h|.öh|.öCJ h|.öh|.ö5CJ h|.öh°uÊCJ h|.öhñCJ h|.öhñ5CJ &ñ³°´<µ~µµ´µ4··ê·.¸c¸¡¸Ð¸¹B¹4ºº»»>¾@¾÷÷÷òíååÙÙÙÙÙÙÊÊÙ·µµµ$8;ý¤1$^8`;ýa$gd°Q:$8¤1$^8a$gd°Q:
8¤1$^8gd°Q: $$gdºCgd¸4Ugd8Ê $a$gdñ ^¸_¸a¸b¸d¸e¸v¸
¸¸¸¸ ¸¢¸±¸³¸º¸Ç¸È¸Ì¸Ï¸Ò¸ß¸ð¸ý¸¹¹*¹+¹,¹2¹;¹<¹=¹A¹B¹G¹ºº º*º,º2º6ºTºXºZººõéÝÒÝÆÝ»õéÝÒÝÒ°Ò°ÒÝÒݨÒÝÒÝÒÝÝ
Ò
Ò}Ò
ÝÒÝÒ°Ò hÔS)CJaJ hqp°CJaJh|5CJaJhÔS)5CJaJhW`·5CJaJ heSCJaJ hBWh°Q:CJaJ hBWhiÜCJaJhBWhjE 5CJaJ hBWhgx5CJaJhBWhgx55CJaJhBWhiÜ5CJaJ hBWhQNÒCJaJ.ººº²º¼º¾ºôºøºúº»»»(»@» »Ø»ì»¼$¼&¼N¼È¼Ê¼ð¼
½½J½N½Þ½¾¾:¾>¾@¾B¾h¾øìàìÔÉÁÔì¶«¶É¶£¶ÉÉ£ÉwÉɶɶɶlha
hBWhgx5hÔS) h(phQNÒCJaJ hBWh¨mæCJaJ hBWhTCJaJ hBWh°Q:CJaJ hBWh'mCJaJ h'mCJaJ h(phgx5CJaJ hBWhgx5CJaJ hL,ÖCJaJ hBWhjE CJaJhBWhQNÒ5CJaJhBWhjE 5CJaJhBWhgx55CJaJ hTW_CJaJ#h¾|¾~¾¾¾¬¾¾¾Ö¾â¾ì¾@¿N¿f¿h¿p¿¿¿¨¿²¿Ü¿à¿æ¿ö¿ú¿ÀÀ ÀcÀjÀÀ»À½ÀÈÀÂ~ÂùòæØæÌÀæ´æ¨¨¨æ´yæmbWbWbWbW hBWhg±CJaJ hBWh3CJaJhBWh9BÅ5CJaJhBWhvG5>*CJaJhM\5CJaJhBWhvG5CJaJhBWhùr 5CJaJhBWh0Ä5CJaJhBWh 5CJaJhBWh~15CJaJhBWhhj5CJaJhBWhgx55>*CJaJhBWhgx55CJaJ
hBWhgx5
hBWh¨mæ"@¾~¾4¿¿À À¸ÃºÃÄ>ÅźÇÉÅÊÎÌêÍúòòéÚÕÕÆÆÆÆÆ·ª $vú¤^`vúa$gdzX
vú^`vúgdÝs vú¤^`vúgdºC vú¤^`vúgdvGgd3 vú¤^`vúgd9BÅ7`7gdvG $$gdakgdt~ÂîÂ
ÃÃöøúÃÀÃÄÃÆÃØÃÄÄ*Ä,Ä.Ä8ÄDÄHÄJĦčĿÄ<Å>Å@ÅBÅDÅÅÅÅÅÅŰÅõêõâõ×ÌÀµª×µ×µ|ª×ti×Àµª^^Àµª× hBWh¨mæCJaJ hBWhÏ6#CJaJ hÏJ*CJaJhBWhhj5CJaJ hBWhhjCJaJhBWhgx55CJaJ hBWhÜ+
CJaJ hBWhJ¥CJaJ hBWh &CJaJhBWh &5CJaJ hBWhg±CJaJ hBWhgx5CJaJ h=&oCJaJ hBWh}WcCJaJ hBWh~1CJaJ#°ÅöÅÆÆ(ÆFÆHÆRÆTÆÆ°ÆÌÆäÆìÆîÆ ÇÇ$Ç(Ç2ÇPÇhÇjǶǸǺÇÎÇÐÇÒÇõêßÔßɾõßÉ³É¨ß t l l aU¾J hBWh$²CJaJhBWh &5CJaJ húHPhgx5CJaJ hÚ-CJaJ húHPhúHPCJaJhúHP5CJaJhBWhúHP5CJaJhúHPhúHP5CJaJ húHPCJaJ hBWh²E;CJaJ hBWh?QCJaJ hBWh &CJaJ hBWhz7CJaJ hBWh CJaJ hBWhgx5CJaJ hBWh¨mæCJaJ hBWh?uÅCJaJÒÇÖÇÞÇ
È ÈÈÈ:ÈhÈjÈxÈzÈ|ÈÈÈúÈÉÉ*É,É.É\ÉÉ¢ÉÌÉÊÊÊ)ÊJÊKÊeÊfÊgÊjÊõêßÔõÔõÔÉÔÉßõ¾õ²¦õÉ
õÔõ}õÉõrj^hÏJ*hgx55CJaJ hÏJ*CJaJ hÏJ*hgx5CJaJ hM\CJaJ hBWh$²CJaJ hBWh CJaJ hBWh
°CJaJhBWh &5CJaJhBWh 5CJaJ hBWh[|CJaJ hBWh &CJaJ hBWhz7CJaJ hBWh,@ÓCJaJ hBWh0ÄCJaJ hBWhgx5CJaJ!jÊkÊnÊoÊqÊrÊtÊuÊvÊ|Ê~ÊÊʢʥÊÅÊÊÊÒÊÓÊÔÊãÊôÊÿÊËËËÌhÌjÌpÌrÌÌÌÌÌÌÌöêöêöêößÔÉÔ¾ÔêÔ¾²Ô¾§ÔÔÔ¾uuj hBWhbg)CJaJhÝshz75CJaJ h×
¬CJaJ hBWhÝsCJaJ hÝsCJaJ hBWhz7CJaJ hBWh»y:CJaJhBWh$²5CJaJ hBWh &CJaJ hBWh$²CJaJ hBWhgx5CJaJ hÏJ*hgx5CJaJhÏJ*hgx55CJaJhÏJ*5CJaJ$ÌÌÈÌÊÌÌÌÎÌÐÌîÌ>ÍRÍxÍÍÍ´ÍÄÍÆÍÒÍÔÍÞÍàÍâÍêÍðÍ&Î(Î>ÎNÎVÎXÎZÎ\ÎóçÜÔÌÁܶ« ÌÜ ÜÁÜ Ü¶¶vÌkcX hzXhzXCJaJ hakCJaJ hBWhÝsCJaJhÝsh$²5CJaJ hBWh/CJaJ hzXCJaJ hBWh}WcCJaJ hBWh$CJaJ hBWhz7CJaJ hBWh$²CJaJ hBWh &CJaJ hÝsCJaJ h×
¬CJaJ hBWhgx5CJaJhÝshÝs5CJaJhÝshgx55CJaJêÍZÎ\ÎÏ0ÐâÐÑÚÑÜÑ"Ò¦ÒJÓLÓÓÊÓÔvÔÐÔííÞÞÞϽ½½° $a$gdÈ$vú^`vúa$gdvG
vú^`vúgdvG $vú¤^`vúa$gdvG ¤^`gd{!j vú¤^`vúgdºC $¤^`a$gdzX\Î^ÎbÎÎÎ¦ÎÆÎúÎüÎÏ
ÏÏÏ&ÏBÏRÏTÏjÏÏÏÏÏÏ´ÏÄÏÌÏÒÏÔÏØÏÞÏàÏæÏîÏøÏüÏõêß×Ïļ߰¤êßÄİļ{o{d{d{dY{d{d hÝshÝsCJaJ hBWhÝsCJaJhzXhÝs5CJaJ hÝsCJaJh{!j5CJaJh×
¬h{!j5CJaJh{!jhgx55CJaJh{!jh &5CJaJh{!jh/5CJaJ h{!jCJaJ h{!jh{!jCJaJ h¥PCJaJ h´0²CJaJ h{!jh/CJaJ h{!jhgx5CJaJ h{!jh &CJaJ"üÏþÏÐ
ÐÐ ÐÐÐ Ð&Ð.Ð2ÐVÐjÐrÐxÐzÐ~ÐÐÐÐТЦШвкоÐÂÐÈÐÌÐÎÐØÐàÐîÐÑÑ&Ñ>Ñ@ÑjÑÑÑÑÑÑõíâíâíâõíâíÖíâíâíâõíâíâõíâíâíâõíâíËÀµÀªª{
hak6CJ hakhgx56CJ h{!jh &CJaJ h{!jCJaJ h{!jhÏJ*CJaJ h{!jhgx5CJaJ h{!jhbg)CJaJ h{!jh$CJaJ h{!jh{!jCJaJhzXhÝs5CJaJ hBWhÝsCJaJ hÝsCJaJ hÝshÝsCJaJ-ÑÀÑØÑÚÑÜÑæÑöÑøÑüÑ"Ò,Ò>Ò@ÒBÒNÒdÒxÒ¤Ò¦Ò¨ÒªÒ4ÓHÓJÓLÓÓñâÖź®£ºº®uiu£º£^M hBWhè<ßCJOJQJ^JaJ hBWhgx5CJaJh#1hgx55CJaJh#1h®5CJaJ hBWh®CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWh &CJaJhBWh$²5CJaJ hBWh$²CJaJ hM\hM\CJ
OJQJ^JaJ
hgx5CJ OJQJ^Jhakhgx5CJ OJQJ^Jhakh &CJ OJQJ^JÓÓÓÓ®ÓÊÓÐÓÜÓÔ ÔÔ>ÔPÔRÔtÔvÔ|ÔÔÔ¶ÔÎÔÐÔLÕNÕPÕ^ÕjÕ ÕïÞÌ»ïªïÞï»ïªï»w»f»wïXhM\CJOJQJ^JaJ hBWhG³CJOJQJ^JaJ hBWh?uÅCJOJQJ^JaJ hBWhoCJOJQJ^JaJ hBWhè<ßCJOJQJ^JaJ hBWhùr CJOJQJ^JaJ hBWhè"¯CJOJQJ^JaJ#hBWhgx55CJOJQJ^JaJ hBWh:\CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJÐÔPÕÐÕÖrÖÒÖ6×¾×,ØÌØ4ÙÔÙÚÚÚâÜäܤàá`âbâã´ãDäôäå÷÷÷÷÷÷÷÷÷÷÷÷÷òòòíèíã÷÷ÛÛ÷ $a$gd:\gdzX gd)[gd)[gdùr $a$gdÈ Õ®ÕÌÕÐÕØÕÚÕÖÖrÖÖÖÖªÖ¶ÖÎÖÐÖ6×è×*Ø2Ø4ØnØpØrØtØØÊØïÞͼ«¼x«x«xxgVgEVEVEg hBWh²E;CJOJQJ^JaJ hBWhTCJOJQJ^JaJ hBWh%pHCJOJQJ^JaJ hBWh?uÅCJOJQJ^JaJ hBWh:\CJOJQJ^JaJ hBWhG³CJOJQJ^JaJ hBWhoCJOJQJ^JaJ hBWhùr CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhè<ßCJOJQJ^JaJ hBWhs}
CJOJQJ^JaJÊØÚØèØìØ0ÙâÙðÙÚÚ Ú¢Ú,ÛÊÛÒÛÜÛüÛþÛnÜàÜâÜäÜ
Ý Ý¬ÝÊÝÒÝÔÝ
Þ
ÞÞïÞïÍïÞï¾²§§§vj_T_T_L_ h KCJaJ hBWhSCJaJ hBWh)[CJaJhBWh pp5CJaJ hzXhzXCJaJ hùr CJaJ hVUCJaJ hBWh$CJaJ hBWh ppCJaJ hBWhùr CJaJhBWhùr 5CJaJhBWhùr CJ OJQJ^J hBWhs}
CJOJQJ^JaJ hBWh®CJOJQJ^JaJ hBWh%pHCJOJQJ^JaJÞ$Þ8Þ~ÞÞ Þ¤ÞâÞúÞþÞßßßß:àRà¤à°àºàèàáá¢áÐá$â^â`âbââØâÜâãõêõêõêßÔßêÉê½ê²ê½¦½½êÉêêyhWy hBWh?uÅCJOJQJ^JaJ hBWh:\CJOJQJ^JaJ hBWhoCJOJQJ^JaJ hzXh ppCJaJ hÃMÎCJaJhÃMÎ5CJaJhBWh 5CJaJ hBWhè"¯CJaJhBWh)[5CJaJ hBWhær_CJaJ hBWh$CJaJ hBWhéCJaJ hBWh)[CJaJ hBWhs#+CJaJ-ãDã²ã´ãÂãäBäLäRä`äbädäfääääªä¬ä®ä°ä²äºäÈäÒäØäÞäðäôäøäúäïáп®¿®¿¿¿~®m\\¿\¿m¿mK® hBWhízCJOJQJ^JaJ hBWh?uÅCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWh{)äCJOJQJ^JaJh KCJOJQJ^JaJ hBWh®@`CJOJQJ^JaJ hBWh:\CJOJQJ^JaJ hBWhoCJOJQJ^JaJ hBWhùr CJOJQJ^JaJh;.GCJOJQJ^JaJ hBWhéCJOJQJ^JaJúäå å"åNåtåvåxåªåÒåÔåÜåææPæXæjææ æ²æÂæÖæ
ççrç²çàçöç,è.è0èïäØÌÀØÌµµµ¢µ¢µµvkv` hzXhgx5CJaJ hBWh²E;CJaJ hBWhær_CJaJ hBWh>êCJaJ hBWh{VCJaJ hBWhgx5CJaJ hBWhMCJaJ hM\CJaJ hBWh%pHCJaJhBWhvG5CJaJhBWhgx55CJaJhBWhær_5CJaJ hzXhær_CJaJ hBWhgx5CJOJQJ^JaJå åxå.è0è¼èé@é¼é*êêÆêë¨ëÖëDì¤ìêìììNîPî¾îïïïüïúôòúêêêêêêêêêêêêêúåúêêêÝØgdt $a$gdJgdºC $a$gds}
1$gdvGgdzX0èèìêìììôìíí íNîPîï$ïïïïüï(ð*ðFðHðTðVðhð¢ð¤ñïÞÓʾ³¨³ÓïïÞsgsgsVK@K hBWhv²CJaJ hBWhÀTµCJaJ h<<«hQNÒCJOJQJ^JaJhBWhÀTµ5CJaJhBWhgx55CJaJ
hBWhgx5 h<<«h>êCJOJQJ^JaJ hBWhJCJOJQJ^JaJ hBWh®@`CJaJ hBWh²E;CJaJhBWh²E;5CJaJh×
¬5CJaJ hzXhs}
CJaJ hBWh²E;CJOJQJ^JaJ hBWhs}
CJOJQJ^JaJüïð&ðJðTðVð¦ñÐó÷üøþøFùHùîù!ú^ú4û5ûøøøñéçßßßÙÐĹ²§é n¤^n`gdrs
©¤`©gdöpE ¤gdöpE
$$¤1$gd
$$$1$a$gd
$$1$gd
1$gdzX
&
F#gd K $a$gdJ ¤gdQNÒ ¤gd{V¤ñ¦ñªñºñÂñò:ò@òHòRòVò~òªò¬òÞòóóó"ó*ó0ótóvóóóó¢ó¦ó´ó¶óÂóÊóÌóÎóøíáÖ˿ִ©´©©Ö©©|qf|fqf]fq´hM\5CJaJ hBWhËAÛCJaJ hBWhSCJaJhBWhM\5CJaJ hBWhECJaJ hBWhMCJaJ hBWhSÌCJaJ hBWh´BÊCJaJ hBWhgx5CJaJhË-°hzH]5CJaJ hBWhO>CJaJ hBWhzH]CJaJhÿsæhzH]5CJaJ hBWhöpECJaJ hkaeCJaJ!ÎóÐóÒóÔóêóìóôóøóô!ô*ôYôeôfôgôtôô¾ôÀôÁôëôñôôôöôõ
õ
õ õõöõêßõêÔÉß¾³õ¨ ³ ÔznbYbMhpæhClG5CJaJhÄ^F5CJaJhWthÄ^F5CJaJhWthWt5CJaJ hÄ^FCJaJ hWtCJaJ hBWhkaeCJaJ hBWhClGCJaJ h×
¬CJaJ hBWh×
¬CJaJ hBWhMCJaJ hBWhJCJaJ hBWhO>CJaJ hBWhbCJaJ hBWh´BÊCJaJ hBWhhjCJaJ hBWhLsoCJaJöö&öJöPöbözööööÊöòö÷÷÷J÷n÷÷¨÷Ö÷ö÷ø÷ø,øØøøøóèàÕɽ±½¦èui]iUMUB hÿsæhÿsæCJaJ h×
¬CJaJ hÿsæCJaJhË-°hË-°5CJaJhË-°hSÌ5CJaJ hBWhöpECJaJ hBWhSÌCJaJ hkaeCJaJ h KCJaJ hBWhrsCJaJ hBWhJCJaJhpæhÿsæ5CJaJhpæhClG5CJaJhpæhb5CJaJ hBWhbCJaJ hË-°CJaJ hBWhClGCJaJhpæhM5CJaJøøúøüøþøFùHùRùfùhùtùùù¾ùîùôùú ú!ú"ú2ú3úAúBúFú]ú^úyúâúøíâÖŹÖÖ¡¹¡ÖsÖíhí]R hBWhrsCJaJ hBWhöpECJaJ hBWh ICJaJhBWh I5CJaJhBWhrs5CJaJ hBWh¡MNCJaJ hBWhN2CJaJhBWhn\5CJaJhBWh¡MN5CJaJhBWh 5CJaJ hBWhgx5CJOJQJ^JaJhBWhgx55CJaJ hÚ-hgx5CJaJ hBWhgx5CJaJ h$z8CJaJâúíú û4û5û:ûTûYûcûhûlûnû
ûûû¡û¦û®û±û¶û·û¸û¹ûºû¿ûçûéûêûü>üDüFüüÊüÌüÒüÔü.ý0ýFýHýRýýý¾ý þþ þ þþõêßζ¶¶« « ««« ~ ζ«~« «¶ « ¶ « ζ« ß« ß hBWhN2CJaJhBWh¡MN5CJaJ hBWh CJaJ hBWhgx5CJaJ hBWh¡MNCJaJhBWhgx55CJaJhBWh 5CJaJ hBWhgx5CJOJQJ^JaJ hBWhrsCJaJ hBWhÃe{CJaJ hBWh}WcCJaJ15ûlû¹ûºûçû>üÌüFýHýýþ:þ<þþþÄþâþÿ3ÿSÿuÿ¾ÿøøðøøøøðèÝÎðÆÆÆÆÆ¾ÆÆ¶ $a$gdËcv $a$gdn~Þ $a$gdöpE $©¤1$`©a$gdöpE
$¤1$a$gdöpE ¤1$gdöpE $a$gdJ ¤gdöpEþþþþþ-þ0þ7þ8þ:þ;þ<þ?þ^þ_þeþþþþþþõêõêßêÔêßò¡n]L]; hBWhn~ÞCJOJQJ^JaJ hBWhçÓCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhò@CJOJQJ^JaJ hBWhv²CJOJQJ^JaJ hBWhôY°CJOJQJ^JaJ hBWhöpECJOJQJ^JaJ hBWhn~ÞCJOJQJ^JaJ hBWhrsCJOJQJ^JaJ hÿsæh/7CJaJ hBWhgx5CJaJ hBWhrsCJaJ hBWh}WcCJaJ þ¢þ©þ²þÄþÇþÞþáþâþåþêþÿ
ÿÿ!ÿ3ÿ6ÿ@ÿIÿSÿVÿWÿ|ÿÿ¾ÿÁÿÃÿäÿèÿéÿìÿöÿÿÿïÞͼ«¼ÞxÞÍïÍÞ«¼ÍxÍïÍ«ÍÍxÍgxÍ hBWhÕ /CJOJQJ^JaJ hBWhò@CJOJQJ^JaJ hBWhçÓCJOJQJ^JaJ hBWhv²CJOJQJ^JaJ hBWhnøCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhËcvCJOJQJ^JaJ hBWhn~ÞCJOJQJ^JaJ hBWhö ±CJOJQJ^JaJ!¾ÿéÿD¶ J¼ò&Ð(Â
C^¬ç():÷÷ï÷ç÷÷÷ç÷÷÷÷÷ç÷÷÷÷ßÚÓÓÓ ¤gdJgdJ $a$gdÈ $a$gd«PR $a$gdËcv $a$gdöpE$(*BDR`|¶¼Ò
$FHXf¼Âèîòø
"$ïÞïͼ«¼Í¼Þ¼ïÞxgVÞgÞÍÞVÞxgVÍV hBWhv²CJOJQJ^JaJ hBWhò@CJOJQJ^JaJ hBWhc&2CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhnøCJOJQJ^JaJ hBWhçÓCJOJQJ^JaJ hBWhËcvCJOJQJ^JaJ hBWhö ±CJOJQJ^JaJ hBWh«PRCJOJQJ^JaJ hBWh&fãCJOJQJ^JaJ!$4BÆÎÐØ`¾ÂÈÎCF\ablm¤«³ºäïÞïÍÞ¼ïÍÞ«ÞÍÞ«ïïïÞïͼïxÞgïVïÞï h/7h/7CJOJQJ^JaJ hBWhÕ /CJOJQJ^JaJ hBWhØWlCJOJQJ^JaJ hBWhc&2CJOJQJ^JaJ hBWhò@CJOJQJ^JaJ hBWhLsoCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhnøCJOJQJ^JaJ hBWhö ±CJOJQJ^JaJ hBWh«PRCJOJQJ^JaJ!äçê()1<>CKPQSTUXeïÞïͼ°¥°°y°myd\QI>° h/7hgx5CJaJ hGQCJaJ h/7h/7CJaJ h*EàCJaJhd~95CJaJhBWhN25CJaJh/75CJaJhBWh}Wc5CJaJhBWh 5CJaJ hBWhgx5CJaJ hÚ-hgx5CJaJhBWhgx55CJaJ hBWhgx5CJOJQJ^JaJ hBWh´ðCJOJQJ^JaJ hBWhnøCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ£¨«±¿ÈÖ×âã
<=>X\¡¢õíõâ×âÌÁ×âõ¶í¶ªª¶í¶õ{odYNY hBWhrsCJaJ hBWhà_oCJaJ hBWhnøCJaJhBWhà_o5CJaJ hÚ-hà_oCJaJhBWhrÙ5CJaJhBWhQNÒ5CJaJhBWh Zö5CJaJhBWhÃe{5CJaJ hBWhÃe{CJaJ hBWhLsoCJaJ hBWh ZöCJaJ hBWhN2CJaJ hBWhgx5CJaJ hd~9CJaJ hBWhrÙCJaJÙ=>X¢£Æ,. $ Ì Î
W
Ô
*
p
ú
ðððééééééééééééééééßÍé $ü©¤^ü`©a$gdJ $¤a$gdJ ¤gdJ ¤^`gdJ¢£¨ÆÊèìñ *,.8z|~ ¨$ 0 ¤ ¦ Æ È Ì Î Ø
W
[
|
~
õéÝÒÇÒ¼ÒDZǦéÝÝÝÒÇÒDZy±ÇnéÝÒÇÒÇc hBWh ICJaJ hBWhgx5CJaJ hBWhí<{CJaJ j$ðhBWhÃe{CJaJ hBWhnøCJaJhÑ
5CJaJ hÚ-hgx5CJ
aJ
hBWhÃe{CJaJ hBWh CJaJ hBWhgx5CJaJ hBWhN2CJaJhBWhgx55CJaJhBWh 5CJaJ hÚ-hò@CJ
aJ
%
¡
§
¬
°
·
É
Ô
×
ì
(
*
F
l
p
v
¬
°
ö
ø
ú
òçÜÑÆ»¯£¯¯ÑwÑwÑwÑlaVÑÆ hBWhW@CJaJ hBWhQNÒCJaJ hBWhN2CJaJ hBWhÉçCJaJhBWhÉç5CJaJhÑ
5CJaJhBWh I5CJaJhBWh 5CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWhgx5CJaJ hBWh ICJaJ hBWhí<{CJaJ hBWhnøCJaJ j"ðhBWhÃe{CJaJú
ü
È
I · å /^Ö
dú\âäa÷ììäääÜäÜÔÜÜÔääÌäÊžÅÅ ¤gd
*7gdÏ
¼ $a$gd
KV $a$gdñW½ $a$gdÆ) $a$gdà_o
$$$a$gdnø $a$gdJú
ü
B
°
º
Æ
È
Ö
3 E H I L R S T U ¤ · º À ñàÏàϾÏàzÏÏiÏÏX hBWh/s"CJOJQJ^JaJ hBWhñW½CJOJQJ^JaJ hBWhò@CJOJQJ^JaJ hBWh@öCJOJQJ^JaJ hBWhÆ)CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhnøCJOJQJ^JaJ hBWhrÙCJOJQJ^JaJ hBWhÕ /CJOJQJ^JaJhBWhgx5CJ OJQJ^JÀ È Ì Ð Õ Ö Ý Þ â è î ï ð !()-/DK^ago²³ÁÃÈÏÐÔÖëò
6TVbdèïÞÍÞÍÞ¼ÞͫޫÍï«ï«ÞÍÞÞ«ÞïÞ¼ÞͫޫÞïÍÞÍï«ï«ÞÍÞÞ«ÞïÞ¼Þï hBWh
KVCJOJQJ^JaJ hBWh/s"CJOJQJ^JaJ hBWh@öCJOJQJ^JaJ hBWh /ûCJOJQJ^JaJ hBWhÆ)CJOJQJ^JaJ hBWhñW½CJOJQJ^JaJ hBWhtºCJOJQJ^JaJ6èøú6\bpª®²º¼ÊÎâä)6v¥ïÞÍÞ¼«Þx«mamVNVamaVC hBWh`-)CJaJ hÿ2®CJaJ hBWhgx5CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWh3KÃCJOJQJ^JaJ hBWhñW½CJOJQJ^JaJ hBWhrÙCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWh@öCJOJQJ^JaJ hBWh
/CJOJQJ^JaJ hBWh
KVCJOJQJ^JaJ hBWhtºCJOJQJ^JaJ , 8 H J P Z f v x ¤ ´ õððäÛÛÛÛäÏÏÏÏÁ¶±ÛÛÛÛFf¤
$1$IfgdLr
$$1$Ifa$gdhb_
$$Ifa$gdõ $IfgdÏ
¼
$$Ifa$gdhb_gdÏ
¼ $¤a$gdõ ¥µ½¾×Ø 8 F f t ¤ ² ¶ À à ê ø *6LZ^jv¢°´ÂÄÎÜÞìðþ óèÝèÒèÆ»««««}««««}««}}«}}«}hÑ
hÑ
CJOJQJaJhÑ
hõ CJOJQJaJ-hÑ
hÑ
5CJOJQJaJ-hÑ
hõ 5CJOJQJaJ hBWhgx5CJaJhBWhgx55CJaJ hBWhÉçCJaJ hBWh1ÖCJaJ hBWh`-)CJaJhpæh`-)5CJaJ/´ ¶ À Ê Ô Þ à ê ö ø (*6@L\^jtvöêêêêêßßÚöööööêêêêêßßÕööFfr-Ff
$1$IfgdLr
$$Ifa$gdõ $IfgdÏ
¼¢²´ÄÎÞîð
Iu¦þT«¬¼PöööêêêêêßßÚÒÊÊÊÊÊÊÊÊÊÊÊ $a$gd¢Wi $a$gdÈFf#
$1$IfgdLr
$$Ifa$gdõ $IfgdÏ
¼
CHLO[st¦©ÏÓÔØñýþ58;RS[ipq§ª«ïÞÐ޿п®¿Ð¿ïÞïïÞï¿Ð¿Þ~¿Ð¿ï¿ïïÞïphgx5CJOJQJ^JaJh KCJOJQJ^JaJ hBWh¢WiCJOJQJ^JaJ hBWh@öCJOJQJ^JaJ hBWh&fãCJOJQJ^JaJ hBWh4pCJOJQJ^JaJh[aCJOJQJ^JaJ hBWh3KÃCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ'«¬ÃÎÒ NúFHJ°²"nprtÐÒÔÚ
'(BCrst¨©ïáÐáÐáÐáÐáп®¢®®ynnyyfyn hpæCJaJ hBWhÎnqCJaJ hBWhÞw.CJaJ h KCJaJ hÿ2®hgx5CJaJ hBWhgx5CJaJhBWhgx55CJaJ hBWhgx5CJOJQJ^JaJ hBWh[aCJOJQJ^JaJ h[ah[aCJOJQJ^JaJh[aCJOJQJ^JaJ hhCJOJQJ^JaJ(PüHJ°²ÔB©+v-x--V ÷÷ïêâêâÛÛÛÛÛÛÓËÃê»°
$$
&
F gdñJ $$gdñJ $$gd[a $$gd[a $a$gd&fã ¤gd@ö $a$gdÚ-gdÚ- $a$gdÈ $a$gd¢Wi©«ÏÐÑÞ+¨¶·ÆÈ-t-v-x-¬-à-6 V z | ¦ õêßÔêÔêüê±ê¦ê
ê}rfêêfUGhBWhgx50J%5CJaJ hBWhgx50J%CJOJQJaJhBWhgx55CJaJ hñJ hñJ CJaJ h1ÖCJaJ hBWhØsCJaJ hBWhæ sCJaJ hBWh¿wCJaJ hBWh CJaJ hBWhæMáCJaJ
hBWhgx5 hBWhñJ CJOJQJ^JaJ hBWhÎnqCJaJ hBWhÞw.CJaJ hBWhgx5CJaJ hÿ2®hgx5CJaJ¦ ª À È Ê &!Z!\!^!`!p!°!²!´!¶!¼!Ð!Ò!æ!ê!ü!
"""$"&""ö"
#,#6#õêßêßêßêÔêÔȽ±¥Èê±wllÔaYN hBWh CJaJ hpæCJaJ hBWh¿wCJaJ hBWh1ÖCJaJhBWhs#+5CJaJhBWh{&a5CJaJ hBWhs#+CJaJ hBWhÏ<CJaJhBWhØs5CJaJhBWhÏ<5CJaJ hp
hgx5CJ
aJ
hBWhgx55CJaJ hBWhØsCJaJ hBWhæ sCJaJ hBWhgx5CJaJ h:hgx5CJaJV ²!´!ê!&"À$¬%®%v&x&9(:((Ô())3)_)w))Á)Â)f*Þ*÷ìçß×ÏìçìçìçÇÇÇÇÇÇÇÇìçÇ $a$gd1Ö
&
Fgd1Ö
&
FgdLk²
&
Fgd1Ögd1Ö
$$$a$gdp
&
F gdLk²6#X#|#ª#Ô#À$Â$Æ$ %L%R%T%%%¢%ª%¬%®%Ê%Ì%Ü%&$&&&(&R&t&v&x&Ì&è&ê&ò&B'J'`'r' ((( ()(õêâêõ×õ×õÌõÁ¶®¶£êêÌ×£¶£u£×ê£êiuhBWh{&a5CJaJhBWhgx55CJaJ hBWhïQÊCJaJhBWhïQÊ5CJaJ hp
hïQÊCJ
aJ
hBWhgx5CJaJ hÿ2®CJaJ hBWhï
CJaJ hBWh"`ôCJaJ hBWh1ÖCJaJ hBWhs#+CJaJ hpæCJaJ hBWhÏ<CJaJ hBWh¿wCJaJ))(*(7(8(9(:(Q((((¾(¿(À(Â(Å(Ó(é(ê(ð(ó(ÿ()))) )-).)/)H)I)O)R)^)q)r)óçÛçÐçźũ©vk©©vk©Z©Z©©©vk© hBWhmCJOJQJ^JaJ hpæhGQCJaJhGQCJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWh-"hCJaJ hBWhgx5CJaJ hp
hgx5CJ
aJ
hBWhÏ<5CJaJhBWhgx55CJaJhBWhæMá5CJaJ#r)s)))¥)¦)§)«)®)°)±)À)Á)Â)Ø)L*\*f*h*j****¦*°*´*Ü*+++ìÛìÛÊìÛ¼±¼±Û¦ÛvÛeìÛeWLÛve ho/lho/lCJaJho/lCJOJQJ^JaJ hBWh^OCJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hÿ2®CJaJ hBWhgx5CJaJhBWhgx55CJaJ hp
hc<¨CJ
aJ
hpæhGQCJaJhGQCJOJQJ^JaJ hBWhICJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ+
+ ++6+8+P+Z+\+`+b+l+r+++¶+º+¼+¾+Ä+Ê+ò+ô+ö+ , ,,,,,,,0,1,8,9,:,ìÛÍÂÛ±Û ±ìÛÍÂÍÛ±ìÛÍÂÛvÛ±ìvÛvÍÂhÂ`Û ho/lCJaJh½7CJOJQJ^JaJ hBWhlCCJOJQJ^JaJ h½7CJaJ hBWhICJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWh^OCJOJQJ^JaJ ho/lho/lCJaJho/lCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ$Þ*8++ö+:,},Õ,-d-¯-û-../0/â/R00 0æ01ô1Â3Ä34÷÷÷÷÷÷÷÷÷÷÷÷ò÷÷÷÷÷ãò÷Ø÷
$$$a$gdp
¤^`gd1Ögd1Ö $a$gd1Ö:,P,W,Y,Z,[,\,],^,_,b,e,|,},£,¤,¥,ïÞͼ«ÞÞxmeZI«5& j®ðhBWhîf´CJOJQJ^JaJ hBWhîf´CJOJQJ^JaJ ho/lhgx5CJaJ ho/lCJaJ ho/lho/lCJaJho/lCJOJQJ^JaJ hBWhuûCJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ hBWhICJOJQJ^JaJ hBWh^OCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhlCCJOJQJ^JaJ hBWh>wCJOJQJ^JaJ¥,§,¨,²,´,·,Ô,Õ,î,ï,ð,÷,ù,
--5-6-7->-@-J-T-c-d-{--------®-²-Æ-ïáïÓÈÀ¯yÓÈÀyÓÀÈÀhWyhÓÈÀh hBWhICJOJQJ^JaJ hBWh>wCJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ hBWh^OCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhîf´CJOJQJ^JaJ ho/lCJaJ ho/lho/lCJaJho/lCJOJQJ^JaJh*EàCJOJQJ^JaJ hBWh.#ËCJOJQJ^JaJ"Æ-Ê-Ë-Ì-Í-Ó-Ö-Ý-à-ú-û-.".&.(.:.>.@.B.D.V.Z.^.x.ïÞ͹¨ïveTveTeÍ@Í& j®ðhBWh.#ËCJOJQJ^JaJ hBWh.#ËCJOJQJ^JaJ hBWh1ÖCJOJQJ^JaJ hBWh$CJOJQJ^JaJ ho/lho/lCJaJ ho/lCJaJho/lCJOJQJ^JaJ hBWh>wCJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ hBWhICJOJQJ^JaJ hBWh^OCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJx....®.¼.¾.Ò.Ô.â.è.,/./0/8/x/¾/Â/Ð/Þ/à/øðè×É»{jYH:H:Hh:CJOJQJ^JaJ hBWhICJOJQJ^JaJ hBWhuûCJOJQJ^JaJ hBWhØWlCJOJQJ^JaJ hBWhuûCJaJ hA1CJaJ hÿ2®hÿ2®CJaJ& j®ðhBWhÿ2®CJOJQJ^JaJhÿ2®CJOJQJ^JaJhÜ\ÕCJOJQJ^JaJhA1CJOJQJ^JaJ hÿ2®hÿ2®CJOJQJ^JaJ h.#ËCJaJ ho/lCJaJ h½7CJaJ à/0 0ä0æ0ø011111111®1ò1ö1ø1282H2N2X2Z2~22¢2¸2º2Ü2æ2ò2 3F3b3d3ïÞÒÁ¶ª¶ª¶ª¡ª¶¶x¶x¶xp¶¶p¶hx¶x¶x hLk²CJaJ h:CJaJ hBWh\ÝCJaJ hBWhbg)CJaJ hIuoCJaJ hIuohIuoCJaJhIuo5CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWhICJOJQJ^JaJhBWhI5CJaJ hBWhc<¨CJOJQJ^JaJ hBWh 5CJOJQJ^JaJ#d3v3À3Â3Ä3Ì3Î3â34 4"4:4x444 4¶4Ê4Ô4ä4æ4è4þ4"5(545D5~5555 5´5Â5Ì5Ö5ì5ïÞÍ·¯·§§···}q}·}·}q}·f}}§}§ hBWh^OCJaJhßG>hgx55CJaJ hBWhgx5CJaJhßG>håNr5CJaJ hBWhÑW|CJaJ hIuoCJaJ h~PCJaJ h:CJaJ hBWhåNrCJaJ h<<«håNrCJaJ hBWhgx5CJOJQJ^JaJ hBWhbg)CJOJQJ^JaJ hBWh.#ËCJOJQJ^JaJ$4è4 5*7,7ä:æ: ;";ïïêâêÊÊUtkd0%$$IfF4Ö
Ö0ºÿã"U
Ô
ÿÿÿÿÖ0ÿ
ÿ
ÿ
ÿ
ÿÿ öööÖÿÿÖÿÿÖÿÿÿÿÿÖÿÿ4Ö
Faöf4 $$¤$If^`a$gd1Ö $a$gdgdLk²$77^7`7a$gd1Öì5 6 606d6f66Ü6Þ6ä6$7&7(7*7,74767R7t7x7î78"8:8L8N8d8l8n8x88888´8Æ8È8Ð899D9z9õêß×Ïß×Äßêßêß¹ê±ê¦ê¦êê}u¦êêêjê hIuohIuoCJaJ hIuoCJaJ hBWh§kÔCJaJ h_¹CJaJ hBWh· ËCJaJ hBWh(²CJaJ hBWhÑW|CJaJ h:CJaJ hh/ôCJaJ hBWh^OCJaJ h~PCJaJ h ?lCJaJ hBWhgx5CJaJ hBWhåNrCJaJ hBWhbg)CJaJ)z9æ9è9þ9:<:p:r:¢:¬:º:â:ä:æ: ;$;<;@;ª;ð;ü;J;çÏÏ· $$¤$If^`a$gd1Ö $$¤$If^`a$gd1Ö $$¤$If^`a$gd1Ö>;@;ª;Î;ì;î;gOOOO $$¤$If^`a$gd1Ökdû%$$IfFÖ
Ö\ºÿë9!ã"U
Üÿÿÿÿ
Nÿÿÿÿ
ªÿÿÿÿ
Ö0ÿ
ÿ
ÿ
ÿ
ÿÿ öööÖÿÿÿÿÿÿÿÿÿÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö
Faöî;ð;ü;"
Ö\ºÿë9!ã"U
ÿÿÿÿ
Ü
N
ª
Ö0ÿ
ÿ
ÿ
ÿ
ÿÿ öööÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿÿÿÿÖÿÿÿÿ4Ö
FaöH>b>>»> ?,@gbbbUbPH $a$gd1ÖgdI
n7^n`7gd1Ögd1Ökd($$IfFÖ
Ö\ºÿë9!ã"Uÿÿÿÿ
Ü
NªÖ0ÿ
ÿ
ÿ
ÿ
ÿÿ öööÖÿÿÿÿÿÿÿÖÿÿÿÿÖÿÿÿÿÖÿÿÿÿ4Ö
Faö =$=*=.=x=¦=è=>>>(>=>A>B>V>W>a>o>v>>>»>Ì>?? ????õêõßõßõÔɽ²õ§õ²§²§²õ²wfU hBWhª~ûCJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ h<<«CJaJ hBWhICJaJhBWhI>*CJaJ hBWhØWlCJaJ hBWhgx5CJaJhBWhæ:ë>*CJaJ h<<«h§kÔCJaJ hBWh§kÔCJaJ hBWhª~ûCJaJ hBWhÑW|CJaJ hBWh
CJaJ??@,@\@l@n@p@r@@@¦@¨@ú@AAAA6A8AnAvAxAzA|AðAòAôAöAøA4BjBnBpB®B°BìÛʹÊÛì۹ʨʹÊìÊۨʹÊÛìÊÛìÊÛrg hh[WCJaJ& j®ðhBWh-"hCJOJQJ^JaJ hBWh-"hCJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWh=@ECJOJQJ^JaJ hBWh(²CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhª~ûCJOJQJ^JaJ& j®ðhBWhgx5CJOJQJ^JaJ#,@¨@8AÄA4B®B°BüB¢CD2DD6E`E¬E.F/FFFwFÊFúFLGMGÒG÷÷÷÷ç÷ßßßßßßßßßßÚÑÑÑÑÉÚ $a$gd<<«7^7gd<<«gd<<« $a$gdKo$77^7`7a$gd1Ö $a$gd1Ö°BØBøB@D|D-F.F/FDFFFFµFG4GLGMGÒGÓGùGýGH,H/H9H=HïÞïÐï¿´¨´~sbPbï>ï>#hBWhKo5CJOJQJ^JaJ#hBWh>w5CJOJQJ^JaJ hBWh>wCJOJQJ^JaJ hhCJaJ hBWhgx5CJaJ h_¹CJaJ hBWhKoCJaJhBWhgx55CJaJhBWh»y:5CJaJ hhKoCJaJ hBWhgx5CJOJQJ^JaJh·CJOJQJ^JaJ hBWh¶CJOJQJ^JaJ hBWhKoCJOJQJ^JaJÒGÓGHSHTHJJL L^LsLtLL[MQQLQîQRR*R,R¢R÷÷÷ïêïï÷÷÷âÚÚÕïÍÍÍ;÷÷ ¤^`gd})Ê $a$gd})Êgd1Ö $$gd
$a$gd<<«gd $a$gd $a$gd1Ö=H>HAHOHQHSHTHÙHøH JJJZJbJrJzJJJJJJ¬J¶JºJÊJÌJÎJÐJÒJÖJîJKKKKPKRKTKVKKK¤KïÝïÝïÒǼDZ¦±±±y±y±±yq±y±±y±y hÉ)æCJaJ hBWhÑ/CJaJ hBWhlCCJaJ hBWh^3CJaJhBWhgx5>*CJaJ hhgx5CJaJ hBWhgx5CJaJ hBWhKoCJaJ hBWh»y:CJaJ hh»y:CJaJ#hBWhKo5CJOJQJ^JaJ hBWhKoCJOJQJ^JaJ)¤KàKüKLLL LL1L;L=L>L?L@L\L^L`LaLsLtLLL¡L¬L®L¯L²L·L¹LõêßÔßɸ§¸¸
¸
t¸i]QßIßQßIß h·CJaJhBWhgx55CJaJhBWhgx5>*CJaJ hp
hgx5CJ
aJ
hBWhKoCJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWh?vCJOJQJ^JaJ hBWhÛdCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hhgx5CJaJ hBWh?vCJaJ hBWhgx5CJaJ hBWhÑ/CJaJ hBWhRÞCJaJ¹LºL¾LÆLÈLÉLËLÑLÒLÔL×LÝLßLàLáLåLìLîLïLôLMMMM
M MMM M&M'M(M)MDMEMXMYMZM´N6OBOOÈOÊOàOòOPPÈPôPóèàèóèàèóèàèóÔèàèóèàèóèàèóèàèàɽɽɲÉè§§èè²èè~ hBWh[|CJaJ h}ôCJaJ hBWhÛdCJaJ hBWhðq CJaJ hBWhï
CJaJ hBWhhCJaJhBWhlC5CJaJ hBWhlCCJaJhBWh·5CJaJ h·CJaJ hBWhgx5CJaJhBWhgx55CJaJ1ôPøPQQQ.Q6QLQTQQòQôQRRR*R,R4RRRþRS
S S$S&S:S
U?UxU®UçU-V.V/VØVÙVWdWW0XbX
YfY¤YòYZZ÷÷÷÷÷÷òòòêêòòå÷÷÷÷÷÷÷÷÷÷÷ågd1Ö $a$gdyxOgdyxO $a$gd1ÖBSDSXShSSªSäSêS
U
U-VïÞïÞïÞͼͫͫͫK¼«Í¼«ÍÞ«ÞÞxïxgx hBWhÛdCJOJQJ^JaJ hBWhyxOCJOJQJ^JaJ hBWhéYÕCJOJQJ^JaJ hBWhðq CJOJQJ^JaJ hBWhÜ8CJOJQJ^JaJ hBWh=@ECJOJQJ^JaJ hBWhf3TCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhÐTøCJOJQJ^JaJ#-V.V/V0V1V2VCVDVJVNVOVkVVVV¨V°VÖV×VØVÙVÜVÝVòáØÏØÃ¸¥¸n]L hBWhJfCJOJQJ^JaJ hBWhÜ8CJOJQJ^JaJ hhgx5CJOJQJ^JaJ h*EàCJaJ h<;ÕCJaJ hBWhgx5CJaJ hBWhxCJaJ hÆüCJaJ hBWh&hCJaJ hBWh
Y YYYdYfYpY¤Y°Y¼YÆYÒYØYòYöYøYZZ$ZDZFZïÞͿͮͮ{®{jï{Þ{Í_VJVh KhlQ5CJaJhlQ5CJaJ hBWhJfCJaJ hBWhÙ&çCJOJQJ^JaJ hBWhCJOJQJ^JaJ hBWh@GTCJOJQJ^JaJ hBWhÚGêCJOJQJ^JaJ hBWhxCJOJQJ^JaJhG&¼CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWhÊ=ÞCJOJQJ^JaJ hBWh×nCJOJQJ^JaJFZHZJZZZZØZþZ
[[$[Z[ [¤[¦[Æ[È[Ê[ô[ö[]2]4]6]`]b]!^"^2_3_4_Ð`Ñ`Õ`Ö`õíâ×í×â×Ì×â×»±§±±±§±±±±r»j^hlQhlQ5CJaJ hÊ
áCJaJ hBWh©mCJOJQJ^JaJ hh©mCJOJQJ^JaJhBWhJf5CJ hBWhJfCJ hBWh@GT5CJhBWhJf5CJ hh³6 CJOJQJ^JaJ hBWh CJaJ hBWhJfCJaJ hBWh³6 CJaJ hlQCJaJ hBWhlQCJaJ!Z¤[¦[Ê[ ]6]!^"^<^m^ðèÜÜÜÜjÜ[$$$$Ifa$gd1Öqkd )$$IfFÖÖ0ºÿDÎ&Ö0ÿÿÿÿÿÿ ö 'ööÖÿÿÖÿÿÖÿÿÖÿÿ4Ö
Faö
$$$Ifgd1Ö $a$gd ¤^`gd1Ö m^¡^»^¿^Å^ë^ _._2_3_4_S_óêêÞÞêêêldd $a$gd1Öqkd¡)$$IfFÖÖ0ºÿDÎ&Ö0ÿÿÿÿÿÿ ö 'ööÖÿÿÖÿÿÖÿÿÖÿÿ4Ö
Faö
$$$Ifgd1Ö $Ifgd1Ö
$$Ifa$gd1Ö
S_s_¨_Ñ_`A`z`½`Ð`Ñ`%a~a£aâa6c@dAdkdwd÷÷÷÷÷÷÷÷ïàÕÕÆ¸¸¥ $$¤gdk $$gdk
;ý¤`;ýgdLk²
$$;ý¤`;ýgd
j ©¤^j `©gd1Ö
;ý¤`;ýgd1Ö ¤^`gd1Ö $a$gd $a$gd1ÖÖ`ç`è`ê`ÿ`aa#a$a%a)a.a3a8a
<5CJaJ hBWh CJaJ hBWh^¹CJaJ hBWh
hBWhgx5 hBWhCJaJ h^¹CJaJ hBWhxCJaJ hBWhJfCJaJ hBWh
dCJaJ hBWhc<¨CJaJhBWh 5CJaJhBWh^¹5CJaJ hBWh
&
F$gd K
^`gd5ò
¤`gd
d $$¤gdk¦d¨dÔdÖdádådee)e:egbghg~g¸gàghPhxhhh h¢h¤h¦h¼hÊhèhðhi@iBiàiòióçÜÑÜÆÑÜÑÜÆ¾ÆÜ³Ü¨ç¨³Ü¨Æ¨Æ¨¾¨¨ç¨Ñ¨Ñ¨ hÉ)æCJaJ hBWhùãCJaJ hBWh CJaJ hBWh]aëCJaJ hBWhgx5CJaJ hBWh[|CJaJ h KCJaJ hBWhò
ËCJaJ hBWh±mCJaJ hBWh5òCJaJhBWhgx55CJaJhBWh5ò5CJaJ-òiôijjTjXjdjhjÔjk$k¨k°k²kØkÚkl"lÔlÖlælôl
m`m m¤mªm°m²m¼mÌmÐmZndnànìn oo6oõíõíõíâ×í×ËâÀâÀâË⵬ ¬ âââââââwkhBWhÈ5CJaJ hkhÞw.CJaJ hBWh CJaJ hBWhò
ËCJaJ hÁCJaJhBWh]aë5CJaJhÉ)æ5CJaJ hkh]aëCJaJ hBWhùãCJaJh½7h]aë5CJaJ hBWh{&aCJaJ hBWh]aëCJaJ hÉ)æCJaJ hBWhõßCJaJ&6oFojolo|o~oo¶o¸oºoîoðo!pqptp{ppppp®p²p´p¹pÂpÃpÉpÌpÓpÖpõêßêõÔÉõßõßõ¾¶®¶¾ß¢|peZ¢NhBWhdE5CJaJ hBWhdECJaJ hBWh"ICJaJhBWhõß5CJaJhBWh 5CJaJhBWhè=5>*CJaJhBWhè=5CJaJhBWh"I5CJaJ h})ÊCJaJ hCJaJ hBWhõßCJaJ hBWh~WCJaJ hBWh]aëCJaJ hBWhgx5CJaJ hBWh±mCJaJ hBWhÈCJaJÖpØpÛpÝpæpèpøpúpÿpqNr^rnrrr¶rºrÀrÈrÖrÚrÜrörs0sLsPsóçóçÛÐź¯¤
zo¯ç¯z¯dº¯XLXh*Eàhgx55CJaJh*EàhdE5CJaJ hBWh"ICJaJ hBWhè=CJaJ hBWhé#¿CJaJ hv>îCJaJ hBWhõßCJaJhBWhõß5CJaJ hBWhlYCJaJ hBWhdECJaJ hBWhgx5CJaJ hBWhÈCJaJ hÁhÈCJaJhBWhgx55CJaJhBWhdE5CJaJhBWhÈ5CJaJNrÚrFt£tÿtLvNvævvw w$x1xzx§xñx$yvy¡yöyhzõæÙÑļ´´´´´´´´´´´´©
$$$a$gdÃMÎ $a$gd° $a$gdÈ
^`gd!6 $a$gdlQ
^`gdBN ¤^`gdÞw. ^`PsRsTsVsXss´sþst
ttt5tî5CJaJ hlQCJaJhBWhBN5CJaJ hBWhgx5CJaJ hCJaJhlQh5CJaJ h½7h"ICJaJh Kh K5CJaJh Kh"I5CJaJ hBWh"ICJaJ hBWh{&aCJaJ hv>îCJaJ hBWhdECJaJ hBWhBNCJaJh*EàhBN5CJaJõtýtþtÿtu u
uNuOuRuSuTuuuv@vHvJvLvNvvõêßÓËÀµª~s~~h]L; hBWh°CJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWh!6 CJaJ hBWh¿{RCJaJ hBWh{2CJaJ hBWhê
¶CJaJ hBWherCJaJ hBWhlYCJaJ hBWhE3ÀCJaJ htu=hE3ÀCJaJ htu=h!6 CJaJ htu=hlYCJaJ hlQCJaJhlQhlQ5CJaJ hkhdECJaJ hBWhÞw.CJaJ h½7hÞw.CJaJ vºvævw>w@wzw|w#x'x]x^x|x}xxxuyvyöyzdzfznzzJ{L{N{\{^{ª{ïÞÐÞ¿Þ®Þ®Þ¿Þ®Þ®ÞÞÞÞ~ÞmÞaXM hBWhê
¶CJaJhlQ5CJaJhlQhlQ5CJaJ hBWh!6 CJOJQJ^JaJ hBWhÁCJOJQJ^JaJhÁCJOJQJ^JaJ hBWhðCJOJQJ^JaJ hBWhlYCJOJQJ^JaJ hBWhÐTøCJOJQJ^JaJhß#¯CJOJQJ^JaJ hBWh°CJOJQJ^JaJ hBWhé#¿CJOJQJ^JaJhzºzL{N{Ü{Þ{?||À|}.}~ ¨Ðþ*xàô ôììÜÑÑÑÑÉÁÁÁÁÁÁÁÁÁÁÁÁÁ $a$gd $a$gdk
$$$a$gdÂc
$$^`gdÂc
$a$gd°
$$$a$gdÃMΪ{Ú{Ü{Þ{ä{1|B|C|O|S|r|s|||À|Ï|}}}}-}b~~~¬®ÔÖô dfâãøíÜ˺˺˺©ºËºËºËºËº©©©v©©vee© hBWhiNCJOJQJ^JaJ hBWhðCJOJQJ^JaJ hBWhCJOJQJ^JaJ hBWhlYCJOJQJ^JaJ hBWhE3ÀCJOJQJ^JaJ hBWhgx5CJOJQJ^JaJ hBWh{2CJOJQJ^JaJ hÂc
ht8 CJ
OJQJ^JaJ
hBWhê
¶CJaJ hlQCJaJ'ãö÷
(5,02TXZ èBP¨ÆÌêìîôïÞïÞïÍïÍï¼Þï¼Þï±¥|q|q|q|q|`O hBWh³xpCJOJQJ^JaJ hÂc
hiNCJ
OJQJ^JaJ
hBWherCJaJ hBWh{2CJaJhBWh{25CJaJ#hBWher5CJOJQJ^JaJhBWher5CJaJ hBWhè=CJaJ hBWhðCJOJQJ^JaJ hBWhiNCJOJQJ^JaJ hBWhE3ÀCJOJQJ^JaJ hBWhCJOJQJ^JaJ 7
Ñ,T ìîrÔF
n
ÊÌl^÷÷÷÷÷÷òêÛÓËËËËÆ·¬¬¬
$$$a$gd;0o ¤^`gd;0ogd;0o $a$gdÚGê $a$gdÂc
¤^`gdßG> $a$gdßG>gdãi
$a$gdônpx|ÌÐÔ
$
F
J
L
l
n
p
ü
ÈÊ̦¨ØÞïÞÍÞÍÞÍÞ¼ïÞÍïÞ®¢zi®i[Mh
iCJOJQJ^JaJhI,õCJOJQJ^JaJ hBWh;0oCJOJQJ^JaJh;0ohgx55CJaJ hBWh;0oCJaJ h;0oCJaJh;0o5CJaJh;0oh³xp5CJaJh;0oCJOJQJ^JaJ hBWhU
çCJOJQJ^JaJ hBWherCJOJQJ^JaJ hBWh³xpCJOJQJ^JaJ hBWhÍ5pCJOJQJ^JaJÞ !FGJ\]^s~·ÑÛÞøûü!"2òäòÖòÖòÈ·¦äÖ¦Öä¦äòÖä¦wk`U hBWhgx5CJaJ hBWhiNCJaJhBWhiN5CJaJh¯TQ5CJaJhBWhÙXc5CJaJhþPB5CJaJ hÂc
hgx5CJ
OJQJ^JaJ
hBWh;0oCJOJQJ^JaJ hBWh´MÏCJOJQJ^JaJh
iCJOJQJ^JaJhI,õCJOJQJ^JaJh;0oCJOJQJ^JaJh´MÏCJOJQJ^JaJ^¦¸Âûü$àâ^º¼\ Ë
EFº÷÷÷÷ïêêïÞÎïÉÁ¹¹¹¹¹ï¹¹ $a$gd)g $a$gdÈgdLk² $Á ^Á `a$gdt6
$^a$gdì-÷gdiN $a$gdÂc
$a$gd;0o2@^t ò02FRf¶ÜÞàâö 0<BLPZ\^óçÜçóçÜÑÜÆÑ»Ü³¨Üçsgss^sRshBWhãi
5CJaJhÁ5CJaJhBWh1¥5CJaJhBWht65CJaJhBWhì-÷5CJaJhBWh 5CJaJ hÂc
hgx5CJ
OJQJ^JaJ
hÂc
hÂc
CJaJ hÂc
CJaJ hBWhì-÷CJaJ hBWh_}mCJaJ hBWhÍ5pCJaJ hBWhgx5CJaJhBWhgx55CJaJhBWh_}m5CJaJ-^`blvz|¤¨ª´¸º¼ÖØÚôöø<JL ¬ óçÛÏçÆçóÛϺƺÛç©óóÆçÆó|t|t©c hBWh)gCJOJQJ^JaJ htu=CJaJ hBWhaRCJaJ hBWhÙXcCJaJ hBWht6CJaJhBWhÐTø5CJaJ hÂc
hÙXcCJ
OJQJ^JaJ
hBWh1¥5CJaJhÁ5CJaJhBWh 5CJaJhBWhgx55CJaJhBWht65CJaJhBWhÙXc5CJaJ# Ëùú
,-EFÝÞô:¾ÀüþFHTVXbrvïÞÍÞïÞïÞ¿Þ®ÞÞÍÞïÞïÞ¿Þth\hhÁhÁ5CJaJhÁh 5CJaJhÁhÐTø5CJaJhÁhgx55CJaJ hÂc
h)gCJ
OJQJ^JaJ
hBWhåzÑCJOJQJ^JaJ hÂc
h_}mCJ
OJQJ^JaJ
hCJOJQJ^JaJ hBWh_}mCJOJQJ^JaJ hBWh)gCJOJQJ^JaJ hBWhÍ5pCJOJQJ^JaJ-ºô:ºFH¶¸8öøx¾ÀÛR\^âd
÷÷÷÷ïêïââïêÝââÝÛÒÛêÝâÊÊ $a$gdÈ7`7gdÐTøgdãi
$a$gd_}mgdLk² $a$gdÂc
$a$gd)gÈèìö$^hÈÔ06²¶¸ <>õéÝÔéÈéõ½õ²õ²õéõ§õ
t
t
cWKWhBWhÐTø5CJaJhBWhgx55CJaJ hÂc
hgx5CJ
OJQJ^JaJ
hBWhÍ5pCJOJQJ^JaJ hBWh_}mCJOJQJ^JaJ hÂc
hmLÓCJ
OJQJ^JaJ
hÁhÐTøCJaJ hÁhÚ!éCJaJ hÁh CJaJhÁh 5CJaJhôKË5CJaJhÁhÁ5CJaJhÁhgx55CJaJ hÁhgx5CJaJª®¸À
f¨Ê^prtvÐðöøTV|~¾ÀÒÖ-:EóêÞóÞÓóÞÓÈÓ½ÓÞ¯ÞÓ¤ÓwwlaÓ½V½ hBWh
CJaJ hBWh_}mCJaJ hÂc
hgx5CJ
aJ
hBWhÍ5pCJOJQJ^JaJ hBWh_}mCJOJQJ^JaJ hBWhmLÓCJaJ hBWhÐTøCJaJhBWhgx55CJH*aJ hBWhÚ!éCJaJ hBWh CJaJ hBWhgx5CJaJhBWhgx55CJaJhÁ5CJaJhBWh 5CJaJ-EKklm|¤§¨ØÝÞäéñòøùþ"%&)R£±²¶ÒàNVXZõêõßõÔÈÔõê½ÔȱȥÈÔÈÔÈÔxmÔõê½m½õêbêõ hBWhGwCJaJ hBWhÐTøCJaJ hBWhmLÓCJaJ hBWhâ@CJaJ hBWh CJaJhBWhÐTø5CJaJhBWh 5CJaJhBWhO¨5CJaJ hBWhñ-ACJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWhÚ!éCJaJ hBWh
CJaJ hBWhåzÑCJaJ&Z\^dâfr
!*,.bcz¿ÀãæQTmno¦ÝõêÙÈ·¦·Ù·¦·Ù·¦··¦····ypi^S^ hBWhôKËCJaJ hBWhs%~CJaJ
hBWhgx5hBWhà
'CJ hBWhgx5CJOJQJ^JaJhôKËCJOJQJ^JaJhÐ3æCJOJQJ^JaJ hBWhÍ5pCJOJQJ^JaJ hBWhé#¿CJOJQJ^JaJ hBWhñ-ACJOJQJ^JaJ hBWh¿{RCJOJQJ^JaJ hBWh¿{RCJaJ hBWhgx5CJaJ-
+AzãQnoÜÞð _ º d¢ü¢÷÷÷ï÷÷÷çåàÛÛÒÉÉÀÀ´«h^hgdy
$h^ha$gdÅTh^hgdÅiEh^hgdlfh^hgd;égd;égdt $a$gd/4ê $a$gdÍ5p $a$gdÈÝÞàZfjrvÎ.02468PVÀÐØÚÜÞêðø
õêßÔÌÄÌÔ¹ê®Ä£¹®ê¹¹®õ£xl`lhBWh³4d5CJaJhBWh>5CJaJhBWh À5CJaJhBWhlf5CJaJ hBWh³4dCJaJ hôKËCJaJ hBWhlfCJaJ hBWh¿{RCJaJ hBWhW`CJaJ hSCJaJ h'CJaJ hBWhô3òCJaJ hBWh@5DCJaJ hBWhs%~CJaJ hBWh4_CJaJ" . G M O R U ] ^ _ i r s
§ ¨ ª ¬ ´ µ º ¿ À ¢"¢.¢8¢<¢÷îèîßîÖîÏ÷«·«··Ã«Ã|ëÃsis`s`shBWhÅTCJ hBWhy5CJ hBWhyCJ hBWh³4d5CJaJhBWh&h5CJaJ hBWhÅiECJaJhBWhwu5CJaJhBWh>5CJaJhBWhÅiE5CJaJhBWhlf5CJaJ
hBWhlfhBWh6 qCJ hBWhGwCJ
h*EàCJ hBWh&hCJ hBWhlfCJ !<¢\¢b¢d¢ª¢¬¢Ä¢Æ¢Î¢à¢ü¢£0£~££££¸£Â£Ê£¤¤*¤,¤H¤J¤^¤f¤j¤¤Ü¤Þ¤à¤â¤¥ ¥"¥$¥¥¥¥õìâÖÊÖÊÖ¾Öìµì¯ì¯ì¦ìÖÊÖÊÖÖ쵦
~rÊrhBWhlf5CJaJ
hBWhlfhBWh³4dCJ
hôKËCJ hBWhlfCJ hôKË5CJaJhBWhÅTCJ
h#FCJ hBWh}WcCJ hBWhÅiE5CJaJhBWh>5CJaJhBWhy5CJaJhBWhy5CJ hBWhyCJ hôKËhy5CJ (ü¢Ê£^¤$¥¨¥¦,¦.¦¢¦¤¦2¨¢©¤©æª~«¬¬¯¯ööííííãÖãÑÑÑѲ²¨£gdãi
gd¿{R -dð ¤gd;é-
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9gdlfgd³4d
hÏ^h`Ïgd;é -dð ¤gdlfh^hgdlfh^hgdy¥¥¥¥¨¥°¥ê¥ì¥î¥ð¥ ¦¦,¦.¦6¦8¦B¦D¦F¦L¦N¦P¦Z¦d¦l¦r¦|¦¦¦¦¦¢¦¤¦óçÛçÏúúîç£ççzncUçççç£hBWhlf5>*CJaJ hBWh!
|CJaJhúHPh!
|5CJaJhúHPhúHP5CJaJhôKË5CJaJhúHP5CJaJ hBWhlfCJaJ hBWhlfCJaJhBWh!
|5CJaJh·7Ú5CJaJhBWh&h5CJaJhBWh À5CJaJhBWh>5CJaJhBWhlf5CJaJhBWh³4d5CJaJ ¤¦¨¦¼¦î¦
§ §§0§R§§§¢§,¨.¨0¨2¨J©L© ©¢©¤©â©ªZªzª¸ªºªÒªæª"«.«F«R«º«Æ«à«ì«õéõÞõÞÒÞÒÞÒÞÇÞǼ±¼©ÞÞõõÞo^o^o^o^ hBWhwuCJOJQJ^JaJ hBWhlfCJOJQJ^JaJ hBWh¶CJaJ h}CJaJ hBWh³4dCJaJ hß#¯hß#¯CJaJ hÝj]CJaJ hBWh¿{RCJaJ hBWhÝj]CJaJ hBWhW`CJaJhß#¯hlf5CJaJ hBWhlfCJaJhôKËhwu5CJaJ hBWhwuCJaJ$쫬¬´¬ô¬~¬ìîð&®2®8®:®`®®®¬®"¯$¯&¯¯¯¯¸¯Ø¯ú¯~°ïäÙÎÙÎÙ檶ª¶¶ªª¶|Ùqe\eQ hBWh<¯CJaJhÏJ*5CJaJhBWh<¯5CJaJ hBWh@5DCJaJ hBWh£mÑCJaJ hBWh4_CJaJhBWh¶5CJaJhBWh8Æ5CJaJhBWh£mÑ5CJaJhBWh4_5CJaJhBWhy5CJaJ hBWh8ÆCJaJ hBWhgx5CJaJ hBWhlfCJaJ hBWhlfCJOJQJ^JaJ~°°Â°Ñ°Û°å°æ°ñ°ò°ó°±
±±±±±,²6²<²t²²²À²øíÜËܺ˩Ü˺|pdpYMAYhBWhsz5CJaJhBWh¶5CJaJ hBWhszCJaJhBWh6 q5CJaJhBWhy5CJaJ hBWhgx5CJaJ hBWhÅTCJOJQJ^JaJ hBWh ÀCJOJQJ^JaJ hBWhyCJOJQJ^JaJ hBWhèZçCJOJQJ^JaJ hBWhwuCJOJQJ^JaJ hBWh<¯CJOJQJ^JaJ hBWh<¯CJaJ hôKËCJaJ¯Â°Ã°ó°±±<²³®³¶´¸´ôµöµ ¶h¶À¶ ·
·b·´·û·úòòòíèààààÚòò¸¸¸¸¸¸¸"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gd¿{R@&gdLk² $a$gdLk²gdLk²gdãi
$a$gd¿{Rgd¿{R À²à²â² ³³"³$³L³¬³®³Ê³Ò³ú³6´t´x´´´¶´¸´¼´Æ´Ê´Ö´ôµöµüµ¶¶óëàØÌàÁàØÌàÁà¶à®à£ÌàxgVg hBWh}WcCJOJQJ^JaJ hBWh5ICJOJQJ^JaJ hBWhLNdCJOJQJ^JaJhBWhsz5>*CJaJhBWhªvµ5CJaJ hBWhLNdCJaJ h'CJaJ hBWh;éCJaJ hBWh}WcCJaJhBWhsz5CJaJ hLk²CJaJ hBWhszCJaJ hPqCJaJhPqhPq5CJaJ¶#¶B¶]¶f¶g¶h¶À¶Î¶Ú¶å¶ý¶þ¶ÿ¶·· ·
··%·&·'·5·8·9·Q·T·`·b·p··©·¶·Ë·Ù·ï·ð·ñ·ïÞïÞÍÞÍÞ¼Þ¼®¼®¼Þ¼¼ÞÞ~pÞ_Þ_Þ_Þ_®_ hBWh;éCJOJQJ^JaJhß#¯CJOJQJ^JaJhPqCJOJQJ^JaJ hBWh}WcCJOJQJ^JaJ hBWhô3òCJOJQJ^JaJhôKËCJOJQJ^JaJ hBWh½xCJOJQJ^JaJ hBWh@4CJOJQJ^JaJ hBWh5ICJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ%ñ·ò·ú·û·ü·H¸¸Ä¸Ü¸ò¸ ¹¹0¹2¹4¹6¹8¹d¹z¹~¹¹¢¹¼¹¾¹À¹Â¹Ä¹Ô¹XºZº\º^ºàºâºäºæºøºúº(»*»4»6»D»l»p»ü»òáÐÅдддá´ò´ò´Ð´Ð´á´ò´ò´ÐáòáòáòáòáŨ¨¨{ hBWh½xCJaJ hBWh!OCJaJ hBWhszCJaJhBWhh5CJaJhBWhsz5CJaJ hBWh½xCJOJQJ^JaJ hBWh5ICJaJ hBWh5ICJOJQJ^JaJ hBWh;éCJOJQJ^JaJhôKËCJOJQJ^JaJ-û·ü·¨¸¹H¹¹Ô¹8ºpºÀºøºúºà¿â¿EÀÀëÀ:ÁõÓÓÓÓÓ±±±±õ¬õ¤¤¤¤ $a$gd¿{Rgd¿{R"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gd;é"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gd¿{R -dð ¤gd;éü»0¼6¼\¼Ô¼à¼ ½F½ ½¾¾¾D¾R¾^¾¾¦¾Ì¾Ô¾ò¾ü¾>¿|¿¢¿ª¿Þ¿à¿â¿IÀRÀjÀõêßõßõßõÔõÔõÉõÔ¾Ô²Ô²Ô§Ô²Ôo^ hBWhÀtCJOJQJ^JaJ hBWhd"YCJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ hBWhszCJaJ hBWhszCJaJ hBWh'pCJaJhBWh!O5CJaJ hBWhasìCJaJ hBWhHòCJaJ hBWh!OCJaJ hBWhLNdCJaJ hBWhVRhCJaJ hBWh:GNCJaJjÀyÀÀÀÀÀ«À»ÀÇÀßÀàÀáÀâÀãÀëÀ.Á/Á0Á1Á:ÁHÂJÂLÂNÂ`ÂbÂdÂïÞͼ﫫«{{{jjjYMhBWhh5CJaJ hBWh<¯CJOJQJ^JaJ hBWh ekCJOJQJ^JaJ hBWh)^&CJOJQJ^JaJhôKËCJOJQJ^JaJ hBWhVRhCJOJQJ^JaJ hBWhd"YCJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ hBWhagCJOJQJ^JaJ hBWhÀtCJOJQJ^JaJ hBWhEsCJOJQJ^JaJ:ÁÁäÁ`ÂbÂ.Ä0ÄþÄÇÇ!È^È¶ÈøÈùÈÊÍÍ*ÎÎÝÕÝÍÈÈÀÀÍÍÍÍÍ»³³Í«Í $a$gdasì $$gdakgdãi
$$gd´MÏgd¿{R $a$gd¿{R $a$gd ek"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gd ekdÂp ¢¾ÂÐÂæÂÃÃ(ÃTÃtÃÃÂÃÄÃÊÃâÃäÃöÃÄÄ Ä*Ä,Ä0Ä<ÄdIJĴĶĸÄìÄóçóßÔßÔɾ߾ßɳɨ¨ßɨÉ}Ôqeq\q\qh#F5CJaJhBWh}Wc5CJaJhBWhy5CJaJ hBWhhCJaJ h·7ÚCJaJhUIDh·7Ú5CJaJhUIDh>5CJaJ hBWh>CJaJ hBWh ekCJaJ hBWh'pCJaJ hBWhtCJaJ hBWhHòCJaJ h#FCJaJhBWh ek5CJaJhBWhHò5CJaJ!ìÄöÄþÄÅÅÅ"Å>ÅLÅÅŠŢÅâÅ
ÆpÇzÇÇÇ!È/È9ÈDÈUÈ^ÈbÈȵȶÈÒÈÞÈêÈøÈùÈÿÈóçÜÐÇÐܼܴܴܩܩÜvevevvvevevZç hBWhýv¡CJaJ hBWhVRhCJOJQJ^JaJ hBWhýv¡CJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ h´MÏhSéCJOJQJ^JaJ hBWh¶CJaJ h#FCJaJ hBWhSéCJaJh#F5CJaJhBWhö,p5CJaJ hBWhö,pCJaJhBWhy5CJaJhBWh6 q5CJaJ"ÿÈÊJÊLÊNÊPÊÊÊÊËÊËôËXÍbÍÍÍ*ÎFÎZÎÎÎ΢ÎäÎÏÏóçÞçÞçÒçǼ±¼±¼ ~m~m~\~K~ hBWhEsCJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ hBWhVRhCJOJQJ^JaJ hBWh@5DCJOJQJ^JaJ hBWhasìCJOJQJ^JaJ hakhmLÓCJ
OJQJ^JaJ
hBWh¶CJaJ hBWh@5DCJaJ hBWhSéCJaJhBWh6 q5CJaJhôKË5CJaJhBWhy5CJaJhBWh}Wc5CJaJÏ ÏHÏfÏzÏ~ÏÏÏϪÏÀÏÄÏÆÏÔÏÖÏìÏ(Ð6Ð\Ð^ÐxÐ ÑhѤÑÒÒ ÒïÞͼͫͼͼÍ{p{p{p{eZ{I hakhuCJ
OJQJ^JaJ
hBWh6 qCJaJ hBWhtCJaJ hBWhVRhCJaJ hBWh6CJaJ hPqCJaJhPqhPq5CJaJ hakh6CJ
OJQJ^JaJ
hBWhýv¡CJOJQJ^JaJ hBWhVRhCJOJQJ^JaJ hBWh@5DCJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ hBWhSvCJOJQJ^JaJÎJÏÄÏÆÏÒ ÒÒ$Ó~ÓøÓ0ÔÚÔ4Õ¶ÕîÕðÕÖLצרTØüئÙÚWÚXÚ÷÷ïê÷ââ÷÷÷÷÷÷÷ÚÚÚÚÚÚÚÚÚÚ÷ $a$gdóG& $a$gdßG>gd¿{R $a$gdak $a$gd¿{R ÒÓ"ÓVÓ|Ó~ÓÓ¨ÓøÓþÓ0Ô@ÔBÔRÔ4Õ:ÕDÕdÕpÕÕ¶Õ¼ÕìÕîÕðÕ®Öö֦׬ר$ØÚÚWÚïÞïÍï¼Íï¼ïÞÍÞͼͫͫͼͼx¼g¼g¼g¼ hBWhãi
CJOJQJ^JaJ hBWh°ÏCJOJQJ^JaJ hakhóG&CJ
OJQJ^JaJ
hBWhÑÜCJOJQJ^JaJ hBWh)^&CJOJQJ^JaJ hBWhóG&CJOJQJ^JaJ hBWh@4CJOJQJ^JaJ hBWhVRhCJOJQJ^JaJ hBWhuCJOJQJ^JaJ!WÚXÚ,Û6Û7ÛLÛMÛÛÛÜÜÜÜ¸ÜºÜæÜèÜìÜÝ(ÝdÝ|ÝÝݰÝÔÝÚÝêÝüÝTÞVÞïÞÍÞÍÞͼ«««xg«g«Yxgxgxx«x¼hPqCJOJQJ^JaJ hBWh¿lCJOJQJ^JaJ hBWh¢ìCJOJQJ^JaJ h´MÏh¿lCJOJQJ^JaJ hBWhãi
CJOJQJ^JaJ hBWhVNÙCJOJQJ^JaJ h´MÏh¢ìCJOJQJ^JaJ hBWhóG&CJOJQJ^JaJ hBWh)^&CJOJQJ^JaJ h´MÏh)^&CJOJQJ^JaJXÚ¡ÚûÚMÛÛÛÔÛÜܸܺÜfÝÔÝTÞVÞfÞÞÞPßòßpàêàìà
á÷÷÷÷÷÷÷÷÷÷÷÷÷÷ÕÕÍÍÍÍÍÍÍ $a$gd#F"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gd¿{R $a$gd¿{RVÞbÞdÞfÞÞÞòßààXàZà\à^àpàààÒàÔàÖàØàèàêàìàTá´á¸áÀáÄáâ@âTâ\âbââóçÞÓ±£±±±£±±±v££ee£e h0Buh0BuCJOJQJ^JaJ hd'Íh0BuCJ
OJQJ^JaJ
h#FCJOJQJ^JaJh0BuCJOJQJ^JaJh)rÈCJOJQJ^JaJ hBWh#FCJOJQJ^JaJ h´MÏh#FCJOJQJ^JaJ h0Buh0BuCJaJh¢ì5CJaJhBWh¢ì5CJaJhBWhÓ&5CJaJ!
á¸áVâââÂãÄã0äÒäfåååú宿RçÚçÜçHèè÷è÷÷÷ïÊ¿·¿¯¯§§§§§§¯¯¯ $a$gd
¾ $a$gd¿{R $$gdd'Í
$$$a$gdd'Í%$$$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gdd'Í $a$gd´MÏ $a$gd#FâââÀãÂãÄã.ä0äDäNäÎäÐäÒäfålåååRçXçÚçÜçïÞÓÈ·¦yhWhFhWh5 h<<«hpCJOJQJ^JaJ h´MÏhÓ&CJOJQJ^JaJ hBWhãi
CJOJQJ^JaJ hBWhÓ&CJOJQJ^JaJ hBWhVNÙCJOJQJ^JaJhPqCJOJQJ^JaJh
CJOJQJ^JaJ hBWh
CJOJQJ^JaJ hakhÓ&CJ
OJQJ^JaJ
hBWh¢ìCJaJ hBWhVNÙCJaJ h´MÏh#FCJ
OJQJ^JaJ
hBWh0BuCJOJQJ^JaJ Üç,è0è2èEèGèKèsètèuèè è¡è£èÎèÏèöèúè:éXéYéqéréxéyé|ééµé¸é×éê´ê¶ê"ë<ë®ë°ë¾ëÄëæëðë ì#ìCìDì½ìïÞÍÞïÞïÞÍïÍïÍïÍïÍïÞïÞÍÞï¼Þï¼ï«ÞÞÍÞÍÞ¼ÞÍÞ¼Þx hBWhVCJOJQJ^JaJ h* ýh5 CJOJQJ^JaJ hBWh6CJOJQJ^JaJ hBWh½cãCJOJQJ^JaJ hBWhãi
CJOJQJ^JaJ hBWh£2%CJOJQJ^JaJ hBWh5 CJOJQJ^JaJ hBWh ÷CJOJQJ^JaJ-÷è2éyéµéØé¶ê>ë¾ë ìCìDììïìGííÍíîÄîüîþîòò'ò]òìò÷ïïïïïïïïïïïïïïïïïïêïããÙ $¤a$gd%: ¤gd%:gd%: $a$gd%: $a$gd¿{R½ìßì>íEííÍíÐíHî~îîÂîÄîÊîüîþîï<ï>ïDïPïTï`ïbïdï ï¢ï¤ïïÞÍ¿ÞÍÞ®Þ®ÞÍÞuj_WuOuOu h#FCJaJ h%:CJaJ hBWhagCJaJ hBWh ÀCJaJ hBWhÅiECJaJ hþUÅCJaJhþUÅhþUÅ5CJaJhé·5CJaJ h<<«h ÀCJOJQJ^JaJ hBWhE6CJOJQJ^JaJh
¾CJOJQJ^JaJ hBWhãi
CJOJQJ^JaJ hBWhVCJOJQJ^JaJ hBWha3nCJOJQJ^JaJ¤ïôïöïð2ð6ðVðZð|ðððð¶ðñ ñhñjñ ñ²ñ¶ñÆñìñüñ òòòòòòò,ò2ò5ò7òHòKòMò]òbògòõíõíõáÙáÍÅõáÙ½Ùõµµµ¥µµÙthththBWh À5CJaJhBWh>5CJaJhBWhgx55CJaJ h2ZûhyCJOJQJ^JaJ h%:CJaJ hCJaJ h2ZûCJaJ h* ýCJaJ hëoCJaJ hm èCJaJh2Zûhm è5CJaJ h·7ÚCJaJh2Zûh·7Ú5CJaJ h#FCJaJ hBWh#FCJaJ'gòxò~òòòòò£ò¨òò®ò±òÂòÌòÍòÎòÒòÓòÔòÕòçòèòëòïòñò8ô¢ôÈôÒôõ>õóçÛÏÃÛÃÛúÃó¥ÃÃ{pepYhm èh7÷5CJaJ hBWhÑ5CJaJ hBWh7÷CJaJ hm èCJaJ hBWhÅiECJaJ hBWh ÀCJaJhBWh>5CJaJh·7Ú5CJaJhBWh* 5CJaJhUID5CJaJhBWhgx55CJaJhBWha3n5CJaJhBWhÀ$05CJaJhBWh7÷5CJaJhBWhÅiE5CJaJìòïò ú~úú(ûØû*üTütüÆüýFýfýýÉýúýOþþÂþæþôïàØØÐØØØ®Ð®®ØØØØØØØ"$
Æ2( ¼
P äx
4 È#\'ð*.2¬5@9a$gda3n $a$gda3n $a$gd¿{R ¤^`gda3ngd%:
¤`gd%: >õ@õJõLõdõvõõ0ö<öDönöôö÷^÷`÷÷÷²÷¸÷Î÷Dø¶øàøùùzù|ùºùÂùìùú ú.ú>úJúfúzú~úóçÜÑÜÑÜÆÜÆÜºÆÜÑÆ¯ÆÜÆÑ¤Ñ¤ÑxÑxmÑ hBWhèZçCJaJ hBWh* CJaJ hBWh6CJaJ hBWhE6CJaJ hBWhSvCJaJ hBWha3nCJaJ hBWhÑ5CJaJhñXìhre5CJaJ hBWhreCJaJ hBWhagCJaJ hBWhÀ$0CJaJhm èh7÷5CJaJhm èhÀ$05CJaJ%~úú(ûØûøûúûü ü
üü*ü8üEüPüTüWü]üdüeühüiüjüküsütüVýWýXýYý`ýaýfýÉýËýúýïÞͼ®¼®¼¼{¼Í¼®¼®®jͮͮͮÍYÍY hBWhÂ
CJOJQJ^JaJ hBWhOCJOJQJ^JaJ hBWhVCJOJQJ^JaJ hBWhagCJOJQJ^JaJ hBWhèZçCJOJQJ^JaJhm èCJOJQJ^JaJ hBWhSvCJOJQJ^JaJ hBWha3nCJOJQJ^JaJ hBWhªvµCJOJQJ^JaJ h2ZûhagCJOJQJ^JaJ"úýÂþÅþæþéþÿÿ ÿ!ÿ@<.02PpÌ ¸t:<¾ÀÐïÞïÞïÐï¿®§|||kcX hm èhm èCJaJ hexICJaJ h2ZûhexICJOJQJ^JaJhBWhß5CJaJhBWhexI5CJaJ hÏJ*CJaJ hBWhexICJaJ
hBWhexI hd'ÍhexICJOJQJ^JaJ hBWhVCJOJQJ^JaJhm èCJOJQJ^JaJ hBWha3nCJOJQJ^JaJ hBWhOCJOJQJ^JaJ!æþ!ÿ"ÿ@¼¢vÀnoÈ" @ ÷÷òíäÜíÊÊ´Êʯ¯§§§§§ $a$gdexIgdLk² $
Æ3 ª¤^ª`a$gdexI $ª¤^ª`a$gdexI $a$gdß7`7gdßgdexIgdt $a$gd¿{RÐ2Dno^ c ß è
q
{
ø
ý
!
"
)
ð
ö
(
.
b
þ
T n NøíâÚâÏâij¢³¢³³¢³¢³ÄâtÚâÚâÚâijf³h 4CJOJQJ^JaJ hBWhl
CJaJh<<«5CJaJhBWhexI5CJaJh> CJOJQJ^JaJ hl
hexICJOJQJ^JaJ hBWhexICJOJQJ^JaJ h%:hexICJaJ hBWhßCJaJ hl
CJaJ hBWhexICJaJ hm èhm èCJaJ hm èCJaJ" Á
S
Ú
!
"
þ
àNÖØ*ÌDX¸Ìv 02÷÷÷÷÷÷÷ïç÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷ $a$gd%: $a$gd<<« $a$gdexINTf¤ÖØÞæ¤ÌÐ.024p ¢¤¦ v z æ
*.02:ïÞÐÞÅÞ³Þ¢Þ¢ÞïÐïÐÞïÞïÐÞÐÞÞ¢Þ¢Þud`h\)' h<<«hY
ûCJOJQJ^JaJhexICJOJQJ^JaJ hBWhëoCJOJQJ^JaJhëoCJOJQJ^JaJ hBWhs
CJOJQJ^JaJ#hé·hé·5CJOJQJ^JaJ h%:hexICJaJhl
CJOJQJ^JaJ hBWhexICJOJQJ^JaJ hBWhßCJOJQJ^JaJ%:RTh~tª¬À8jklm
¥¦ª#ÈÒ*lx~ª- -"-D-üõüõîãÛãÛãÒÆ½Æ´Æ´Æ«ÆãÆãÆãÆãÆãÆãÆãÛãÆãw h§3rCJaJ h|BÉCJaJh§3rhY
û5CJaJh§3rh§3r5CJaJh§3rh|BÉ5CJaJh|BÉ5CJaJhkÔ5CJaJh<<«5CJaJhBWhY
û5CJaJhY
û5CJaJ hY
ûCJaJ hBWhY
ûCJaJ
h\)'hY
û
hBWhY
ûhY
û,2¬à:Dx[ x~â-ä-l úòëëëáÓáÓÈȶ¶§§¢ $a$gdY
ûgd MJ ¤^`gdY
û $$¤^`gdUE
¤`gdY
û
$¤`a$gdY
û $¤a$gdY
û ¤gdY
û $$gdY
ûgd\)'D-F-J-d-p-|-- -Þ-â-ä-V X f h ¦ ¨ ¬!®!ê!ì!î!ð!0"8"b"r"z"æ#ê#ô#öîæîæîÞîÓÈ·¦·····yky·ZkZ h MJh MJCJOJQJ^JaJhÕ|~CJOJQJ^JaJh§3rCJOJQJ^JaJhkÔCJOJQJ^JaJ hBWhkÔCJOJQJ^JaJ hkÔhkÔCJOJQJ^JaJ hBWhY
ûCJOJQJ^JaJ h<<«hY
ûCJaJ hBWhY
ûCJaJ hQaCJaJ h MJCJaJ h§3rCJaJh§3r5CJaJl ø ^!!þ!z"#F#¼#ö#2$Ö$þ$%4&Ø&'x'Ê'(V(i(j(((Ñ(,)h)÷÷÷÷÷ïïïïï÷÷÷÷÷÷÷÷÷÷÷÷÷ê÷÷÷gd MJ $a$gd MJ $a$gdY
ûô#ö#*%,%.%0%&'('X'Z'\'^'.(/(i(j(((«((])^)º)»)¼)½)* *Ü*Ý*Þ*ß*++È+É+Ê+Ë+Æ,Ç,----%-&-(-8-òáÓáÓáÓáÓáÓáÓá·¬ááÓáÓáÓáÓáÓáÓáÓáÓáÓáÓáÓáÓá
hBWhÆyÅ
hBWh Zö h<<«hõJCJOJQJ^JaJhëoCJOJQJ^JaJ hëymhY
ûCJaJ hBWhY
ûCJaJ h%:hY
ûCJOJQJ^JaJhkÔCJOJQJ^JaJ hBWhY
ûCJOJQJ^JaJh MJCJOJQJ^JaJ/h))Ä)*n*ª*ÿ*Z++é+:,,Ñ,%-&-8-d/f/0T1Ò1Ô1>3¾3÷÷÷÷÷÷÷÷÷÷÷÷÷ïêåååÝÝå×Í
&
F1$gdYì1$gdYì
&
FgdõJgdõJgdt $a$gdõJ $a$gdY
û8-s--..&.H.t....¤.ö.ø.
/$/`/b/d/f///¢0²0Ò1Ô1è1@5Ð5Ü5ú5ü5þ577 7õêÞêõÓõËûÃõ³§³õ³õ§õõ§õ~v~õkõ`§ hÆühÆyÅCJ
aJ
h%:h©CJaJ hé·CJaJ hBWhA
CJaJ hkÔCJaJ hBWhp\×CJaJ h MJhÆyÅCJaJhBWhÆyÅ5CJaJ h%:CJaJ h-iCJaJ hiQpCJaJ héZCJaJ hBWh1CJaJh÷ ,hý»5CJaJ hBWhý»CJaJ hBWhÆyÅCJaJ#¾3\4¶4ü5þ577X7Ä7B88þ9i:j:::%;&;.>õõåßßß××ÏÏļ·····¨ ¤^`gdõJgdõJ $a$gd©
$
&
Fa$gd©
&
FgdõJ $$gdkÔ1$gdYì h¤1$^h`gdYì
&
F1$gdYì 7R7T7X77¸7º78899®9ú9þ9::J:P:h:i:j:::::óçÛÏĹĮģÄÄÏĹÄvhZOG hCmCJaJ hW]h©CJaJhBWh¡@©5>*CJaJhBWh©5>*CJaJ hW]h7CJaJ hBWh¦fCJaJh<Åh©5CJaJ hBWhhCJaJ hBWh CJaJ hBWh
gôCJaJ hBWh©CJaJ hBWhÆyÅCJaJh<ÅhÆyÅ5CJaJhBWhÆyÅ5CJaJhBWh¡@©5CJaJhBWh©5CJaJ: :µ:¶:Ê:ã:ï:;$;%;<(<*<2.>°>????F?Z?^?d?f?
@@-@#@%@(@F@G@õíâí×â×íâÌÀâµâµâªâ××Àµ~Àâµâµâvnvnvnâ h
CJaJ hé·CJaJ hW]h©CJaJ hBWhhCJaJ hBWh¡@©CJaJ hBWhUðCJaJ hBWh}WcCJaJ hBWh½-CJaJhBWh¡@©5CJaJ hW]h¤uCJaJ hBWh©CJaJ hBWh¤uCJaJ hCmCJaJ hBWhCmCJaJ(.>°>??G@t@¾@ñ@BCCDDnE
FWFxFyFÐFþFIGøíèÙÒÒÒÒÒÒÒÒÒȶ±è¬¬¬gdw3gdõJ $ü©¤^ü`©a$gdõJ $¤a$gdõJ ¤gdõJ ¤^`gdõJgd©
©¤`©gdõJ ¤gdh G@_@i@r@t@x@¾@Ü@æ@ñ@BÔBÖBØBÚBêBCCCîCDDDºDÄDEE,ELETEjEnEpE¢E®E.FVFWFtFóçÛóÐÅÛçÛºÛ±Û±ÛçÛºÛçÛºÛ¨ÛÛÛÛºº{ºohBWhUð5CJaJ hBWhUðCJaJ h
CJaJ h:CJaJh¬Hx5CJaJh
5CJaJh:5CJaJh
5CJaJ hBWh½-CJaJ hBWh¤uCJaJ hBWhhCJaJhBWh½-5CJaJhBWhôc5CJaJhBWh¤u5CJaJ&tFwFxFyF=G>GHGIGHÎHäHüIþIJ JJpKrKtKBLCL/M0M7M8M9MFNHNLONO^O`OçPèPïPðPñPxRyRzR{R¢R£RóçÜ˽˯Ë˽˯˯Ë˽˯˽˽Ë˽˯˽˽Ën hBWhor´CJOJQJ^JaJ h
hLYúCJOJQJ^JaJhÚâCJOJQJ^JaJ hKXhKXCJOJQJ^JaJhw3CJOJQJ^JaJh
CJOJQJ^JaJ hBWhw3CJOJQJ^JaJ hëymhntáCJaJhBWh½-5CJaJhBWhntá5CJaJ*IGJGH"I~I JJÄJüJrKtKÖK LBLCLL°LæL8M9MM¢M×MXNÄN^O`OPúúúúúúúúúúúúúúúúúúúúúúúúúõí $$gdUEgdhgdw3P?P~PPðPñP@QQêQ;RORbR£R¤RñR'SiS«SäSþSTºT:U
$a$gdqggdÙ=¿gdõJ $$gd%:gdw31$gdYì1$gdh $$1$gdUE£R¤R½RÀRÁRÃRðRñRS&S'S=SAS[ShSmSnSySãSäStTvTxTzTTT:Uïã×Îû°uduuudVVdh
CJOJQJ^JaJ hBWh
CJOJQJ^JaJh
CJOJQJ^JaJhÙ=¿CJOJQJ^JaJhqgCJOJQJ^JaJ hBWhÙ=¿CJOJQJ^JaJ hqgh--ÞCJaJ hqgCJaJ hqghqgCJaJhqg5CJaJhBWh--Þ5CJaJhBWhUð5CJaJ hX9hw3CJOJQJ^JaJ:U
^;CJOJQJ^JaJ hBWh +CJOJQJ^JaJhÙ=¿CJOJQJ^JaJh
^;CJOJQJ^JaJ hBWh
^;CJOJQJ^JaJ h
^;h
^;CJOJQJ^JaJh
CJOJQJ^JaJ hBWhÙ=¿CJOJQJ^JaJ h
^;h
CJOJQJ^JaJ
^;
$$$a$gd
^;gd +gd
^;gdÙ=¿DYYY¢YÂYìYZZZZ)[*[+[,[X[¨[©[ª[±[²[òáÐÂÐÂÐá´Ð¦veTH?hèb^5CJaJhBWhE4e5CJaJ hrLhó cCJOJQJ^JaJ hBWhrLCJOJQJ^JaJ hrLhrLCJOJQJ^JaJhrLCJOJQJ^JaJ hrLhd'ÍCJOJQJ^JaJhrLCJOJQJ^JaJhÙ=¿CJOJQJ^JaJh
^;CJOJQJ^JaJ hBWh
^;CJOJQJ^JaJ hBWhÙ=¿CJOJQJ^JaJhX9CJOJQJ^JaJ²[³[\]`]]Æ]P^â^ä^Z`ú`¦a*b¨b8cúcad³d e
e\fìfg¾g7húúúúúúúúúõééáááááááÜ×××××gdÙ=¿gd© $a$gdõJ
$7`7a$gdõJgdLk²gd÷ ,²[³[\~\\\]]ò]ô]ö]ø]^^à^â^ä^è^
_F_v_x___ð_`T`V`b`d`v`
a
aïÞÐÞÂбÞÂÞÂÞÂÞ ~r~g\T\ h/ ÑCJaJ hBWhFF#CJaJ hBWhóXóCJaJhµ[hèb^5CJaJh<Åhèb^5CJaJ hBWhó cCJaJ hBWhèb^CJaJ h÷ ,h÷ ,CJOJQJ^JaJ hBWhÌ: CJOJQJ^JaJh÷ ,CJOJQJ^JaJhÌ: CJOJQJ^JaJ hBWh÷ ,CJOJQJ^JaJ hh÷ ,CJOJQJ^JaJ
aa®aÞa,b.bXb`brbvbxbbbbb¤b¨bªb¬b¸bÂbÚbèbúbübc
c cc c&c4c8c:c
eZføíåíÚíÚíÏÚÏÚíÄÚíÏÚí¼Ï±ÏÚ¼ÏÚíÄí±íÏÚí¦Ä¦íÏÚí¦Ä¦í¦ÄíÚ hBWhÙ=¿CJOJQJ^JaJ hëymhèb^CJaJ hBWhA
CJaJ hÿsæh
CJaJ h+.¹CJaJ hBWhó cCJaJ hBWhÙ=¿CJaJ hBWhaCCJaJ hKXCJaJ hBWhèb^CJaJ h/ ÑCJaJ4Zf\fìfHgvggghhh¼h¿hÀhÑh-i i!i"iwixiyizi}i~iijjHjNjòäÖÅÖÅ´¦ÖÖyyyyhWäIäIhCJOJQJ^JaJ hhÙ=¿CJOJQJ^JaJ hBWhLYúCJOJQJ^JaJh
CJOJQJ^JaJ hBWh,W§CJOJQJ^JaJhÌ: CJOJQJ^JaJhó cCJOJQJ^JaJ hBWhÙ=¿CJOJQJ^JaJ hBWhKXCJOJQJ^JaJhKXCJOJQJ^JaJh/ ÑCJOJQJ^JaJhÙ=¿CJOJQJ^JaJ7hShhÒh&i~iiiJjìjBkDkrltlmmnZnqnrn¶nRtSt¬tãtuúúòòíúååååúààØØØØØààààààà $a$gd,V»gd,V» $a$gd/ Ñgd,W§ $$gdUEgdÙ=¿NjPjVjÚjêjìj@kBkDkXk~kkÄkÜkÞkèkòk
l
l(lrltlzl¬l°lòäòäòäÓ·«|q`O> hBWh©R CJOJQJ^JaJ hBWhe!ZCJOJQJ^JaJ hBWht8 CJOJQJ^JaJ hW]he!ZCJaJh<Åh 5CJaJh<Åhe!Z5CJaJ hBWhe!ZCJaJhµ[he!Z5CJaJhµ[h\8Ø5CJaJ hBWh\8ØCJaJ hëymh/ ÑCJOJQJ^JaJ hBWhCJOJQJ^JaJhCJOJQJ^JaJh/ ÑCJOJQJ^JaJ°lÌlmmmmpmmm¤m²mÆmÖmØmämnn n0n1n2n3nn?nCnDnZn]nqnrn¢n´nµn¶nÊnËnïÞÍÞÍÞ¿ÞïÞïÞÍ®Þͮ޿޿޿޿ޮޮÞ|qf hBWhCYêCJaJ hBWhï%ÔCJaJhBWhï%Ô5CJaJh8,]5CJaJhBWhÊp5CJaJ hëymhú@3CJOJQJ^JaJ hBWhÙ=¿CJOJQJ^JaJhC³CJOJQJ^JaJ hBWh©R CJOJQJ^JaJ hBWhe!ZCJOJQJ^JaJ hBWhï%ÔCJOJQJ^JaJ%ËnÞnßnánænínînônõnooooo$o*opp"p$pPpFrNrfrhrjrlrºrørürøíøáÕÉÕø½µ©|qe|ZOZ|ZO|O| hBWh¶$CJaJ hBWhÊpCJaJhBWh"/Ì5CJaJ hBWh8mCJaJ hBWh9SCJaJ hBWh"/ÌCJaJ hBWhHvçCJaJhW]h"/Ì5CJaJhW]hHvç5CJaJ hëoCJaJhëohëo5CJaJhW]h_»5CJaJhW]hz5CJaJhW]hCYê5CJaJ hBWhCYêCJaJ hzCJaJür¦s¨sªsØsPtQtRtStuu¡u´uçuèuéuìuðu®v¯v°v±v½v¾v¿vÀvývþvÿvw
w
w
w w!wõêâÚêâõϾ°¾°¾¢xjjjjjjjjhzCJOJQJ^JaJh-c
CJOJQJ^JaJ hBWh EçCJOJQJ^JaJ hëymh
&ÙCJaJh EçCJOJQJ^JaJh
&ÙCJOJQJ^JaJ h
&Ùh
&ÙCJOJQJ^JaJ hW]h_»CJaJ hÌ: CJaJ hñ3CJaJ hBWh8mCJaJ hBWh_»CJaJ"uluuèuéu=v
vÕv!wcwwÏwðwñw~y>z({*{{||}Æ}úúõõðððððððððáÑÌÇ¿¿¿¿¿ $a$gdÌ0:gdW]gdëym$77^7`7a$gdÊp» ¤^`gdÊp»gd Eçgd
&Ùgd,V»!w$wcwowwwÏwÛwîwïwðwñwøwÿw xxÞxèxìxôxDyzy~yyyyz zïÞïÞïÞïÍÞ¼±¨
z
r
g
[PrPH h-iCJaJ hBWhÁuÐCJaJhBWhÁuÐ5CJaJ hÊp»hzCJaJ hÊp»CJaJ hÊp»hÊp»CJaJ hÊp»hÁuÐCJaJhÊp»hÁuÐ5CJaJhÊp»h 8.5CJaJh-c
5CJaJ hëymhÁuÐCJaJ hBWhÆyÅCJOJQJ^JaJ hBWhWCJOJQJ^JaJ hBWh EçCJOJQJ^JaJ hBWha
CJOJQJ^JaJ z8z:z>zVz`zpz¦z¨z¾zÚzæzôz{
{
{${({*{}Â}z|~øðèÝÑÝèÝÑ莱¥{j\jNC hëymhÌ0:CJaJhÌ0:CJOJQJ^JaJhZ!ÐCJOJQJ^JaJ h¾AñhÌ0:CJOJQJ^JaJ hëymhÄjzCJaJ h-ihÁuÐCJaJ h-ih-iCJaJh-i5CJaJh
gôhñJ 5CJaJhBWhñJ 5CJaJ hñJ CJaJh-ih-i5CJaJhBWhÁuÐ5CJaJ hBWhÁuÐCJaJ h-iCJaJ hu×CJaJ hT'±CJaJÆ}V~æ~R|~ðò^.0¦F¢ìMwñ;
<
^`
0÷÷÷÷ò÷ò÷÷÷ò÷÷÷÷÷÷÷÷÷÷ççç÷÷
$$$a$gdUEgdÌ0: $a$gdÌ0:~ÀÄBîðò "46\l|¶*.0®ÄTÚê(Pbstu~§¯Ìôú
!
9
:
;
<
^üöêâ×â×Ì»»»Ì}h (CJOJQJ^JaJ hñ3hÌ0:CJOJQJ^JaJ hV'9hÌ0:CJOJQJ^JaJhÌ0:CJOJQJ^JaJ hâhÌ0:CJOJQJ^JaJ hëymhÌ0:CJaJ h¾AñhÌ0:CJaJ hÌ0:CJaJh¾AñhÌ0:5CJaJhÌ: 5CJaJ0üþ
ÀÁÅßòû¬ ²ÚÜÞæ ¬® 67òáб¨veWeWeWeFWeWeWe hëymhUTÅCJOJQJ^JaJh\&CJOJQJ^JaJ h\&h\&CJOJQJ^JaJ h\&h\&CJaJ h\&CJaJ h°HÛh 3CJaJ h 3CJaJh 3h 35CJaJhþPB5CJaJ hWhV'9CJ
OJQJ^JaJ
hÌ0:CJOJQJ^JaJ hV'9hÌ0:CJOJQJ^JaJ hV'9h (CJOJQJ^JaJh>;CJOJQJ^JaJ0sÀÁ ªàn´ N® 7gÇ÷ø@A÷÷ïààØØØØØØØØØØØØØÐÐÐÐÐ $a$gdh8 $a$gd\& ¤^`gd 3 $a$gdV'9 $a$gdÌ0:7fg¹»ÂÃÇ÷ø@Av²Æ<=klÆööòáòÓòÓòáòÓòÓòÓÂÓ±©¡©¡©¡©¡
wiw[h[CJOJQJ^JaJh/UnCJOJQJ^JaJhGtCJOJQJ^JaJ hëymhGtCJOJQJ^JaJ hh8hh8CJaJ hGtCJaJ hh8CJaJ hëymhh8CJOJQJ^JaJ hëymhW]CJOJQJ^JaJhh8CJOJQJ^JaJ h\&h\&CJOJQJ^JaJh\&CJOJQJ^JaJ-AZÈ=kl¤ø$aâ>Þ6"#yºÏðæ×æÈÀÀÀÀÀÀÀÀÀ¸¸¸¸¸¸¸ $a$gd[ $a$gdGt 7¤^7`gdGt 7¤^7`gdh8
&
F"¤gdh8 ¤^`gdh8
:<>®!"#yRT Ôàäê"($&òäÖòÈäºäÖ©äthhhhWW hW]hx
CJOJQJ^JaJhW]hx
>*CJaJ hW]hñJ CJaJ hW]hx
CJaJ hëymhm|¢CJOJQJ^JaJhm|¢CJOJQJ^JaJ h (hW]CJ
OJQJ^JaJ
h/UnCJOJQJ^JaJhGtCJOJQJ^JaJhè0CJOJQJ^JaJh[CJOJQJ^JaJh |êCJOJQJ^JaJÏ _¥ºñRT¸,°& HòfÆ÷ïïïïï÷÷ãÛÐÐĵµµ¦¦¦
&
F"
Æ ¤gd]¦ ¤^`gdm|¢
$-^-a$gdè0
$
&
F"a$gdx
$a$gdx
$7`7a$gdx
$a$gdm|¢ $a$gd[ ÀÄÆÚDFHfrv|¤¨°´ºÒÞâîðò"(8ÂÖ>@FÀÂô`bïäÙÎäÆäٻίίÎäί£ä£ä£ä£äÎäääääw» hW]h$UCJaJ hW]h0S=CJaJ hW]hoCJaJ hW]hæ5CJaJhW]hÜk¼>*CJaJhW]hc
v>*CJaJ hW]hÇzCJaJ hv>îCJaJ hW]hc
vCJaJ hW]hx
CJaJ hW]hÜk¼CJaJ h (hè0CJOJQJ^JaJ-bÛ Ü !¡W¡¡¡n¢£Ú£r¤Ô¤Ö¤X¥à¥¦@§<¨>¨íèããã××ÒÒÊÊÊÊÒÒʺµgd
ST
&
Fgdìa
&
FgdÝAG
&
FgdÎ`ÜgdÎ`Ü
$7^7a$gd@&´gd-c
gd¸4U $
&
F"
Æ ¤a$gd]¦ bdÛ Ü ë í ¡ ¡!¡8¡:¡;¡<¡>¡D¡E¡F¡G¡M¡Q¡U¡V¡W¡b¡k¡m¡n¡p¡u¡v¡x¡¡
¡¡¡¡¡¡¢üõíâÖíËíËøáá¸ÃáÃ{pe hëymhgx5CJaJ hBWh*`ÀCJaJhBWh*`À5CJaJ h*`ÀCJaJh@&´5CJaJh©ï5CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWh'@CJaJ h©ïCJaJ hBWh-c
CJaJh©ïh-c
5CJaJ h*`Àh-c
CJ
aJ
h-c
CJaJ
hBWhgx5hW]'¢¢"¢0¢B¢V¢j¢n¢¢£:£°£Ø£Ú£ô£8¤r¤¤Ô¤Ö¤æ¤ö¤¥*¥@¥X¥r¥¥¥Æ¥Ü¥à¥¦¦.¦/¦1¦¦¦¦°¦@§_§§§õêß×ßõêËêËêõêË×êËêÀ¸êõßêË¢õê×êËê¢êõêtt× hBWhìaCJaJhBWhìa5CJaJhBWh^*]5CJaJ hìah^*]CJaJ hìahgx5CJaJ hBWhx:öCJaJ hß¹CJaJ hëymhgx5CJaJhBWhgx55CJaJ hìaCJaJ hBWh4ßCJaJ hBWhgx5CJaJ hBWh^*]CJaJ,§§¢§¨:¨<¨>¨^¨~¨¨Ö¨Ø¨2©©¬©®©Ü©ð©ª,ª0ªDªFªHªTªVªXªvªxª´ª¸ªòª«D«|«Ú«â«¬¬:¬t¬¬¨¬ª¬¶¬æ¬øðøåðÚÎÂη¬Î·Î·Î·¡·¡ð·ð········t·ø· hBWhx:öCJaJhBWh@UP5CJaJ hëymhgx5CJaJ hBWh@UPCJaJ hBWh^*]CJaJ hìahgx5CJaJ hBWhgx5CJaJhBWh^*]5CJaJhBWhgx55CJaJ hëymhìaCJaJ hBWhìaCJaJ hìaCJaJ h×poCJaJ->¨Ø¨©VªXªæ¬è¬B¯D¯Ô²Ö²æ¶è¶\·^·\¸lºnº»8»v»÷ïäßÚÚÚÚÕÐËËÆß¾¾¹±±± $a$gdº ýgdHw
&
Fgd
STgdÖgdkAgdÂ:ïgd-c
gdÎ`ÜgdËo
$
&
F
a$gdÝAG
&
F
gdÎ`Ü
&
F
gdÎ`Ü æ¬è¬ê¬ü¬þ¬ P®@¯B¯D¯\¯^¯b¯°¯²¯Ê¯,±D±X±±î±H²N²V²`²Ò²Ô²Ö²$³>³D³F³³¦³¨³õéÝÒÝéÒÇÒõ»°»°»¨°»»»°¨°»}qfq}[} hBWhì3"CJaJ hZ!ÐhHwCJaJhBWhHw5CJaJ hBWhHwCJaJ hëymhËoCJaJh-c
5CJaJh-yh-c
5CJaJ h-c
CJaJ hBWh-c
CJaJhBWh-c
5CJaJ hBWhsRbCJaJ hBWhgx5CJaJhBWhgx55CJaJhBWhËo5CJaJ hëymhgx5CJaJ#¨³¸³Â³Ê³þ³`´´´´´ª´¾´À´Â´vµÌµâµ6¶D¶l¶z¶¶ä¶æ¶è¶ ·"·@·F·\·^·f·h·j·l·~···\¸j¸n¸®¸Ä¸õêõêõÞÒÇõ¼ê±ê¼¦¼±¼±¼ê
±ymy
y±±±±y±±hBWhÛ·5CJaJhBWhì3"5CJaJ h
SThì3"CJ
aJ
hBWhÖCJaJ hBWhòOeCJaJ hBWhÌ`CJaJ hBWhì3"CJaJ hBWhkACJaJ hZ!ÐhÚvñCJaJhBWhÚvñ5CJaJhBWhòOe5CJaJ hBWhHwCJaJ hBWhÚvñCJaJ*ĸ¹z¹î¹lºnºtºØº»
»T»V»v»|»
¼¼â¼ä¼ô¼ø¼ú¼ ½ ½H½J½j½½½½õêßêÓ± ± ±Â  |qfqfqf[OhBWhÛ·5CJaJ hBWhLCJaJ hBWhËoCJaJ hBWhÛ·CJaJhBWhËo5CJaJhBWhÛ·5CJaJh6hÛ·5CJaJ hBWhÛ·CJOJQJ^JaJ hBWhÖCJOJQJ^JaJ hBWhº ýCJOJQJ^JaJhakhì3"5CJ
aJ
hBWh*PCJaJ hBWhì3"CJaJ hBWhÖCJaJv»
¼n¼â¼ä¼n½½ ¾.¾/¾H¾Ì¾¿&¿'¿¶Á¸ÁúÁÄÄdÅæÅrÆÇôôìçççâÝØçØØØçççÓÓÎÎÎÎÎgdÞpùgdÎ`Ügdº ýgdQõgdËogdÛ· $a$gdº ý
$$$a$gdëym½½Ê½Ô½ ¾¾ ¾¾¾.¾/¾G¾H¾_¾d¾e¾¾öêÞêÓȽµê©r]C]2jhBWhÛ·B*CJOJQJU^JaJph)hBWhÛ·B*CJOJQJ^JaJph)hBWhº ýB*CJOJQJ^JaJph hBWhÛ·CJOJQJ^JaJ hBWhº ýCJOJQJ^JaJh6hº ý5CJaJ hQõCJaJ hBWhÛ·CJaJ hBWhº ýCJaJ hBWhLCJaJhBWhº ý5CJaJhBWhÛ·5CJaJhQõ5CJaJ¾¾¾É¾Ê¾Ë¾Ì¾õ¾û¾¿¿$¿&¿'¿Í¿ÀÀÔÀzÁ®Á¶Á¸ÁÐÁÔÁøÁãɸ£É¸}¸}¸}qf[f[f[fqOAOhBWh*P5>*CJaJhBWh*P5CJaJ hBWhËoCJaJ hBWhÛ·CJaJh6hÛ·5CJaJ hBWhÛ·CJOJQJ^JaJ)hBWhÛ·B*CJOJQJ^JaJph)hBWhº ýB*CJOJQJ^JaJph hBWhº ýCJOJQJ^JaJ2jhBWhÛ·B*CJOJQJU^JaJph8j.*hBWhÛ·B*CJOJQJU^JaJphøÁúÁüÁúÂ6ÃfèòÃ,ÄÄÄÄĪÄ"Å2ÅfÅpÅàÅâÅæÅðÅöÅ Æ*Æ,Æ8ÆXÆ\ÆbÆfÆhÆnÆpÆtÆ~ÆÆ
Ç ÇÇóèÝÕÝÕÝèÝèʾ³¨¨¨
¨
¨¨
¨
¨yn¨n
¨e¨
¨hUE5CJaJ hBWhÊSåCJaJh"xhÊSå5CJaJ hBWhÍaCJaJh"xhÞpù5CJaJh
SThÞpù5CJaJ hBWhÞpùCJaJ hBWhòOeCJaJh6hÞpù5CJaJ hBWhgx5CJaJ ho2CJaJ hBWh4ßCJaJ hBWh*PCJaJhBWhÊ_
5CJaJ'Ç*Ç,ÇjÇpÇǢǦǮÇÒÇúÇÈ<ÈHÈJÈPÈÈÈÈÈÈ$É8ÉDÉÉ É¢É®ÉÞÉÊ Ê
Ê.ÊDÊ[ÊaÊmÊõêõêÞõêÒêõijêõêõê¨ês¨¨¨¨¨¨k¨ h×poCJaJhBWhìZÌB*CJaJphhBWh2B*CJaJph hBWhìZÌCJaJh"xh25CJaJ hBWh2CJaJ hBWhÍa0J'CJOJQJaJh×po0J'CJOJQJaJh"xhÞpù5CJaJh"xhÍa5CJaJ hBWhÞpùCJaJ hBWhÍaCJaJ$ǤÇÈ$ÉÉÞÉ.ÊmʱʲÊÑÊêÊ Ë/ËNËkËË>ÌjÌlÌͤÍöîéÙÙÙÙÌǽgdÿ©gdÊSågdYì
n7^n`7gdìZÌ$n7^n`7a$gdìZÌgdìZÌ $a$gdÞpù7`7gdÞpùmÊzÊʦʯʰʱʲÊËfÌjÌlÌtÌÌÌÌÌÈÌÎÌúÌ ÍÍïàÕɽౠ}qf^SfHf=f hBWhlCJaJ hBWhÿ©CJaJ hBWh3>ZCJaJ hëymCJaJ hBWh¶1
CJaJhBWh¶1
5CJaJhÇa!5CJaJh6h¶1
5CJaJh6CJOJQJ^JaJ hBWhÊSåCJOJQJ^JaJh6hgx55CJaJhBWhìZÌCJ\aJhBWhòOeCJ\aJ hBWhìZÌCJaJhBWhìZÌB*CJaJph h"xhìZÌ5B*CJaJphÍ@ÍJÍ^Í Í¤ÍÎÍøÍÎ Î<ÎPÎaÎbÎeÎuÎÎÎάÎÎÑÎÛÎÜÎàÎðÎÏ<Ï>ÏKÏLÏMÏNÏZÏ^Ï|ÏϤϻÏËÏÌÏ0УФХÐ÷ñ÷ñ÷æÛæÛæÛæÛÐÛæÛæÅÐÅæÛÐÛºÛº©ºÛÐæÛæÛæÛwp
hBWhL h J hgx5CJaJ hBWhaCJaJ hBWhO#nCJaJ hBWhlCJOJQJ^JaJ hBWhÿ©CJOJQJ^JaJ hBWhlCJaJ hBWhì.ûCJaJ hBWhºMKCJaJ hBWhÿ©CJaJ hBWh¶1
CJaJ
h×poCJ hBWhÿ©CJ ,¤ÍúÍ!ÎQÎvÎÎÑÎðÎNÏ|Ï¥ÏÌÏúÏ0ÐOÐyÐ¤ÐæÐÑѨÑóóóóóóóã×óóóóóóËÆ¾¹² ¤gdÎ`ÜgdÎ`Ü $a$gd s gdt
$7^7a$gd J
$7^7a$gdO#n$77^7`7a$gdl
$7^7a$gdÿ© ¥ÐÊÐåÐæÐíÐøÐùÐ-Ñ0Ñ<ÑIÑKÑLÑMÑÑÑѧѫѬÑÐÑÔÑßÑñÑòÑõÑ÷ÑøÑüÑÿÑ$Ò&Ò2Ò6ÒtÒxÒÒÒºÒäÒæÒèÒùõùéÝéÒÇÒǼǴ©ÝéÝéÝÝÝéÝéÝéÝtÝtÝÝÇiÇ hBWh§JþCJaJhBWhÒ
(5CJaJh°kÐ5CJaJh~¢5CJaJhBWh-Zû5CJaJ h s hgx5CJaJ h d£h s CJaJ h s CJaJ hBWhM|CJaJ hBWhÒ
(CJaJ hBWhLCJaJhBWhgx55CJaJhBWhL5CJaJht
hBWhgx5)¨ÑüÑ0ÒrÒÒÒHÔ ÕØÕ4×êÛ*ÝÞ[ÞÞ²ßõîîîéÚʸ¸¸¸¦¸ $OÍø¤^O`Íøa$gdE&& $O¤^O`a$gdqlN $OÍø¤^O`Íøa$gd«U $OÍø¤^O`Íøa$gd
2 $OÍø^O`Íøa$gd¼P% ¤^`gd s gd} ¤gdÎ`Ü $¤a$gdÎ`ÜèÒ¨Ó®Ó¼Ó¾ÓÜÓÔ ÔÔÔDÔFÔHÔZÔ\Ô`ÔÀÔÂÔÆÔÈÔÊÔàÔÕÕ Õ6Õ8Õ<Õ~ÕÕÕÕ¸ÕºÕ¼Õ¾ÕÖÕØÕæÕìÕõêßêÔÉÔÉßÁêɵÉꪪÁÉÁªÉµÉêªÉªÔªÁÔypdhBWhO-ú5CJaJhO-ú5CJaJ hO-úCJaJ hBWh~¢CJaJ h~¢CJaJ hBWh¼P%CJaJ hBWhqlNCJaJ hBWh
2 CJaJhBWhgx55CJaJ h¼P%CJaJ hBWhgx5CJaJ hBWhÒ
(CJaJ hBWhÈf!CJaJ hBWh§JþCJaJ hBWh.@®CJaJ'ìÕîÕðÕ,Ö.Ö0ÖÖÖ¤Ö¦Ö¨Ö¬Ö¼ÖêÖìÖîÖðÖ×
××(×4×T×V×X×Z××Ä×Èר×`ØbØnتخØîØðØÙÙÙ"Ù$ÙfÙõíåÚÒǼڱڱ¢Ú±Ú±¢±Ú¢Ú±±Ú±ÚÚåÚwÚh¼P%5CJaJ hBWhÁYóCJaJ hBWh
2 CJaJhBWhgx55CJaJhBWhgx5CJOJQJaJ hBWh§JþCJaJ h~¢hÁYóCJaJ h~¢h~¢CJaJ h~¢CJaJ hBWhgx5CJaJ h¼P%CJaJ hO-úCJaJ hBWhO-úCJaJ*fÙjÙÙÙÜÙàÙ Ú<Ú>Ú@ÛBÛêÛòÛøÛ ÜÜ`Ü$Ý&Ý(Ý*Ý0Ý<ÝÝÝݤݺÝÄÝÈÝÌÝÒÝÖÝÞÞcÞnÞrÞtÞÞÞ ÞÃÞóèÝèóèÝèÝèÝÑÆÝ¾³¨³Ý¨¾¾¾³¾³¨~¨s¨s¨ÝÝ hBWhdX¾CJaJhBWhqlN5CJaJ hBWh~¢CJaJ h s CJaJ hBWh«UCJaJ hBWhqlNCJaJ hBWhÈf!CJaJ h~¢CJaJ hBWh
2 CJaJhBWhgx55CJaJ hBWhgx5CJaJ hBWhÁYóCJaJhBWhÁYó5CJaJ*ÃÞÈÞÙÞÛÞûÞüÞýÞß0ß1ßqßrßß߲߳߻ßÈßÉßøß@ààà¢à¦àêàïàûàüàýà á
áõêßÔßÔɾ¶¾¶¾¶¾«ê|ß|qõqfqß«]QhBWhÎ !5CJaJhI5CJaJ hBWh (UCJaJ hBWhÎ !CJaJ hBWh-ZûCJaJhBWhgx55CJaJhBWh-Zû5CJaJhBWhÈf!5CJaJ h s hgx5CJaJ h J CJaJ h J hE&&CJaJ h J h1&ZCJaJ hBWh1&ZCJaJ hBWhgx5CJaJ hBWhÈf!CJaJ hBWhö}ÉCJaJ-²ß³ßüàýàìäîäHåråèåHæræÞæ,çXçç¤çÈçîç è¶ê
ðóZóúõððëããúúúúúúúúúúúÞÙÒÍgd®& ¤xgd®&gd,w(gdr $$gdakgdÎ`Ügd=XgdÝAGgd}
á
á
ááá5áâ|ââÀâÆâÌâÎâÜãüãä ä¢ä¤ä¬ä®äÎäæäêäìäîäè èèHèbèdè²ê´êóèÝÒÝÒÝÊÝÊÝÒÝÂݺ²ºÂ²Âݧ
ymymbW hBWhrCJaJ hBWh} CJaJhBWh} 5CJaJhBWhgx55CJaJ hBWhgx5CJOJQJ^JaJ hBWh} CJOJQJ^JaJ h s hgx5CJaJ h]rÌCJaJ hß¹CJaJ hf7ïCJaJ h~¢CJaJ hBWhgx5CJaJ hBWh=XCJaJ hBWhÎ !CJaJhBWh-Zû5CJaJ!´ê¶êÆêØêÜêë ëìì8ìTìXìjìpìrì¨ì¬ìÀìÂìÔìØìþìíí|í®íÈíîîîVî²î ï$ï*ï<ïïïð
ðõìàõÕõÕÍõÍÅÍõºÅº®ÍºÍ¢®¢ºÍººº{{p hBWh} CJaJ haaCJaJhW9h ´5CJaJ h¸dCJaJ hBWhïh:CJaJhß¹hß¹5CJaJhß¹h ´5CJaJ hBWh ´CJaJ h LaCJaJ hß¹CJaJ hBWhrCJaJhBWh
]¤5CJaJhß¹5CJaJ hBWh
]¤CJaJ'
ð ð°ð*òfò¾òóóZóóÖóÞóâóøóôrôÄôÎôÐôÒôZõõ õÆõÊõ ö öBö÷$÷(÷B÷D÷P÷X÷\÷.øóçÜÔÜÔÜçÈç¿çÈó´Ü禴ܴóÜÜÜugu\ hBWhÇa!CJaJh¹hÇa!5>*CJaJhBWhÇa!5CJaJhBWh.@®5>*CJaJhBWhh]ª5CJaJ hBWhh]ªCJaJhBWh®&56CJaJ hBWh®&CJaJhUDm5CJaJhBWhý:v5CJaJ h°kÐCJaJ hBWh.@®CJaJhBWh.@®5CJaJhBWh®&5CJaJ$Zóâó õ(÷D÷tøvúûÐýÆþÐFæH²IZKMbNBQQQòëëëá×Ǽ¯¼¼¼¼¼¼×ªªgdTW_
$
&
F ¤
h ¤<^hgdÝAG
&
F eþ^e`þgd]¦
&
F ¤
&
F ¤
7¤< ¤<^7gdMp.ørøtøøøø¢ø¸øÐøRùVùpùtúvúú¨ú¬úÀúÌúäúèúû¤û$ü(ü@üBüÎýÐýîýöýþ þ(þøíáÕʿʴʩ¡ÊáÕ¿¿´¿¿©¡©¿wkwbVhBWhÅz5CJaJhak5CJaJhBWhÃ0þ5CJaJhBWhYC-5CJaJ hBWhYC-CJaJ hÝAGCJaJ hBWh.@®CJaJ húlCJaJ hBWhúlCJaJ hBWh5YJCJaJ hBWhñiCJaJ hBWhnCJaJhBWhn5CJaJhBWh.@®5CJaJ hBWhÇa!CJaJ hÇa!CJaJ!(þ>þJþZþ^þdþfþrþ|þþþÆþÒþäþúþÿ,ÿlÿòÿD4DE°EæEFF,FÎFÐFÔFGGtGGGàG
H HäHæHóçóÛçÛóÛóÐóŽŲŧyynn hBWh^CJaJ hBWh4%CJaJ hBWhá^®CJaJU hBWhÃ0þCJaJ hBWh a
CJaJ hBWh?(]CJaJ hBWhgYUCJaJ h5,àCJaJ hBWh7CJaJ hBWh.@®CJaJhBWhYC-5CJaJhBWhÃ0þ5CJaJhBWh.@®5CJaJ(zlop(ok) értéke adja meg, hogy az adott tábla (gyerek tábla) egy sora, a másik tábla (szülQ tábla) mely sorához tartozik. Egy vagy több oszlop alkothatja. A külsQ kulcs a gyerek táblában van és hivatkozik (REFERENCES) a szülQ tábla elsQdleges (PRIMARY KEY) vagy egyedi (UNIQUE) kulcsára. A hivatkozott szülQ tábla általában egy másik tábla, de lehet ugyanaz.
A külsQ kulcs értéke csak létezQ szülQ kulcs értékre hivatkozhat, vagy NULL értékq lehet. A szülQ táblából olyan sor nem törölhetQ, melyben lévQ kulcsértékre hivatkoznak gyerek sorok. A szülQ tábla olyan kulcs értéke nem módosítható, melyre hivatkoznak gyerek sorok.
FOREIGN KEY: kijelöli a gyerek tábla külsQ kulcs oszlopait. Oszlop szintq megszorításnál ez nem kell.
REFERENCES: kijelöli a szülQ táblát és annak oszlopait. Ha nincs megadva oszlop, akkor a szülQ tábla elsQdleges kulcsát veszi. A külsQ kulcs és a hivatkozott kulcs oszlopok adattípusának rendre illeszkedni kell.
ON DELETE: Opcionális. Felülírhatjuk az alapértelmezett törlési szabályt. CASCADE esetén a szülQ sor törlésekor törli a függQ gyereksorokat is, SET NULL esetén a függQ gyereksorok külsQ kulcs értékét NULL -ra állítja.
Megjegyzés: Egyes SQL implementációkban létezik egy teljesen analóg ON UPDATE záradék is, mely az alapértelmezett módosítási szabályt írja felül. Oracle ezt nem engedi.
CHECK (feltétel) a feltételt minden sornak ki kell elégíteni. Megenged minden olyan sort, amelyre a feltétel igaz (True) vagy ismeretlen (Unknown). Tehát a CHECK egy oszlopra a NULL értéket nem tiltja meg! A feltételben csak a tábla saját oszlopai szerepelhetnek. Nem lehet a benne alselect, nem determinisztikus függvényhívás (SYSDATE, USER, ...) és pszeudo oszlop.
Tábla definíciójának módosítása:
ALTER TABLE táblanév {ADD ... | MODIFY ...| DROP ... | RENAME ...};
A megvalósításokban sok szabály erQsen korlátozza a tábladefiníciók módosítását. A szabvány is viszonylag késQn ír róla, a megvalósítások pedig túlmutatnak a szabvány lehetQségein. Általában megengedett új oszlopok, megszorítások felvétele, a meglévQk módosítása, törlése vagy átnevezése.
Az általános alapszabály a következQ: az ALTER TABLE utasítás végrehajtása csak akkor lesz sikeres, ha a tábla módosított definíciójának eleget tesznek a táblában már meglévQ adatok és az integritási megszorítások sem sérülnek. Ha egy tábla még üres, vagy ha egy oszlop csupa NULL értéket tartalmaz, akkor több a módosítási lehetQség.
KerülQ úton megoldhatók a nagyon körülményes táblamódosítások: egy új táblát kell definiálni, fel kell tölteni beágyazott alselecttel, a régi táblát törölni kell, majd az új táblát át kell nevezni a régi nevére a következQ utasítással:
TetszQleges objektum átnevezése:
RENAME objektumnév TO új_objektumnév;
Tábla törlése:
DROP TABLE táblanév [CASCADE CONSTRAINTS] [PURGE];
A tábla adatai, indexei, megszorításai, triggerei és a táblához kötQdQ objektumjogok törlQdnek. A CASCADE CONSTRAINTS opcióval adható meg, hogy a táblára hivatkozó külsQ megszorítások is automatikusan törlQdjenek. A táblától függQ más objektumok (szinonimák, nézetek) nem törlQdnek, csak érvénytelen (INVALID) lesz a státuszuk. Ha a táblát ismét létrehoznánk akkor a függQ objektumok státuszának VALID-ra való állítását a rendszer automatikusan megoldja, a függQ objektumra való elsQ hivatkozáskor. A PURGE opció csak Oracle10g-tQl használható: fizikailag törli a táblát és csatolt objektumait, hiánya esetén fizikailag nem törli ezeket, hanem csak átnevezi a rendszer által generált névre és a "lomtárba" (RECYCLEBIN nevq DD tábla) teszi. Lomtár megtekintése: SELECT * FROM RECYCLEBIN;
Lomtár ürítése: PURGE RECYCLEBIN;
-- Sikertelen a tábla törlése, mert van rá hivatkozó külsQ megszorítás
DROP TABLE telephely;
-- Sikeres a tábla törlése
DROP TABLE telephely CASCADE CONSTRAINTS;
Haladó: A mintatáblát létrehozó CREATE TABLE -n túlmutató példa:
/* Tábla több oszlopát érintQ megszorítások: összetett kulcsok.
SZAMLA, SZAMLA_TETEL táblák definiálása: egy számlával annak tételei is törlQdjenek.*/
CREATE TABLE szamla
( ev NUMBER(4), -- számla gazdálkodási éve
sorszam NUMBER(7), -- számla sorszáma, gazdálkodási évente 1-rQl indul
CONSTRAINT szamla_pk PRIMARY KEY(ev, sorszam)
-- egyéb oszlopok, pl. dátum, állapot, vevQ, szállító, stb.
-- más táblákkal való kapcsolatok
);
CREATE TABLE szamla_tetel
( ev NUMBER(4), -- számla gazdálkodási éve
sorszam NUMBER(7), -- számla sorszáma, gazdálkodási évente 1-rQl indul
tsorszam NUMBER(3), -- számla tételének sorszáma
osszeg NUMBER(9,2) NOT NULL, -- számla tételének összege
CONSTRAINT szamla_tetel_pk PRIMARY KEY(ev, sorszam, tsorszam),
CONSTRAINT szamla_tetel_fk FOREIGN KEY (ev, sorszam)
REFERENCES szamla(ev, sorszam) ON DELETE CASCADE,
CONSTRAINT szamla_tetel_osszeg CHECK(osszeg > 0)
-- egyéb oszlopok, pl. cikk, szolgáltatás, mennyiség, egységár, stb.
-- más táblákkal való kapcsolatok
);
-- Lehet dolgozni, végül töröljük a táblákat
DROP TABLE szamla CASCADE CONSTRAINTS;
DROP TABLE szamla_tetel CASCADE CONSTRAINTS;
Tábla definíciójának módosítása Oracle-ben: csak egy záradék lehet egy ALTER-ben:
ALTER TABLE táblanév
ADD (oszlopnév többi_specifikáció ,& ) -- Új oszlopok megadása.
MODIFY (oszlopnév többi_ specifikáció ,& ) -- MeglévQ oszlop definíciójának megváltoztatása.
-- Oszlopok eltávolítása, az oszloptól függQ egyéb objektumok (pl. VIEW) státuszát
-- érvénytelenre (INVALID) állítja, az oszlopra épülQ indexek törölve lesznek.
-- Ha van rá hivatkozó megszorítás, nem engedi a törlést, de elQírható hogy azokat is törölje.
DROP {COLUMN oszlopnév | (oszlopnév,...)} [CASCADE CONSTRAINTS]
RENAME COLUMN oszlopnév TO új_oszlopnév -- Oszlop átnevezése
ADD megszorítás_megadás & -- Új megszorítások megadása
MODIFY CONSTRAINT megszorításnév megszorítás_állapot -- Megszorítás állapot módosítása
-- Megszorítás eltávolítása, ha vannak függQ megszorítások, akkor nem engedi a törlést,
-- de elQírható hogy azokat is törölje.
DROP CONSTRAINT meszorításnév [CASCADE]
RENAME CONSTRAINT megszorításnév TO új_megszorításnév -- Megszorítás átnevezése
megszorítás_állapot ::= [ ENABLE | DISABLE ] [ VALIDATE | NOVALIDATE ]
[ NOT DEFERRABLE | DEFERRABLE ] [ INITIALLY { IMMEDIATE | DEFERRED } ]
ENABLE vagy DISABLE: megszorítás be- vagy kikapcsolt állapotának állítása.
VALIDATE vagy NOVALIDATE: a táblában már meglévQ adatok alá legyenek-e vetve a megszorítás-ellenQrzésnek vagy se? A táblába DML-el kerülQ új adatok, adatmódosítások mindig, mindkét esetben alá vannak vetve egy bekapcsolt megszorításnak.
*** DEFERRABLE vagy NOT DEFERRABLE: tranzakciók közben átállítható-e a megszorítás elhalaszthatósági állapota a SET CONSTRAINT[S] utasítással vagy sem. ALTER TABLE -ben ez az állapot nem módosítható!
*** INITIALLY IMMEDIATE vagy INITIALLY DEFERRED: mi legyen a default, induló viselkedése egy DEFERRABLE megszorításnak, mely a SET CONSTRAINT[S] utasítással megváltoztatható a tranzakció közben. IMMEDIATE: azonnal, a DML utasítás végrehajtásakor lesznek az adatok a megszorítással ellenQrizve. DEFERRED: legyen elhalasztva az ellenQrzés a tranzakció végéig.
Ha nem adunk meg semmilyen megszorítás állapotot, akkor ENABLE VALIDATE NOT DEFERRABLE INITIALLY IMMEDIATE az alapértelmezés. Az elhalasztható (DEFERRABLE) megszorításokra példákat lásd a tranzakcióknál.
-- DD-ben nézzük meg milyen megszorításaink vannak:
SELECT * FROM USER_CONSTRAINTS WHERE table_name IN ('TELEPHELY', 'ALKALMAZOTT');
-- Tábla bQvítése új oszloppal: a táblában már meglévQ sorok az új oszlopban NULL
-- értéket kapnak => nem adható meg NOT NULL specifikáció, ha léteznek sorok és
-- nincs DEFAULT érték megadva.
ALTER TABLE telephely ADD (telefon NUMBER(10));
ALTER TABLE alkalmazott ADD (szem_szam VARCHAR2(13) CONSTRAINT alk_uk UNIQUE
CONSTRAINT alk_szsz
CHECK(SUBSTR(szem_szam, 1, 2) IN ('1-', '2-') AND SUBSTR(szem_szam, 9, 1) = '-'));
-- Csupa NULL értéket tartalmazó oszlopnak még a típusa, mérete is megváltoztatható,
-- ha már vannak benne értékek, akkor csak egy "odaillQ" másikra változtatható:
ALTER TABLE telephely MODIFY (telefon VARCHAR2(20),
varos CHAR(20) DEFAULT 'PÉCS' NOT NULL );
-- Nem törölhetünk olyan oszlopot, amelyre megszorítások hivatkoznak:
-- Használjuk a CASCADE CONSTRAINTS opciót:
ALTER TABLE telephely DROP (telefon);
ALTER TABLE telephely DROP (t_kod);
ALTER TABLE telephely DROP (t_kod) CASCADE CONSTRAINTS;
-- Adjunk az alkalmazott táblához egy több oszlopra épülQ CHECK feltételt:
-- Hibajelzés, mert a meglévQ sorok nem elégítik ki a feltételt. Javítás után jó lesz.
ALTER TABLE alkalmazott ADD
CONSTRAINT alk_fiz_prem CHECK (fizetes + NVL(premium, 0) < 200000);
ALTER TABLE alkalmazott ADD
CONSTRAINT alk_fiz_prem CHECK (fizetes + NVL(premium, 0) < 500000);
-- Kapcsoljuk ki az ALK_BEOSZTAS megszorítást
ALTER TABLE alkalmazott MODIFY CONSTRAINT alk_beosztas DISABLE;
-- Töröljünk megszorításokat.
-- Ha vannak függQ megszorítások, akkor nem lehet. Használjuk a CASCADE opciót!
ALTER TABLE alkalmazott DROP CONSTRAINT alk_fiz;
ALTER TABLE alkalmazott DROP CONSTRAINT alk_pk;
ALTER TABLE alkalmazott DROP CONSTRAINT alk_pk CASCADE;
-- DD-ben nézzük meg milyen megszorításaink vannak most:
SELECT * FROM USER_CONSTRAINTS WHERE table_name IN ('TELEPHELY', 'ALKALMAZOTT');
-- Vigyünk fel egy-két sort a táblákba
INSERT INTO telephely (t_nev) VALUES('Próba ABC');
INSERT INTO alkalmazott VALUES('1001','Valaki1','Oktató1','99-DEC-09',
-20000, NULL,'99','9999', '2-840127-1234');
INSERT INTO alkalmazott VALUES('1001','Valaki2','Oktató2','99-DEC-09',
-20000, NULL,'99','9999', '2-840127-1234');
SELECT * FROM telephely;
SELECT * FROM alkalmazott;
-- Futtassuk le a mintatáblát létrehozó SQL szkriptet
@http://delfin.unideb.hu/~lnagyeva/SQL/create_telalk.sql
*** Globális ideiglenes tábla (GLOBAL TEMPORARY TABLE): A szabvány és az Oracle is megengedi az ideiglenes tábla definiálását, amely tábla a munkamenet elején mindig létrejön, kijelentkezéskor pedig automatikusan törlQdik (de a definíció megmarad a DD-ben). Munkamenetenként a táblának egy külön példánya jön létre, ezért egymás táblájának adatait nem látják. Beállítható, hogy az ideiglenes tábla tranzakció specifikus vagy munkamenet specifikus legyen: azaz az ideiglenes tábla sorai egy-egy tranzakció végén automatikusan törlQdjenek (ON COMMIT DELETE ROWS), vagy sem (ON COMMIT PRESERVE ROWS). Jól használható összetett számítások részeredményeinek vagy más forrásból átvett adatok ideiglenes tárolására. Törölni csak akkor lehet, ha egyetlen munkamenet sem tart benne sort (vagy TRUNCATE TABLE tábla; utasítással töröljük ki azokat.)
CREATE [GLOBAL TEMPORARY] TABLE táblanév
( oszlopok és megszorítások)
[ON COMMIT {DELETE | PRESERVE} ROWS]
[tárolási és egyéb elQírások]
[AS alselect];
-- Munkamenetenként létrejön, munkamenet végéig megmaradnak a sorok.
CREATE GLOBAL TEMPORARY TABLE munkamenet_naplo
(sorszam NUMBER, megjegyzes VARCHAR2(100))
ON COMMIT PRESERVE ROWS;
-- Munkamenetben felvett sorok a munkamenet számára végig elérhetQk
INSERT INTO munkamenet_naplo VALUES('1', 'Bejegyzés');
INSERT INTO munkamenet_naplo VALUES('1', 'Másik bejegyzés');
COMMIT;
SELECT * FROM munkamenet_naplo;
-- Jelentkezzünk ki, bejelentkezés után a munkamenet(ek) üres táblát talál.
SELECT * FROM munkamenet_naplo;
DROP TABLE munkamenet_naplo;
*** Megjegyzés fqzése egy táblához, vagy annak oszlopához dokumentálás céljából:
COMMENT ON {TABLE táblanév | COLUMN táblanév.oszlopnév} IS 'szöveg';
COMMENT ON TABLE telephely IS 'a cég telephelyeinek adatait tartalmazza';
COMMENT ON COLUMN telephely.t_kod IS 'telephely kódja, egyedi azonosító';
Nézettábla létrehozása, törlése
Nézettábla: más táblá(k)ból és/vagy nézettáblá(k)ból levezetett (SELECT utasítással származtatott) virtuális tábla. Olyan mint egy ablak, melyen keresztül az alapjául szolgáló adatok egy részére lehet rálátni. A nézettáblában adatok nem tárolódnak, csak a definíciója kerül be a DD-be. A nézettáblát ugyanúgy használhatjuk SQL parancsokban mint az alaptáblákat. Lekérdezhetjük SELECT-el és karbantartást is végezhetünk nézettáblán keresztül az INSERT, UPDATE, DELETE utasításokkal, ha ez nincs letiltva és a nézet karbantartásra alkalmas.
Nézettábla létrehozása, vagy a meglévQ definíció felülírása:
CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW nézettábla_név [(oszlopnév,...)]
AS select_utasítás
[WITH CHECK OPTION] [CONSTRAINT megszorítás_név]
[WITH READ ONLY] [CONSTRAINT megszorítás_név];
Nézettábla törlése:
DROP VIEW nézettábla_név;
OR REPLACE: ha már létezik, felülírja a meglévQ definíciót. Opciót elhagyva, nem hozná létre, ha már létezik.
FORCE vagy NO FORCE: létrehozza-e akkor is érvénytelen státusszal, ha nem létezik az alaptábla?
AS select_utasítás: tetszQleges lekérdezés. A SELECT listában szereplQ sql_kifejezések darabszáma feleljen meg a nézettábla oszlopainak számával, a típust a SELECT szolgáltatja. Ha nem adunk meg a nézetnek oszlopneveket, akkor azokat is a SELECT szolgáltatja, ezért a nem egy oszlopból álló sql_kifejezéseknek adjunk oszlop-aliasnevet.
WITH READ ONLY: megszorítás, csak SELECT-et enged meg a nézetre, többi DML mqveletet letiltja.
WITH CHECK OPTION: megszorítás, csak a nézettáblát definiáló szelekciós utasítás WHERE feltételének is megfelelQ adatok kerülhessenek be az alaptáblába a nézettáblán keresztül (amilyen adatokat lekérdezhetünk a nézettáblán keresztül, csak azokat tarthassuk karban).
Használatának elQnyei:
Adatvédelem, adathozzáférés szabályozása: meghatározott felhasználók az alaptáblákhoz nem kapnak hozzáférési jogot, csak a nézettáblához és azon keresztül férhetnek hozzá az alaptáblákban lévQ adatok egy részhalmazához.
Felhasználói igények kielégítése: felhasználók különbözQ csoportjai számára célszerq nézetek létrehozása.
Adatbázis komplexitásának elrejtése: a gyakran használt összetett lekérdezéseket a nézet segítségével a DD tároljuk, majd azt használjuk. Egy vagy több táblára, nézettáblára támaszkodó bonyolult lekérdezés eredménye könnyebben kezelhetQ, ha az összetett lekérdezés helyett nézettáblát használunk.
Amikor nézettáblán keresztül kérdezünk le az adatokat, a rendszer mindig az alaptáblákból veszi az adatokat. Ha az alaptáblák tartalma módosul, akkor módosul a nézettábla is. Ha nézeten keresztül végzünk karbantartást, akkor is az alaptáblák adatait tartjuk karban, ezért a nézeten keresztül való karbantartás csak akkor végezhetQ el, ha minden szükséges adat megadható a nézeten keresztül és a karbantartandó sorok is egyértelmqen kijelölhetQk.
Karbantartásra alkalmas nézettábla: a nézetet definiáló SELECT egy táblára támaszkodik és nem tartalmaz speciális záradékokat (pl. GROUP BY, ORDER BY). A SELECT lista pedig csak oszlopnevekbQl áll, nem tartalmaz összetett kifejezéseket, függvényeket, pszeudo oszlopokat, DISTINCT opciót.
-- Karbantartásra alkalmas nézettábla.
-- Nézet oszlopainak nevét a SELECT adja
CREATE OR REPLACE VIEW videk
AS SELECT * FROM telephely WHERE varos <> 'BUDAPEST'
WITH CHECK OPTION CONSTRAINT videk_where;
-- Nézet definícióját lekérdezQ [i]SQL*Plus parancs
DESCRIBE videk
SELECT * FROM videk;
-- sorok felvitele a nézeten keresztül, majd azok megtekintése:
INSERT INTO videk VALUES ('91', 'Rossz ABC', 'BUDAPEST');
INSERT INTO videk VALUES ('93', 'Jó ABC', 'EGER');
SELECT * FROM videk;
SELECT * FROM telephely;
ROLLBACK;
-- Karbantartásra nem alkalmas, összetett nézettáblák:
CREATE OR REPLACE VIEW alk_tel
AS SELECT a_kod, a_nev, beosztas, t_nev, varos
FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod
ORDER BY a_kod;
SELECT * FROM alk_tel;
-- Nézet oszlopainak nevét a SELECT oszlop-, oszlopalias nevei adják
CREATE OR REPLACE VIEW csoport
AS SELECT t_kod, AVG(fizetes) atlag_fiz, COUNT(*) letszam
FROM alkalmazott
GROUP BY t_kod;
-- Nézet oszlopainak nevét explicit módon megadjuk
CREATE OR REPLACE VIEW csoport (t_kod, atlag_fiz, letszam)
AS SELECT t_kod, AVG(fizetes), COUNT(*)
FROM alkalmazott
GROUP BY t_kod;
SELECT * FROM csoport;
-- Alkalmazottak, akik fizetése több mint az azonos telephelyen dolgozók átlagfizetése
SELECT * FROM alkalmazott X
WHERE fizetes > (SELECT atlag_fiz FROM csoport WHERE t_kod = X.t_kod);
-- ElözQ, plusz: legyen kiírva az alkalmazott telephelyének átlagfizetése és a létszáma
SELECT X.*, atlag_fiz, letszam FROM alkalmazott X JOIN csoport CS ON X.t_kod = CS.t_kod
WHERE fizetes > atlag_fiz;
-- A legmagasabb átlagfizetés (a telephelycsoportok közül)
SELECT MAX(atlag_fiz) FROM csoport;
-- Kérdezzük le a nézettáblák definícióját tartalmazó DD táblát
-- LONG típusú oszlopokból ne csak 80 karaktert írjon ki az iSQL*Plus
SET LONG 2000
SELECT * FROM USER_VIEWS WHERE view_name IN ('VIDEK', 'ALK_TEL', 'CSOPORT');
DROP VIEW videk;
DROP VIEW alk_tel;
DROP VIEW csoport;
Haladó: *** Materializált nézettábla, pillanatfelvétel:
Készítése hasonló a nézettáblához, szintén más táblákból, nézettáblákból levezetett tábla, csak ez nem virtuális tábla lesz, hanem egy ténylegesen létrejövQ valódi tábla adatokkal, amely csak olvasható. Szokás még a replikátum, másolat elnevezés is. REFRESH záradékban megadható, hogy mikor és hogyan történjen az automatikus frissítésük (meghatározott idQpontokban periódikusan, vagy azonnal az alaptábla változásakor, a frissítés teljes vagy részleges legyen, stb.), ha a záradékot elhagyjuk az automatikus frissítés elmarad. További használatuk az alaptáblákhoz hasonló.
CREATE { MATERIALIZED VIEW | SNAPSHOT } nézettábla_név [(oszlopnév,...)]
[tárolási és egyéb elQírások]
[REFRESH frissítési_paraméterek | NEVER REFRESH]
AS select_utasítás;
Használatának elQnyei:
Osztott adatbázisok esetén: egy távoli szerver gépen tárolt adatokról másolatot készíthetünk a lokális szerver gépeken, azzal a céllal, hogy a hálózati forgalom csökkenjen, a rendszer gyorsabb legyen és a hálózati hiba miatti leállást elkerüljük. Például egy országos áruházláncban a termékek árának karbantartása csak egy központi adatbázisban történik, errQl kapnak az egyes áruházak automatikusan (pl. éjszakánként) másolatot, amelyet gyakran olvasnak a napi munka során.
Döntéstámogató rendszerekben: Sok, változatlan alapadat (lezárt idQszakok) alapján kell bonyolult kigyqjtéseket, összesítQ számításokat végezni. Ezen számítások eredményét tárolhatjuk materializált nézettáblában frissítést nem kérve, majd többször felhasználhatjuk a további elemzésekben. Adattárházas technológiát használó rendszerekben: különbözQ típusú "örökölt" adatbázisokból származó adatokat megfelelQ átalakítás után egy egységes központi adatbázisba másolják. Ahogy az egyes adatbázisok változnak, úgy módosuljon automatikusan a központi adatbázis is.
-- Automatikus frissítés tilos, ezért ez (csak ez!) karbantartható DML-el
CREATE MATERIALIZED VIEW mv_alk1
NEVER REFRESH -- tilos az automatikus frissítés
AS SELECT * FROM alkalmazott;
-- Automatikus frissítés lehet, ezért nem karbantartható DML-el
-- Automatikus frissítés jelenleg még nincs elQírva, de ALTER-el még megadható
CREATE MATERIALIZED VIEW mv_alk2
AS SELECT * FROM alkalmazott;
-- START: elsQ frissítésés ideje (opcionális). NEXT: következQ frissítések periodikusan
-- Automatikus frissítés: holnap 11:00 órakor, majd minden vasárnap 21:00 órakor
CREATE MATERIALIZED VIEW mv_alk3
REFRESH START WITH TRUNC(SYSDATE + 1) + 11/24
NEXT NEXT_DAY(TRUNC(SYSDATE), 'Vasárnap') + 21/24
AS SELECT * FROM alkalmazott;
-- Lehet használni a táblákat, majd ha nem kell töröljük
DROP MATERIALIZED VIEW mv_alk1;
DROP MATERIALIZED VIEW mv_alk2;
DROP MATERIALIZED VIEW mv_alk3;
Indexek létrehozása, módosítása, törlése, nagymennyiségq adatok hatékony kezelése
Nagymennyiségq adatok hatékony kezelése:
idQben: a felhasználóknak elfogadható idQn belül (válaszidQ < 2-20 sec) választ kell kapni a feltett kérdéseire.
tárhelyben: szabályozottan redundánsan tárolhatnak a rendszerek bizonyos adatokat az idQbeni hatékonyság növeléséhez.
Indexet (index-objektumot) táblához hozhatunk létre, a táblára vonatkozó lekérdezések felgyorsítása céljából vagy oszlop(ok) értékének egyediségének biztosítására. Definiálás után az indexstruktúrát a rendszer automatikusan létrehozza és használja. A táblára vonatkozó karbantartó mqveleteket során pedig karbantartja, ami lassítja ezen mqveleteket. Létrehozásuk és megszüntetésük nincs hatással az SQL utasítások kódjára.
Index: egy olyan objektum, amely rendezve tartalmazza az indexkulcsot alkotó oszlop(ok) különbözQ sorokhoz tartozó értékét és a sor közvetlen fizika eléréséhez szükséges mutatót (ROWID). NULL értékq indexkulcshoz nem jön létre bejegyzés az indexben (kivétel: bitmap index, cluster index).
Az index lehetQvé teszi, hogy az adatsorokat gyorsan megtaláljuk, ha ismerjük a hozzá tartozó értékek bizonyos részét. Például: egy tábla azon sorait keressük, amelyben az egyik oszlop értéke egy megadott érték. Ha nincs a táblához index az adott oszlop szerint, akkor a tábla sorait sorban végig kell olvasni. Ha van a táblához index az adott oszlop szerint, akkor a rendszer az indexkulcs szerint rendezett indexben gyorsabban meg tudja találni a megadott értéket, majd a mellette lévQ mutató (sor fizikai címe) segítségével beolvassa a keresett sort.
Egy táblához több index is definiálható. Ha már egyszer létre vannak hozva az indexek, akkor a rendszer optimalizálója, az utasítás végrehajtási tervének elkészítésekor dönt, hogy használja-e azokat. A rendszerek optimalizálói szabályalapú és/vagy költségalapú lehet: Szabályalapú: az utasítás formai jellemzQi alapján készít végrehajtási tervet, elQtte átalakíthatja az utasítást egy azzal egyenértékq formára. Költségalapú: figyelembe veszi a táblák méretét és/vagy az adatok, utasítások gyakoriságának statisztikai jellemzQit. Nincs két olyan termék, amely ugyanazon optimalizációs módszert alkalmazná, ezért az SQL szabvány sem sokat ír az indexek használatáról.
Az Oracle-ben a tábla PRIMARY KEY és UNIQUE megszorítás oszlopaihoz automatikusan létrejön egyedi index objektum, aminek a neve egyezik a megszorítás nevével, ezen indexek egyben biztosítják a kulcsértékek egyediségét is. Más rendszerekben a FOREIGN KEY oszlopokra épülQ index is létrejöhet automatikusan.
Index definiálása:
CREATE [UNIQUE | BITMAP] INDEX indexnév
ON táblanév (index_kifejezés [ ASC | DESC ] ,...) -- indexkulcsot alkotó oszlopok
[tárolási és egyéb elQírások];
Index módosítása (csak a tárolási és egyéb elQírások változtathatók):
ALTER INDEX & ;
Index törlése:
DROP INDEX indexnév;
Alapértelmezés: ha nem adunk meg semmilyen opciót, akkor a legtöbb DBMS-ben az index nem egyedi és az indexstruktúra B-fa (Balance - kiegyensúlyozott fa valamely változata, szokás a B+-fa jelölés is), a fa az indexkulcs értékei szerint növekvQleg rendezett. (B-fa: a kiegyensúlyozott bináris keresQfa általánosítása, egy B-fa csomópontjának nem két, hanem sok gyermeke lehet.)
index_kifejezés: oszlopnév hagyományos index esetén. Egyes rendszerekben itt kifejezés is állhat, és ekkor függvény alapú indexnek nevezzük, célszerq használatának külön specifikumai vannak.
UNIQUE: indexkulcsot alkotó oszlopok értékei egyediek legyenek. Azonos a UNIQUE megszorításal.
BITMAP: B-fa szerkezetq index helyett a bitmap indexstruktúra legyen.
ASC, DESC: az oszlopbeli értékek növekvQ vagy csökkenQ sorrendjében legyen az indexképzés. Az Oracle-ben minden index ASC rendezett, a kompatibilitás miatt megengedett DESC is erre van visszavezetve.
Irányelv indexek készítéséhez: azon oszlopok legyenek az index kulcsai, amelyek értékei ismeretében gyakran akarunk a tábla soraihoz hozzáférni. Túl sok indexet létrehozni nem célszerq, mert nagyon lelassulhatnak a karbantartó mqveletek és az indexek külön tárhelyet is igényelnek. Nincs két olyan rendszer, mely ugyanazt az optimalizációs módszert alkalmazná, ezért meg kell nézni a konkrét rendszer idevonatkozó ajánlásait.
Az oszlopot (vagy oszlopokat együtt) gyakran használjuk a WHERE feltételben, vagy join kapcsolófeltételben. De nem sql_kifejezés belsQ részeként!
Az oszlop nagy számú NULL értéket tartalmaz és általában a nem NULL értékq oszlopokkal dolgozunk.
A tábla nagy és a legtöbb lekérdezés kevés (pl. 5-10-15%) sort ad vissza.
Más rendszereknél: az oszlop értéke szerint gyakran rendezzük a lekérdezés eredményét.
Oracle-ben minden tábla ROWID nevq pszeudo oszlopa a sor fizikai címét tartalmazza, mely mutatóként fel van használva az index készítésénél.
-- Tábla ROWID pszeudo oszlopának lekérdezése
SELECT a_kod, a_nev, ROWID FROM alkalmazott;
-- Alkalmazott táblát indexeljük a_nev oszlop szerint
CREATE INDEX alk_anev ON alkalmazott (a_nev);
-- Gyorsítja a következQ lekérdezéseket
SELECT * FROM alkalmazott WHERE a_nev = 'Szabó Pál';
SELECT * FROM alkalmazott WHERE a_nev LIKE 'Ko%';
-- Nem gyorsítja a következQ lekérdezéseket
SELECT * FROM alkalmazott WHERE UPPER(a_nev) LIKE 'KO%';
SELECT * FROM alkalmazott WHERE a_nev IS NULL;
** Haladó:
B-fa indexstruktúra: többszintq, hierarchikus fastruktúra, amelyben a felül elhelyezkedQ rendezett indexlistákból (csomópontokból) nem közvetlenül a tábla soraira, hanem újabb rendezett indexlistákra (csomópontokra) történik hivatkozás, a fa leveleit alkotó indexlisták mutatói hivatkoznak csak a tábla soraira. A fa kiegyensúlyozott: a levéllisták a hierarchia azonos szintjén helyezkednek el, minden sort közel azonos idQ alatt lehet elérni. Az indexlisták mérete úgy van megválasztva a rendszerben, hogy egyszerre beférjen a központi memóriába: egy logikai blokk méretq. A szintek száma alacsonyan tartható: kb. LOGM(N) szint szükséges N darab táblasor indexeléséhez, ha egy blokkba M bejegyzés kerül. A keresés elve megfelel a keresQfák megszokott algoritmusának. Összetett indexkulcsok esetén fokozhatjuk az adatelérés teljesítményét, ha a legtöbb különbözQ értékkel rendelkezQ (legszelektívebb) oszlopot adjuk meg elsQként az indexkulcsban.
Bitmap index: speciális index, mely a sorok eléréséhez szükséges mutatót egy bittérkép (bitmátrix) segítségével társítja az indexkulcs értékeivel. A bittérkép minden egyes bitje megfelel egy lehetséges mutatónak. Ha egy bit értéke 1, akkor a megfeleltetett mutató által hivatkozott sor tartalmazza az indexkulcs értékét, egyébként nem. Bitmap esetén DESC rendezés nem írható elQ. Akkor célszerq, ha az indexkulcs értéktartománya nem széles (a sorok számához képest, kevés a kulcs különbözQ értékeinek száma (pl. 1%)) és alacsony szinten van a konkurens tranzakciók száma (pl. adattárházas alkalmazások). Az alkalmazott táblának a BEOSZTAS oszlopa (vagy ha lenne NEM, CSALADI_ALLAPOT, stb. oszlopa) lenne alkalmas bitmap indexkulcsnak. A WHERE feltétel OR, AND kiértékelései a bitmap vektorain végezhetQk, ami tovább gyorsít.
Függvény alapú index: indexkulcsnak olyan nem NULL értékq indexkifejezés(eke)t írunk, amilyen kifejezések gyakran szerepelnek a WHERE feltételben. A SELECT végrehajtása során a kifejezés értékét az indexben már letárolt, "elQre kiszámított" értékek adják.
-- alkalmazott táblát indexeljük a_nev oszlop nagybetqsített értéke szerint
CREATE INDEX alk_upper_anev ON alkalmazott (UPPER(a_nev));
-- a következQ SELECT biztosan használja az indexet
SELECT * FROM alkalmazott WHERE UPPER(a_nev) LIKE 'KO%';
-- alkalmazott táblát indexeljük az alkalmazottak jövedelme szerint
CREATE INDEX alk_jov ON alkalmazott (fizetes+NVL(premium,0), beosztas);
-- gyorsítja a következQ lekérdezést
SELECT * FROM alkalmazott WHERE NVL(premium,0)+fizetes < 150000 AND beosztas='ELADO';
*** Egyéb Oracle lehetQségek:
Az Oracle-ben az indexdefiníció az itt ismertetettQl több finomságot is megenged, és az adatelérés teljesítményének növelésére vagy nagymennyiségq adatok hatékony kezelésére vannak egyéb lehetQségek is:
*** Index-szervezett tábla: egyetlen objektumban valósul meg a tábla és annak indexe: tábla sorait egy B*-fa indexstruktúrába szervezi, a rendezés alapjául szolgáló indexkulcsot a tábla PRIMARY KEY oszlopa(i) adja. A B*-fa levelei az indexkulcs mellett nem egy mutatót tartalmaznak, hanem a tábla konkrét sorát. Megadható, hogy a tábla mely oszlopától jobbra esQ oszlopok kerüljenek át a túlcsordulási területre. Az index-szervezett tábla sorainak fizikai tárolási címe (ROWID) a fa átszervezésével állandóan változik. Többek között ezért van az Oracle-ben, egy mindentQl független, univerzális logikai UROWID is alkalmazva. Ez a leggyorsabb a sorok PRIMARY KEY szerinti keresésénél.
Tábla szervezését megadó záradék: [ORGANIZATION {HEAP | INDEX} ...]
-- egy index-szervezett tábla, melynek sz1, sz2 oszlopa kerül a túlcsordulási területre
CREATE TABLE varosok
(irszam CHAR(4) PRIMARY KEY, nev VARCHAR2(40), sz1 VARCHAR2(1000), sz2 VARCHAR2(1000))
ORGANIZATION INDEX INCLUDING nev OVERFLOW;
DROP TABLE varosok;
*** Klaszter: közös oszlopokat tartalmazó táblák együtt tárolt csoportja. Ezeket a közös oszlopokat a klaszterkulcs fogja össze és a tárolás/elérés kulcsául szolgál. Klaszter használatával érhetjük el, hogy egymáshoz fizikailag közel (egy logikai blokkban) tárolódjanak az azonos klaszterkulcshoz tartozó táblasorok. A táblák klaszterkulcshoz tartozó oszlopértékei csak egyszer lesznek tárolva, függetlenül a tábláktól és a soroktól, amelyekben elQfordul. Ha a klaszterkulcsot a táblák összekapcsolásánál használt oszlopok adják, vagy olyan oszlopok, amelyekre gyakran hivatkozunk együtt, akkor az teljesítmény növelést eredményez. Egy klasztert elQször definiálni kell, majd táblákat helyezünk bele.
Speciális opció segítségével hash klaszter is definiálható, amely stabil méretq táblák esetén célszerq, ahol a kulcs érték egy kulcstranszformációs függvénnyel (hash függvény) könnyen leképezhetQ tárolási címmé, a lekérdezési feltétel pedig a kulcsérték egyenlQségén alapszik. Az azonos kulcstranszformációs értékq sorok egy logikai blokkban tárolódnak.
CREATE CLUSTER klaszter_név (oszlopnév típus ,...) -- klaszterkulcs megadása
[INDEX | [SINGLE TABLE] HASKEYS darab [HASH IS kulcstranszformációs_kifejezés] ]
[tárolási és egyéb elQírások];
-- Indexelt klaszter létrehozása, majd a klaszter indexének definiálása
-- Egy klaszterkulcshoz tartozó logikai blokk mérete legyen 100K
CREATE CLUSTER telalk_klaszter (kod VARCHAR2(2)) -- klaszterkulcs leírása
SIZE 100K;
CREATE INDEX telalk_klaszter_ind ON CLUSTER telalk_klaszter;
-- Tegyünk táblákat a klaszterbe
CREATE TABLE telep CLUSTER telalk_klaszter (t_kod) -- klaszterkulcsot t_kod adja
AS SELECT * FROM telephely;
CREATE TABLE dolgozo CLUSTER telalk_klaszter (t_kod) -- klaszterkulcsot t_kod adja
AS SELECT * FROM alkalmazott;
-- ALTER TABLE -el megszorítások megadása mindkét táblára
-- ...
-- Gyorsítja a következQ lekérdezést:
SELECT * FROM telep T JOIN dolgozo D ON T.t_kod=D.t_kod;
-- Töröljük a klasztert táblákkal, megszorításokkal
DROP CLUSTER telalk_klaszter INCLUDING TABLES CASCADE CONSTRAINTS;
-- Tároljuk az alkalmazott tábla sorait a t_kod oszlopon alapuló hash klaszter
-- segítségével 5 csoportban. A hash függvényt a rendszer biztosítja.
-- A klaszterben csak egy tábla lesz (a rendszer ezt ki tudja használni)
CREATE CLUSTER alk_klaszter (t_kod VARCHAR2(2))
SINGLE TABLE HASHKEYS 5;
CREATE TABLE dolgozo CLUSTER alk_klaszter (t_kod)
AS SELECT * FROM alkalmazott;
-- ALTER TABLE -el megszorítások megadása a táblára
-- ...
SELECT * FROM dolgozo WHERE t_kod=40;
DROP CLUSTER alk_klaszter INCLUDING TABLES CASCADE CONSTRAINTS;
*** Táblák, indexek partícionálása: nagyon nagy méretq objektumokat feloszthatunk kisebb, jobban kezelhetQ részekre. A partíciók egymástól függetlenek: tárolási jellemzQket (pl. tablespace) partíciónként lehet állítani, az I/O terhelés így jobban el van osztva, partíciónként végezhetQk a mentési, visszaállítási, archiválási munkák miközben más partíciókat alkalmazások használnak. Az Oracle többféle partícionálási záradékot megenged a CREATE TABLE utasításban (az ALTER TABLE-ben is külön kezelhetQk a partíciók):
PARTITION BY RANGE (oszlop ,& ) & -- oszlop(ok) értékének értéktartományba esése alapján
PARTITION BY LIST (oszlop ,& ) & -- oszlop(ok) értékei egyeznek a listán megadott értékkel
PARTITION BY HASH (oszlop ,& ) & -- oszlop(ok) -hoz Hash függvényt alkalmazva
egyéb: -- összetett, alpartíciókkal rendelkezQ partíciókat is meg lehet adni
-- Milyen táblaterületekhez (TABLESPACE) férhetünk hozzá: DD tábla lekérdezés
-- Nézzük meg, hogy léteznek-e a HALLGATO, USERS táblaterületek
SELECT * FROM USER_TABLESPACES;
-- Hozzunk létre különbözQ partícinált táblákat az alkalmazott tábla alapján
CREATE TABLE part_alk1
PARTITION BY RANGE (premium)
(PARTITION p1 VALUES LESS THAN (60000) TABLESPACE hallgato,
PARTITION p2 VALUES LESS THAN (100000) TABLESPACE users,
PARTITION p3 VALUES LESS THAN (MAXVALUE) TABLESPACE users)
AS SELECT * FROM alkalmazott;
CREATE TABLE part_alk2
PARTITION BY LIST (beosztas)
(PARTITION p1 VALUES (NULL, 'IGAZGATO', 'VEZETO') TABLESPACE hallgato,
PARTITION p2 VALUES ('ELADO', 'SZALLITO', 'EGYEB') TABLESPACE users)
AS SELECT * FROM alkalmazott;
CREATE TABLE part_alk3
PARTITION BY HASH (a_kod)
PARTITIONS 2 STORE IN (hallgato, users)
AS SELECT * FROM alkalmazott;
-- ALTER TABLE -el megszorítások megadása a táblákra
-- ...
-- Lehet dolgozni a táblákkal, kérdezzük le a táblák egyes partícióinak sorait
SELECT * FROM part_alk1 PARTITION (p3);
SELECT * FROM part_alk1 PARTITION (p3) P WHERE P.beosztas='VEZETO';
SELECT * FROM part_alk2 PARTITION (p1);
SELECT * FROM part_alk3;
-- Vegyünk fel egy új partíciót part_alk2 -be
ALTER TABLE part_alk2 ADD PARTITION p3 VALUES ('SEGED') TABLESPACE hallgato;
-- Töröljük part_alk1 egy partíciójának adatait
ALTER TABLE part_alk1 TRUNCATE PARTITION p1;
SELECT * FROM part_alk1 PARTITION (p1);
-- Töröljünk egy üres partíciót
ALTER TABLE part_alk1 DROP PARTITION p1;
DROP TABLE part_alk1 CASCADE CONSTRAINTS;
DROP TABLE part_alk2 CASCADE CONSTRAINTS;
DROP TABLE part_alk3 CASCADE CONSTRAINTS;
Szekvencia Oracle-ben
Haladó:
Szekvencia: egyedi egész értékekbQl álló sorozatot készítQ objektum. Jól használható például egy oszlop (UNIQUE, PRIMARY KEY) egyedi értékeinek automatikus elQállítására. LeegyszerqsíthetQ vele az új egyedi érték elQállítása többfelhasználós rendszerben is. Egyes legenerált sorszámok felhasználatlanul kimaradhatnak a következQ esetekben: tranzakció visszagörgetésénél, rendszer összeomlásakor.
Szekvencia definiálása röviden :
CREATE SEQUENCE szekvencia_név
[ START WITH kezdQ_érték ] [ INCREMENT BY növekmény ]
[ MAXVALUE max_érték ] [NOCYCLE | CYCLE] [CACHE darab | NOCACHE];
Módosítása: ALTER SEQUENCE szekvencia_név ...;
Törlése: DROP SEQUENCE szekvencia_név;
Használata: NEXTVAL, CURRVAL pszeudo oszlopokkal:
SoronkövetkezQ egyedi értékének elQállítása: szekvencia_név.NEXTVAL
Aktuális értékének lekérdezése: szekvencia_név.CURRVAL
-- alkalmazott tábla elsQdleges kulcsának automatikus elQállítását segítQ szekvencia
CREATE SEQUENCE alk_seq
START WITH 2000 INCREMENT BY 10 MAXVALUE 9999;
-- Használata:
INSERT INTO alkalmazott
VALUES(alk_seq.NEXTVAL, 'Soros Pál', NULL, NULL, 100000, NULL, '10', NULL);
SELECT * FROM alkalmazott;
SELECT alk_seq.CURRVAL FROM DUAL;
-- Érvénytelenítsük a módosítást és töröljük a szekvenciát
ROLLBACK;
DROP SEQUENCE alk_seq;
DML ( Adatmanipulációs, adatkezelQ nyelv )
Tábla, nézettábla, materializált nézettábla adatainak lekérdezése: SELECT
Tábla, nézettábla adatainak karbantartása:
INSERT -- Új sor(ok) felvitele.
UPDATE -- MeglévQ sor(ok) módosítása.
DELETE -- MeglévQ sor(ok) törlése.
Megjegyzések:
A karbantartó mqveletek által kezelt adatoknak ki kell elégíteni az integritási megszorítási szabályokat, egyébként a rendszer nem hajtja végre az utasítást, hibajelzést ad:
ORA-hibakód: szöveges üzenet (sémanév.megszorításnév)
Egy-egy karbantartó utasítással csak egy táblát kezelhetünk. (Az újabb verziókban megjelentek a több táblát karbantartó speciális DML utasítások is.) Az utasításokban szereplQ alselectek, más táblá(k)ra is hivatkozhatnak és korrelációban lehetnek a karbantartó utasítással kezelt táblával.
A rendszer a táblákhoz kapcsolódó index-objektumokat automatikusan karbantartja.
Adatok lekérdezése - lásd 2. fejezet
Adatok felvitele
INSERT INTO tábla [t_aliasnév] [(oszlop , ... )]
{ VALUES ( sql_kifejezés , ... ) | alselect | (alselect) };
Ha az oszlop felsorolás elmarad, akkor az összes oszlopra vonatkozik az értékadás a CREATE TABLE utasításban megadott sorrendben.
Az oszlop és a VALUES sql_kifejezés listák párjainak típusban és értéktartományban illeszkedni kell, darabszámuknak pedig meg kell egyezni. Speciális értékek megadhatók az sql_kifejezés helyén: NULL, DEFAULT, SYSDATE+7, USER, stb. Skalár értéket adó alselect is lehet itt. Dátumkonstansokat az alapértelmezett dátumformátum szerint vagy TO_DATE konverziót alkalmazva adhatunk meg, ha az idQpont elmarad, az alapértelmezett idQ éjfél.
Az alselect más táblá(k)ból nyert adatok felvitelét teszi lehetQvé. Több sor is felvihetQ egy utasítással.
-- Sikeresen végrehajtódnak:
INSERT INTO telephely VALUES ('80', 'Mindenki ABC-je', 'SZEGED');
INSERT INTO alkalmazott
VALUES('1990', 'Pepita Pál', 'SZALLITO', DEFAULT, 100000, NULL, '30', NULL);
-- Hiányos oszloplista: a meg nem adott oszlopokba ha van DEFAULT érték, akkor az,
-- egyébként NULL kerül:
INSERT INTO alkalmazott (a_kod, a_nev, t_kod, fizetes)
VALUES('1991', 'Kiss Edit', '10', 100000);
-- IdQpont explicit megadása dátumkonstansban (hogy ne éjfél legyen):
INSERT INTO alkalmazott
VALUES('1992', 'IdQ Pál', 'ELADO', TO_DATE('03-01-31 13:55', 'RR-MM-DD HH24:MI'),
80000, 40000, '30', 1003);
-- Nézzük meg a módosításokat
SELECT * FROM telephely;
SELECT a_kod, a_nev, beosztas, TO_CHAR(belepes, 'YYYY-MM-DD HH24:MI:SS') AS belepes,
fizetes, premium, t_kod, fonok FROM alkalmazott;
-- Érvénytelenítsük a módosításokat
ROLLBACK;
-- Megszegik valamelyik integritási szabályt, nem hajtódnak végre:
INSERT INTO telephely VALUES (10, 'Rossz ABC', 'SZEGED');
INSERT INTO telephely VALUES (NULL, 'Rossz ABC', 'SZEGED');
INSERT INTO telephely VALUES (100, 'Rossz ABC', 'SZEGED');
INSERT INTO telephely VALUES (60, 'Rossz ABC', 'Szeged');
INSERT INTO alkalmazott
VALUES('1999', 'Rossz Pál', 'SZALLITO', SYSDATE, 100000, NULL, '99', NULL);
INSERT INTO alkalmazott
VALUES('1999', 'Rossz Pál', 'SZALLITO', NULL, 100000, NULL, '10', '9999');
INSERT INTO alkalmazott
VALUES('1999', 'Rossz Pál', 'SZALLITO', NULL, 1234567, NULL, '10', NULL);
INSERT INTO alkalmazott
VALUES('1999', 'Rossz Pál', 'SZALLITO', NULL, -100000, NULL, '10', NULL);
INSERT INTO alkalmazott
VALUES('1999', 'Rossz Pál', 'FUVAROS', NULL, 100000, NULL, '10', NULL);
-- Egy alselectes példa
CREATE TABLE szemely (kod NUMBER, nev VARCHAR2(20));
INSERT INTO szemely
SELECT a_kod, INITCAP(a_nev) FROM alkalmazott WHERE beosztas='ELADO';
SELECT * FROM szemely;
DROP TABLE szemely;
Haladó:
*** Több táblás INSERT: Egy alselectbQl adatfelvitel egy vagy több táblába feltétel nélkül vagy feltétellel:
a). Feltétel nélküli több-táblás INSERT:
INSERT ALL
{ INTO tábla [t_aliasnév] [(oszlop , ... )] VALUES ( sql_kifejezés , ... ) }...
alselect;
/* HETI_JUTALEK tábla tartalmazza a dolgozók adott héten, naponként kapott jutalékainak
összegét, ezeket át kell tölteni egy egészen más szerkezetq JUTALEK táblába. */
CREATE TABLE heti_jutalek (d_kod NUMBER, het_kezdo_datum DATE, hetfo NUMBER, kedd NUMBER,
szerda NUMBER, csutortok NUMBER, pentek NUMBER);
CREATE TABLE jutalek(d_kod NUMBER, datum DATE, osszeg NUMBER);
INSERT INTO heti_jutalek VALUES(111, '04-AUG-30', 100, 200, 300, 400, 500);
INSERT INTO heti_jutalek VALUES(222, '04-AUG-30', 200, 300, 400, 500, 600);
INSERT INTO heti_jutalek VALUES(111, '04-SZE-06', 300, 400, 500, 600, 700);
INSERT ALL
INTO jutalek VALUES(d_kod, het_kezdo_datum, hetfo)
INTO jutalek VALUES(d_kod, het_kezdo_datum+1, kedd)
INTO jutalek VALUES(d_kod, het_kezdo_datum+2, szerda)
INTO jutalek VALUES(d_kod, het_kezdo_datum+3, csutortok)
INTO jutalek VALUES(d_kod, het_kezdo_datum+4, pentek)
SELECT * FROM heti_jutalek;
SELECT * FROM heti_jutalek;
SELECT * FROM jutalek ORDER BY d_kod, datum;
DROP TABLE jutalek;
DROP TABLE heti_jutalek;
b). Feltételes több-táblás INSERT:
INSERT [ ALL | FIRST ]
WHEN feltétel THEN { INTO tábla [t_aliasnév] [(oszlop , ... )] VALUES ( sql_kifejezés , ... ) }...
...
[ELSE { INTO tábla [t_aliasnév] [(oszlop , ... )] VALUES ( sql_kifejezés , ... ) }... ]
alselect;
FIRST: a feltételes utasítások megszokott módján mqködik: az elsQ olyan WHEN ág INTO VALUES beszúrásai lesznek végrehajtva, melyre a feltétel igaz. Ha nincs ilyen ág és nincs ELSE ág sem, akkor nem lesz beszúrás.
ALL: Minden olyan WHEN ág INTO VALUES beszúrása(i) végrehajtva lesznek hajtva, melyre a feltétel igaz.
/* ALKALMAZOTT, TELEPHELY táblák alapján töltsünk fel 3 táblát: ALACSONY_FIZ, MAGAS_FIZ,
SZUPER_FIZ. A megoldást futtassuk le FIRST módon is, készíthetünk ELSE ágat is */
CREATE TABLE alacsony_fiz (kod NUMBER, nev VARCHAR2(20), fizetes NUMBER, valami NUMBER);
CREATE TABLE magas_fiz AS SELECT * FROM alacsony_fiz;
CREATE TABLE szuper_fiz (kod NUMBER, nev VARCHAR2(20), fizetes NUMBER,
varos VARCHAR2(20), t_kod NUMBER);
INSERT ALL
WHEN fizetes <= 90000 THEN
INTO alacsony_fiz(kod, nev, fizetes) VALUES(a_kod, nev, fizetes)
WHEN fizetes >= 150000 THEN
INTO szuper_fiz VALUES(a_kod, nev, fizetes, varos, telep)
WHEN fizetes > 90000 THEN
INTO magas_fiz(kod, nev, fizetes) VALUES(a_kod, nev, fizetes)
SELECT a_kod, INITCAP(a_nev) AS nev, fizetes, varos, A.t_kod AS telep
FROM alkalmazott A JOIN telephely T ON A.t_kod=T.t_kod;
SELECT * FROM alacsony_fiz;
SELECT * FROM magas_fiz;
SELECT * FROM szuper_fiz;
DROP TABLE alacsony_fiz;
DROP TABLE magas_fiz;
DROP TABLE szuper_fiz;
Adatok módosítása
UPDATE tábla [t_aliasnév]
SET { oszlop = sql_kifejezés | oszlop = (skalár_értéket_adó_alselect)
| (oszlop ,& ) = (egy_sort_adó_alselect) } ,...
[WHERE feltétel];
SET: megadja, hogy mely oszlopok régi értékét kell módosítani és melyek legyenek az új értékek, amelyeket alselect is szolgáltathat. NULL, DEFAULT is használható az sql_kifejezés helyén.
Ha az alselect nem ad vissza sort, akkor az oszlop(ok) értéke NULL lesz.
[WHERE feltétel]: az UPDATE-ben résztvevQ sorokat válogatja ki, e nélkül a tábla összes sora részt vesz a mqveletben.
-- Sikeresen végrehajtódnak:
-- Legyen minden alkalmazott prémiuma NULL
UPDATE alkalmazott
SET premium = NULL;
-- A NULL beosztású dolgozókat tegyük a 10-es telephelyre és legyen EGYEB a beosztása:
UPDATE alkalmazott
SET beosztas = 'EGYEB', t_kod = '10'
WHERE beosztas IS NULL;
-- Vidéki dolgozóknak adjunk 10%-os fizetésemelést:
UPDATE alkalmazott
SET fizetes = 1.1 * fizetes
WHERE t_kod IN (SELECT t_kod FROM telephely WHERE varos <> 'BUDAPEST');
-- Változtassuk meg az 50-es telephely kódját (itt még nincs alkalmazott)
UPDATE telephely SET t_kod = 51 WHERE t_kod = 50;
-- Legyen a dolgozók belépési dátuma módosítva az azonos telephelyen
-- dolgozó, leghamarabb belépett dolgozó dátumára
UPDATE alkalmazott X
SET belepes = (SELECT MIN(belepes) FROM alkalmazott WHERE t_kod = X.t_kod);
-- Nézzük meg a módosításokat
SELECT * FROM telephely;
SELECT A.*, varos FROM alkalmazott A JOIN telephely T ON A.t_kod = T.t_kod;
-- Érvénytelenítsük a módosításokat
ROLLBACK;
-- Megszegik valamelyik integritási szabályt, nem hajtódnak végre:
-- Helyezzük át a_kod=1004 dolgozót a 99-es (nem létezQ) telephelyre:
UPDATE alkalmazott
SET t_kod = '99' WHERE a_kod = '1004';
-- SzülQ táblában olyan kulcs érték nem módosítható, melyhez vannak gyereksorok
UPDATE telephely SET t_kod = 99 WHERE t_kod = 40;
Haladó:
További alselectes példák:
-- A 20-as telephelyen dolgozók fizetését ill. prémiumát növeljük meg a 30-ason dolgozók
-- átlagfizetésével ill. átlagprémiumával, belépésük dátuma pedig legyen a DEFAULT érték:
UPDATE alkalmazott X
SET belepes=DEFAULT,
(fizetes, premium) = (SELECT X.fizetes + AVG(fizetes),
NVL(X.premium, 0) + AVG(NVL(premium, 0))
FROM alkalmazott WHERE t_kod = '30')
WHERE t_kod = '20';
-- Nézzük meg a módosításokat, majd érvénytelenítsük azokat
SELECT * FROM alkalmazott WHERE t_kod = '20';
ROLLBACK;
-- Alkalmazottak eddigi fizetését növeljük meg az azonos beosztásúak
-- átlagfizetésének 10%-val (NULL beosztásúak nem kapnak fizetésemelést):
UPDATE alkalmazott X
SET fizetes = fizetes + NVL((SELECT 0.1 * AVG(fizetes) FROM alkalmazott
WHERE X.beosztas = beosztas), 0);
-- Nézzük meg a módosításokat, majd érvénytelenítsük azokat
SELECT * FROM alkalmazott;
ROLLBACK;
*** Táblák egyesítése: (pl. egy tábla karbantartásához szükséges adatsorok egy "forrás" táblában vannak):
MERGE INTO tábla [t_aliasnév] -- erre kell UPDATE vagy INSERT
USING tábla [t_aliasnév] ON (feltétel) -- adatforrás tábla
WHEN MATCHED -- ha ON (feltétel) igaz: UPDATE
THEN UPDATE SET { oszlop=sql_kifejezés } ,&
WHEN NOT MATCHED -- egyébként: INSERT
THEN INSERT(oszlop ,& ) VALUES (sql_kifejezés ,& );
/* Állítsunk elQ egy FORRAS táblát, amely a TELEPHELY táblára vonatkozó módosító
adatokat tartalmazza, majd MERGE-el végezzük el a karbantartást */
CREATE TABLE forras AS SELECT * FROM telephely WHERE 1 = 2;
INSERT INTO forras VALUES( 10, 'FQközpont', NULL);
INSERT INTO forras VALUES( 20, 'Nagy ABC', NULL);
INSERT INTO forras VALUES( 60, 'Új ABC', 'SZEGED');
MERGE INTO telephely T USING forras F ON (T.t_kod = F.t_kod)
WHEN MATCHED THEN UPDATE SET T.t_nev = F.t_nev
WHEN NOT MATCHED THEN INSERT (T.t_kod, T.t_nev, T.varos)
VALUES (F.t_kod, F.t_nev, F.varos);
SELECT * FROM forras;
SELECT * FROM telephely;
ROLLBACK;
DROP TABLE forras;
Adatok törlése
DELETE [FROM] tábla [t_aliasnév]
[WHERE feltétel];
[WHERE feltétel]: a DELETE-ben résztvevQ sorokat válogatja ki, e nélkül a tábla összes sora részt vesz a mqveletben.
-- Sikeresen végrehajtódnak
-- Egy sor törlése:
DELETE FROM telephely
WHERE t_kod = 50;
-- Tábla részlet törlése
DELETE FROM alkalmazott
WHERE beosztas = 'ELADO';
-- Nézzük meg a módosításokat
SELECT * FROM telephely;
SELECT * FROM alkalmazott;
-- Érvénytelenítsük a módosításokat
ROLLBACK;
-- Megszegik valamelyik integritási szabályt, nem hajtódnak végre
-- SzülQ táblában olyan sor nem törölhetQ, melyhez vannak gyereksorok
DELETE FROM telephely
WHERE t_kod = '10';
DELETE FROM alkalmazott
WHERE a_kod = '1001';
*** Haladó:
Tábla csonkoló DDL utasítás Oracle-ben: TRUNCATE TABLE tábla;
Törli a tábla összes sorát. A DELETE-el való törléstQl hatékonyabb, mert ez tárhely felszabadítást is végez. Gyorsabb is, mert nem generál visszagörgetési információkat, de éppen ezért a törlések nem állíthatók vissza:
-- Tábla teljes tartalmának törlése, a törlések érvényteleníthetQk
DELETE FROM alkalmazott;
ROLLBACK;
SELECT * FROM alkalmazott;
-- Tábla csonkolása, a törlések véglegesek, a ROLLBACK-al nem lehet érvényteleníteni
TRUNCATE TABLE alkalmazott;
ROLLBACK;
SELECT * FROM alkalmazott;
-- Futtassa le a mintatáblát létrehozó SQL szkriptet!
DCL ( AdatvezérlQ nyelv )
Tranzakcióvezérlés, konkurens adathozzáférés kezelése
Tranzakció: az adatfeldolgozási munka egy logikai egysége. Egy feladat szempontjából összetartozó DML utasítások sorozata. (Például egy összetett banki tranzakciós feladat megoldását alkotó DML utasítások egy tranzakciót alkotnak. Ezen DML utasítások mindegyikének sikeresen végre kell hajtódni, esetleg egyéb feltételeknek is teljesülni kell ahhoz, hogy a feladat végrehajtása komplett legyen.)
Tranzakció kezdete: az elsQ DML utasítás indítja a tranzakciót.
Tranzakció vége:
COMMIT; utasítás (véglegesítés): rögzíti a tranzakció folyamán végrehajtott adatmódosításokat az adatbázisban.
ROLLBACK; utasítás (visszagörgetés): visszaállítja a tranzakció megkezdésekor (a legutolsó explicit vagy implicit COMMIT-nál) rögzített állapotot az adatbázisban, így a tranzakcióhoz tartozó adatmódosító utasítások egyikének sem érvényesül a hatása.
Egy DDL (pl. CREATE, ALTER, DROP, TRUNCATE, RENAME) vagy DCL (pl. GRANT, REVOKE) utasítás végrehajtása elQtt és után implicit módon COMMIT lesz kiadva. Ezért a DDL és a DCL utasítások nem görgethetQk vissza ROLLBACK-el. A kiadott implicit COMMIT a DML karbantartásokat is véglegesíti.
Az eszközökbQl való normális kilépés (EXIT) vagy kijelentkezés után automatikusan COMMIT történik.
Abnormális programbefejezés esetén automatikus ROLLBACK lesz kiadva a legközelebbi indításkor. (Pl. áramszünet, rendszer összeomlása, [i]SQL*Plus ablak bezárása.)
-- Listázzuk ki az alkalmazott tábla tartalmát (kiinduló állapot)
SELECT * FROM alkalmazott;
-- Töröljük az ELADO beosztású dolgozókat
DELETE FROM alkalmazott WHERE beosztas = 'ELADO';
-- Állítsuk mindenki fizetését 1-re
UPDATE alkalmazott SET fizetes = 1;
-- Listázzuk ki az alkalmazott tábla tartalmát (minden változás látszik)
SELECT * FROM alkalmazott;
-- Adjuk ki a ROLLBACK parancsot, ez a tranzakció vége
ROLLBACK;
-- Listázzuk ki az alkalmazott tábla tartalmát (egyezik a kiinduló állapottal)
SELECT * FROM alkalmazott;
Többfelhasználós rendszerek, konkurens adathozzáférés, Oracle implicit sor szintq zárolása:
Minden komoly adatbázis-kezelQnek biztosítani kell sok felhasználó egyidejq (konkurens) hozzáférését az adatbázishoz, megtartani az adatbázis konzisztenciáját akkor is, ha több felhasználó egyidQben ugyanazzal az objektummal, vagy annak ugyanazon adatrészével szeretne dolgozni. (Például egy helyfoglaló rendszerben elQfordulhat, hogy ugyanazt az adatot, egyszerre több felhasználó tranzakciója szeretné elérni és kezelni.)
A tranzakció a felhasználók munkameneteihez kötQdik. A munkamenetek (Session) egyidejqleg, az erQforrásokat megosztva mqködnek. Egy felhasználói munkamenet egy alkalmazás vagy eszköz elindításával, az adatbázishoz való kapcsolódással indul. Egy felhasználó több munkamenetet indíthat (pl. kétszer bejelentkezve a rendszerbe ugyanazon felhasználói névvel), ugyanazon felhasználó két munkamenetének tranzakciója különbözik.
Az Oracle alapértelmezett tranzakció kezelési modellje: Egy tranzakció által módosított sorok automatikusan zárolódnak (lefoglalódnak), a már zárolt sorokat más tranzakciók nem módosíthatják, csak lekérdezhetik és ekkor is csak a tranzakció elQtti állapotot látják. A tranzakció SELECT-je nem zárol sorokat (kivétel a FOR UPDATE résszel rendelkezQ SELECT). A zárak a tranzakció végén oldódnak, addig az olyan tranzakcióknak várakozni kell, amelyek az éppen zárolt sorokat akarják módosítani. A várakozó tranzakciók a folytatáskor azonnal látják a COMMIT-ált adatmódosításokat. (Haladó: Ez az SQL92 szabvány ISOLATION LEVEL READ COMMITTED tranzakció kezelési modellje. Újabban az Oracle-ben megengedett a szabvány ISOLATION LEVEL SERIALIZABLE modellje is, amely a SET TRANSACTION utasítással állítható be, amelynek a tranzakció elsQ utasításának kell lennie.)
A rendszerek a tranzakciók során bekövetkezett adatmódosításokat egy "adatbázis pufferben" tárolják, az itt tárolt információk COMMIT-kor véglegesen átkerülnek az adatbázisba, ROLLBACK-kor pedig visszagörgetQdnek, azaz az adatbázis tranzakció elQtti állapota nem változik meg. Az ORACLE a visszaállító/visszagörgetQ szegmens (Undo, Rollback Segment) fogalmat használja erre a célra.
Explicit tranzakciókezelQ utasítások összefoglalása:
COMMIT; A tranzakció által okozott módosításokat átvezeti az adatbázisba és láthatóvá teszi azokat más tranzakciók számára, felold minden, a tranzakció mqködése közben elhelyezett zárat és törli a mentési pontokat.
ROLLBACK; Érvényteleníti a teljes tranzakció hatását (az adatbázis változatlan marad), oldja a zárakat és törli a mentési pontokat.
SAVEPOINT mentési_pont; LehetQvé teszi, hogy a tranzakció közben olyan pontot képezzünk, amely pontig részlegesen visszagörgethetjük a tranzakciót.
ROLLBACK TO mentési_pont; A megadott pontig végzi el a visszagörgetést: csak az érintett zárakat oldja és csak a megadott pontig talált mentési pontokat törli.
Az utóbbi két utasítás procedurális környezetben lehet igazán hasznos, ahol feltételtQl függQen lehet megcsinálni különbözQ részleges visszagörgetéseket.
-- DML1 utasítások ...
UPDATE telephely SET varos='BP' WHERE varos='BUDAPEST';
-- Egy mentési pont elhelyezés
SAVEPOINT A;
-- DML2 utasítások ...
UPDATE telephely SET varos='DB' WHERE varos='DEBRECEN';
-- Részleges visszagörgetés A pontig, DML2 módosításai visszagörgetQdnek
ROLLBACK TO A;
-- Listázással meggyQzQdhetünk, hogy csak a DML1 módosításai látszanak
SELECT * FROM telephely;
-- További DML-eket adhatunk ki,majd visszagörgethetjük/véglegesíthetjük a változtatásokat
ROLLBACK;
Alapfeladat: Jelentkezzünk be kétszer lnagyevaXX-ként (iSQL*Plus-t két különbözQ böngészQbQl indítva). Hajtsuk végre a következQ SQL utasításokat a megadott idQbeli sorrendben, képernyQt törölve minden "téglalapos" utasításcsoport elQtt.
1. munkamenet lnagyevaXX 2. munkamenet lnagyevaXX
-- Néhány DML
UPDATE telephely SET varos='BP1'
WHERE varos='BUDAPEST';
DELETE FROM telephely WHERE varos='EGER';
INSERT INTO telephely VALUES(60,'Kicsi ABC','PÉCS');
-- Saját tranzakcióját látja, SELECT nem zárol sorokat
SELECT * FROM telephely; -- Nem látja mások tranzakcióját
SELECT * FROM telephely;
-- Nem zárolt sorokat módosíthat
UPDATE telephely SET varos='DB2'
WHERE varos='DEBRECEN';
-- Saját tranzakcióját látja
SELECT * FROM telephely; -- Zárolt sorokat nem módosíthat,
-- hibajelzés nélkül vár a zárak feloldására
UPDATE telephely SET varos='BP2'
WHERE varos='BUDAPEST';
DELETE FROM telephely
WHERE varos='EGER'; -- Véglegesítés, zárak feloldódnak
COMMIT; -- Tovább tudott dolgozni,
-- azonnal látta az 1. módosításait
-- (READ COMMITTED viselkedés miatt),
-- de már egyik WHERE feltétel sem volt igaz.
-- EllenQrzés, véglegesítés
SELECT * FROM telephely;
COMMIT; -- Futtassuk le a mintatáblát létrehozó SQL szkriptet
@http://delfin.unideb.hu/~lnagyeva/SQL/create_telalk.sql
Haladó:
Implicit utasításszintq visszagörgetés: Ha a tranzakció egy DML utasításának (mely több sort is kezelhet) végrehajtása során bármilyen hiba van, akkor a rendszer a hibás utasítást teljes egészében automatikusan visszagörgeti, a tranzakció többi DML-jének módosítása megmarad. A felhasználónak ekkor is explicit módon (COMMIT vagy ROLLBACK) kell befejeznie a tranzakciót.
Kétfázisú COMMIT: Osztott adatbázisok esetén osztott tranzakciók lehetnek: egy tranzakció több (helyi és távoli) adatbázisban lévQ táblát használ. A rendszerek úgynevezett kétfázisú COMMIT mechanizmusa garantálja azt, hogy az osztott módosítást végzQ tranzakciók biztonságosan végrehajtódjanak: csak minden szerveren sikeresen lezajlott érvényesítés után, egy második fázisban történik meg a végleges COMMIT, vagy az egész tranzakció vissza lesz görgetve minden szerveren. Így biztosítva van az adatok konzisztenciája osztott adatbázisok esetén is.
Holtpont (Deadlock): két vagy több munkamenet tranzakciója kölcsönösen vár egymásra a zárak miatt. Mindegyik vár olyan zárak feloldására, amelyet egy másik holtpontra jutott résztvevQnek kellene végrehajtani. A rendszer automatikusan észreveszi a holtpontok létrejöttét és valamilyen stratégia szerint hibaüzenetet küld a résztvevQknek.
1. munkamenet - lnagyevaXX 2. munkamenet lnagyevaXX
UPDATE telephely SET varos='DB1'
WHERE varos='DEBRECEN'; UPDATE telephely SET t_nev='ABC2'
WHERE varos='BUDAPEST'; -- Zárolt sorokat nem módosíthat,
-- hibajelzés nélkül vár a zárak oldására
UPDATE telephely SET varos='DB2'
WHERE varos='DEBRECEN'; -- Zárolt sorokat nem módosíthat,
-- hibajelzés nélkül vár a zárak feloldására
UPDATE telephely SET t_nev='ABC1'
WHERE varos='BUDAPEST'; -- vagy itt HOLTPONT hibajelzés -- vagy itt HOLTPONT hibajelzés !!! -- zárak feloldása:
ROLLBACK; -- tovább tud dolgozni
ROLLBACK;
Olvasási konzisztencia: egy SELECT a lekérdezés kezdetekor érvényes konzisztens adatokat használja, akkor is ha a lekérdezés ideje alatt más felhasználók tranzakciója módosította és véglegesítette a SELECT által használt táblákat. A rendszer a lekérdezés számára egy "pillanatfelvételt" hoz létre az adatbázisról.
Tranzakció tulajdonságai: Egy tranzakció tulajdonságai, kezelési modellje a SET TRANSACTION ... ; utasítással állítható be. Ennek az utasításnak mindig a tranzakció elsQ utasításának kell lenni. A tranzakciók alaphelyzetben olvasható-írható tranzakciók, azaz READ WRITE van beállítva, és minden DML kiadható benne. Használjuk a READ ONLY beállítást a csak-olvasható tranzakció indításához. Ez csak a SELECT DML utasítást engedi meg és a tranzakció lekérdezései az adatbázisnak ugyanazon kezdeti "pillanatfelvételét" látják. Más tranzakciók által okozott véglegesített változtatásokat a tranzakció nem látja.
Példa: olvasási konzisztencia biztosítása több egymást követQ lekérdezésnél:
1. munkamenet lnagyevaXX 2. munkamenet - lnagyevaXX
-- pillanatfelvétel készül az adatbázisról
SET TRANSACTION READ ONLY;
SELECT * FROM alkalmazott; -- sorok törlése és véglegesítése
DELETE FROM alkalmazott
WHERE beosztas='ELADO';
COMMIT; -- nem látja 2. COMMIT-ált változtatásait
SELECT * FROM alkalmazott; -- zárjuk az olvasási tranzakciót
COMMIT;
-- most már látja 2. COMMIT-ált változtatásait
SELECT * FROM alkalmazott; -- Futtassa le a mintatáblát létrehozó SQL szkriptet!
@http://delfin.unideb.hu/~lnagyeva/SQL/create_telalk.sql
Explicit zárolás: Speciális helyzetekben kiadhatók explicit módon tábla és sor szintq lefoglalások:
SELECT ...
[ FOR UPDATE [OF oszlop,...] [ NOWAIT | WAIT [másodperc] ] ;
A SELECT által leválogatott sorok zárolásra kerülnek egy késQbbi UPDATE vagy DELETE utasítás számára. ElsQsorban akkor használjuk, amikor biztosak akarunk lenni abban, hogy a leválogatott sorokat más felhasználó nem módosítja addig, míg mi a módosításokat végre nem hajtjuk.
OF oszlop,... rész akkor kell, amikor a SELECT több táblát használ és nem akarjuk mindegyik táblában az érintett sorokat zárolni, hanem csak azon táblák sorait, amelyekbQl oszlop (mint jelzQ-oszlop) szerepel az OF listán. Ha a leválogatott sorok zárolása sikertelen (más tranzakciók által történt zárolás miatt), akkor alapértelmezésként hibajelzés nélkül korlátlan ideig várakozik a zárak feloldására, de beállítható, hogy WAIT másodperc várakozás után, vagy NOWAIT esetén azonnal, adjon hibaüzenetet. Példák:
-- Mindkét tábla érintett sorait zárolja.
-- Hibajelzés nélkül várna: WAIT végtelen.
SELECT * FROM alkalmazott A
JOIN telephely T ON A.t_kod = T.t_kod AND T.varos = 'DEBRECEN'
FOR UPDATE;
-- Csak az alkalmazott tábla érintett sorait zárolja.
-- Azonnal (NOWAIT) vagy várakozás után (WAIT 10) adna hibajelzést:
-- az erQforrás foglalt: sikertelen volt a zárolás.
SELECT * FROM alkalmazott A
JOIN telephely T ON A.t_kod = T.t_kod AND T.varos = 'DEBRECEN'
-- FOR UPDATE OF A.t_kod NOWAIT
FOR UPDATE OF A.t_kod WAIT 10;
*** LOCK TABLE tábla ,& IN zárolási_mód MODE [NOWAIT];
Segítségével egy vagy több táblát tudunk zárolni a megadott módon. Ez felülírja az automatikus zárolás vezérlést. Külön rendszerjog (LOCK ANY TABLE) kell a használatához. A zárolási módokat nem ismertetjük.
*** Megszorítások ellenQrzési tevékenységének elhalasztása a tranzakció végéig: Egy elhalasztható (DEFERRABLE) állapotú megszorítás ellenQrzésének a mikéntjét a SET CONSTRAINT[S] utasítással állíthatjuk be egy konkrét tranzakciónál, mely beállítás az adott tranzakció végéig érvényes Lásd még a DDL utasításoknál a megszorítás_állapot pontos leírását.
SET CONSTRAINT[S] { meszorításnév ,... | ALL } { IMMEDIATE | DEFERRED };
IMMEDIATE: azonnal, a DML utasítás végrehajtásakor lesznek az adatok a megszorítással ellenQrizve. DEFERRED: legyen elhalasztva az ellenQrzés a tranzakció végéig.
ALL: a tranzakció összes elhalasztható (DEFERRABLE) állapotú megszorítását állítja.
-- Definiáljunk egy táblát, melyben a telephelyekhez tartozó épületeket tároljuk
-- A megszorítások elhalaszthatók legyenek, de kezdetben azonnal ellenQrizzenek
CREATE TABLE epulet
( ep_kod VARCHAR2(4) CONSTRAINT ep_pk PRIMARY KEY DEFERRABLE,
ep_nev VARCHAR2(20),
t_kod VARCHAR2(4) CONSTRAINT ep_fk REFERENCES telephely(t_kod) DEFERRABLE );
-- Indul a tranzakció
INSERT INTO epulet VALUES('B500' , 'Központi bolt', '50');
-- Nem létezQ telephelyhez nem vehetünk fel épületet
INSERT INTO epulet VALUES('R600' , 'Raktár', '60');
-- Állítsuk be a megszorítás elhalasztását
SET CONSTRAINTS ep_pk, ep_fk DEFERRED;
-- Most már felvihetjük az elözQ sort
INSERT INTO epulet VALUES('R600' , 'Raktár', '60');
-- Utólag vigyük fel a telephelyet
INSERT INTO telephely VALUES('60', 'Új ABC', 'SZOLNOK');
-- Még a következQ is megcsinálható most
UPDATE telephely SET t_kod ='70' WHERE t_kod='50';
UPDATE epulet SET t_kod ='70' WHERE t_kod='50';
-- Véglegesítéskor történnek meg az elhalasztott megszorítások ellenQrzései
-- Ha véglegesítéskor hiba lenne, hibajelzést és automatikusan ROLLBACK-t ad ki
COMMIT;
-- EllenQrzés
SELECT * FROM telephely;
SELECT * FROM epulet;
DROP TABLE epulet;
-- Futtassuk le a mintatáblát létrehozó SQL szkriptet
@http://delfin.unideb.hu/~lnagyeva/SQL/create_telalk.sql
Felhasználók kezelése, jogosultságaik szabályozása
Rendszergazda (DBA: Database Administrator): kitüntetett felhasználó, aki felügyeli az egész rendszer mqködését. A rendszer installálása során automatikusan létrejön egy vagy több DBA felhasználó (Oracle-ben: SYS, SYSTEM), akik a DBA feladatok elvégzéséhez szükséges jogokkal rendelkeznek.
DBA veszi fel az új felhasználókat a rendszerbe:
CREATE USER felhasználó_név IDENTIFIED BY jelszó
[alapértelmezett_tárolási_elQírások] [erQforrás_korlátozások];
Felhasználók módosítása, törlése az ALTER USER & ; DROP USER & ; parancsokkal végezhetQ el.
A felhasználó is használhatja ezt az utasítást de csak a saját jelszavának módosítására:
ALTER USER felhasználó_név IDENTIFIED BY jelszó;
Séma (SCHEMA): Objektumok névvel ellátott gyqjteménye. Oracle-ben a CREATE USER végrehajtásakor a felhasználóhoz automatikusan létrejön egy séma, amely a felhasználó által definiált (CREATE & ) adatbázis objektumokat foglalja magába. A séma neve azonos a felhasználói névvel és Q a tulajdonosa a sémában lévQ objektumoknak.
Adatvédelem, adatbiztonság megoldása: rendszer- és adatvédelem: Többfelhasználós rendszerekben szabályozni kell tudni, hogy ki mit csinálhat a rendszerben és milyen adatokhoz férhet hozzá, azaz milyen jogosultságai vannak.
Jogosultságok (Privileg) fajtái és nevei:
Rendszerjogok: a rendszer használatával kapcsolatos jogok, azaz milyen tevékenységeket (pl. DDL utasításokat) hajthat végre. DBA adja ezeket. Néhány rendszerjog neve:
CREATE USER, CREATE SESSION, CREATE [ANY] TABLE, CREATE [ANY] VIEW,
CREATE [ANY] SEQUENCE, CREATE [ANY] PROCEDURE, CREATE ROLE,
GRANT ANY PRIVILEGE, GRANT ANY OBJECT PRIVILEGE stb.
ANY jelentése: bármelyik felhasználó sémájában dolgozhat az adott utasítással.
Kérdezzük le, hogy a munkamenetben (Session) milyen rendszerjogaink vannak:
SELECT * FROM SESSION_PRIVS;
Objektumjogok (adathozzáférési jogok): konkrét objektumok használatával kapcsolatos jogok. A felhasználó a saját sémájában lévQ objektumok használatára minden jogosultságot megkap továbbadható módon, más felhasználók objektumaihoz pedig csak konkrét jogok birtokában férhet hozzá. Hozzáférési jogokat az objektum létrehozója (tulajdonosa) vagy a DBA adhat másoknak. A konkrétan megadható objektumjogok az objektum típusától függenek. Néhány objektumjog neve tábla esetén:
SELECT, DELETE, INSERT[(oszlop, & )], UPDATE[(oszlop, & )],
REFERENCES[(oszlop, & )], ALTER, INDEX, stb.
Tehát az objektumjogok egy részénél lehetQség van a hozzáférhetQ oszlopok körének szqkítésére is.
Szerepkör (ROLE): Jogosultságok névvel ellátott gyqjteménye. Egy olyan objektum, melybe jogosultságokat lehet elhelyezni, azzal a céllal, hogy egyetlen hozzárendeléssel a benne lévQ összes jogot hozzárendelhessük felhasználókhoz vagy más szerepkörökhöz. A szerepkörök a jogosultság adás/visszavonás munkát egyszerqsítik.
CREATE ROLE szerepkör_név & ;
CREATE ROLE konyvelo;
Egyes rendszerekben installálás után automatikusan létrejön néhány célszerqen kialakított, elQredefiniált szerepkör, amelyeket a DBA késQbb módosíthat. Ezek általában az adatbázist használók három alapvetQ típusának - egyszerq felhasználó, fejlesztQ, adatbázis adminisztrátor - jogait, tevékenységi körét határozzák meg. Oracle-ben jelenleg ezen szerepkörök nevei rendre: CONNECT, RESOURCE, DBA.
Rendszerjogok adása:
GRANT {rendszerjog | szerepkör | ALL [PRIVILEGES]} , ...
TO {felhasználónév | szerepkör | PUBLIC}, &
[WITH ADMIN OPTION];
Rendszerjogok visszavonása:
REVOKE {rendszerjog | szerepkör | ALL [PRIVILEGES]},&
FROM {felhasználónév | szerepkör | PUBLIC}, & ;
PUBLIC az összes adatbázis felhasználót, ALL PRIVILEGES az összes rendszerjogot jelenti. WITH ADMIN OPTION esetén a felhasználó a kapott jogokat továbbadhatja (visszavonhatja) más felhasználóknak vagy szerepköröknek.
GRANT CREATE TABLE, CREATE VIEW TO konyvelo;
GRANT konyvelo TO kiss, kovacs;
GRANT CONNECT, RESOURCE TO nagy;
Objektumjogok adása:
GRANT {objektumjog [(oszlop, & )] | ALL [PRIVILEGES]},&
ON objektum
TO {felhasználónév | szerepkör | PUBLIC}
[WITH GRANT OPTION];
PUBLIC az összes adatbázis felhasználót, ALL PRIVILEGES az adott objektumhoz tartozó összes objektumjogot jelenti. WITH GRANT OPTION esetén a felhasználó a kapott jogokat továbbadhatja más felhasználóknak. Táblánál az adathozzáférés oszlopok szintjéig finomítható!
GRANT UPDATE(t_nev, varos), SELECT
ON telephely TO kiss;
Objektumjogok visszavonása:
REVOKE {objektumjog | ALL [PRIVILEGES]},&
ON objektum
FROM {felhasználónév | szerepkör | PUBLIC},&
[CASCADE CONSTRAINTS];
A másoknak WITH GRANT OPTION lehetQség szerint továbbadott jogosultságok is visszavonódnak. Az oszlopszintq jogok egyenként nem vonhatók vissza. CASCADE CONSTRAINTS csak a REFERENCES jogosultság visszavonása esetén kell, hogy a kapott jogosultság alapján definiált hivatkozási integritási megszorítások törlQdjenek.
Haladó:
*** Néhány idevonatkozó Oracle DD tábla lekérdezése:
-- Aktuális felhasználó általános paraméterei
SELECT * FROM USER_USERS;
-- erQforrás korlátozásai
SELECT * FROM USER_RESOURCE_LIMITS;
-- munkamenetünk rendszerjogai
SELECT * FROM SESSION_PRIVS;
-- megkapott/elérhetQ szerepkörök (role)
SELECT * FROM USER_ROLE_PRIVS;
-- szerepkörökben lévQ rendszerjogok
SELECT * FROM ROLE_SYS_PRIVS;
-- szerepkörökben lévQ objektumjogok
SELECT * FROM ROLE_TAB_PRIVS;
-- közvetlenül kapott rendszerjogok
SELECT * FROM USER_SYS_PRIVS;
*** Hajtsuk végre a következQ - objektumjogokra vonatkozó - feladatsort a szomszédunkkal egyeztetve:
(Ha lenne CREATE ROLE rendszerjogunk, akkor praktikusabb megoldást alakíthatnánk ki!)
1. munkamenet - lnagyevaXX 2. munkamenet - lnagyevaYY -- objektumjogok adása
GRANT UPDATE(t_nev, varos), SELECT, INSERT
ON telephely TO lnagyevaXX; -- milyen objektumokhoz férhetünk hozzá
SELECT * FROM ALL_OBJECTS
WHERE OBJECT_TYPE='TABLE'; -- milyen objektumjogokat kaptunk
SELECT * FROM USER_TAB_PRIVS_RECD;
-- milyen, objektum oszlopára vonatkozó jogokat kaptunk
SELECT * FROM USER_COL_PRIVS_RECD;
-- milyen objektumjogokat adtunk
SELECT * FROM USER_TAB_PRIVS_MADE;
-- milyen, objektum oszlopára vonatkozó jogokat adtunk
SELECT * FROM USER_COL_PRIVS_MADE;
-- néhány DML mqvelet
UPDATE lnagyevaYY.telephely
SET varos='XXX' WHERE varos='DEBRECEN';
SELECT * FROM lnagyevaYY.telephely;
-- Hozzunk létre privát szinonímát
CREATE SYNONYM telep
FOR lnagyevaYY.telephely;
-- néhány DML mqvelet szinonimával
UPDATE telep
SET varos='YYY' WHERE varos='EGER';
SELECT * FROM telep; -- objektumjogok visszavonása
REVOKE UPDATE, SELECT, INSERT
ON telephely FROM lnagyevaXX; -- telephely tábla nem elérhetQ
SELECT * FROM telep;
-- szinonima törlése
DROP SYNONYM telep; -- lnagyevaXX DDL-jei miatt implicit COMMIT volt
SELECT * FROM telephely; Futtassa le a mintatáblát létrehozó SQL szkriptet!
*** Az SQL szabványban és az Oracle-ben is létezik egy CREATE SCHEMA utasítás. A szabványban:
CREATE SCHEMA sémanév AUTHORIZATION felhasználó_név ... ;
Oracle-ben nem ez hozza létre a sémát, hanem csak "benépesíti" objektumokkal. A CREATE SCHEMA utasítás lehetQvé teszi objektumok definiálását és jogosultságok adományozását egyetlen "tranzakció" alatt. Ha minden parancs végrehajtása sikeres, akkor automatikus véglegesítés történik, ha valamelyik hibás, akkor minden DDL parancs vissza lesz görgetve.
-- A következQ DDL utasítások egyike sem lesz végrehajtva, pedig csak a legutolsó hibás.
-- (Mert x2 oszlop nem elsQdleges kulcsa a tt1 táblának.)
CREATE SCHEMA AUTHORIZATION lnagyevaXX
CREATE TABLE tt1 (x1 NUMBER PRIMARY KEY, x2 NUMBER)
GRANT SELECT ON tt1 TO PUBLIC
CREATE VIEW v1 AS SELECT * FROM tt1 WHERE x1<500
CREATE TABLE tt2 (y1 NUMBER, y2 NUMBER REFERENCES tt1(x2));
Mellékletek
6.1. Mintafeladat - Oracle9i
6.2 *** Oracle adatbázis-kezelõ rendszer architektúrája, komponensei
Mintafeladat - Oracle9i
Egy kereskedéssel foglalkozó cég telephelyeinek és az ott dolgozó alkalmazottak adatainak nyilvántartása.
Táblák és kapcsolatuk: TELEPHELY (T_KOD, T_NEV, VAROS)
ALKALMAZOTT (A_KOD, A_NEV, BEOSZTAS, BELEPES, FIZETES, PREMIUM,
T_KOD (> TELEPHELY(T_KOD), FONOK(>ALKALMAZOTT(A_KOD))
Szabályok:
A TELEPHELY-ek és az ALKALMAZOTT-ak azonosítására kódokat alkalmaznak (T_KOD, A_KOD).
Egy TELEPHELY foglalkoztathat egy vagy több ALKALMAZOTT-at. Egy ALKALMAZOTT kell, hogy tartozzon egy és csak egy TELEPHELY-hez.
Egy ALKALMAZOTT-nak lehet egy vagy több beosztottja. Egy ALKALMAZOTT-nak lehet egy fQnöke.
Egyéb szabályok: T_NEV, A_NEV megadása kötelezQ. VAROS csak nagybetqs lehet. BELEPES dátumának alapértelmezett értéke a rendszerdátum. FIZETES>0 és kötelezQ megadni.
BEOSZTAS neve csak IGAZGATO, VEZETO, ELADO, SZALLITO, EGYEB lehet.
Táblákat létrehozó SQL utasítások (Lásd create_telalk.sql parancsfájl)
CREATE TABLE telephely
(t_kod VARCHAR2(2) CONSTRAINT tel_pk PRIMARY KEY,
t_nev VARCHAR2(15) NOT NULL,
varos VARCHAR2(15)
CONSTRAINT tel_varos CHECK(varos=UPPER(varos))
); CREATE TABLE alkalmazott
(a_kod VARCHAR2(4) CONSTRAINT alk_pk PRIMARY KEY,
a_nev VARCHAR2(15) NOT NULL,
beosztas VARCHAR2(15),
belepes DATE DEFAULT SYSDATE,
fizetes NUMBER(6) NOT NULL CONSTRAINT alk_fiz CHECK(fizetes>0),
premium NUMBER(6),
t_kod VARCHAR2(2) NOT NULL,
fonok VARCHAR2(4),
CONSTRAINT alk_fk1 FOREIGN KEY (t_kod) REFERENCES telephely(t_kod),
CONSTRAINT alk_fk2 FOREIGN KEY (fonok) REFERENCES alkalmazott(a_kod),
CONSTRAINT alk_beosztas
CHECK(beosztas IN ('IGAZGATO','VEZETO','ELADO','SZALLITO','EGYEB')) );
Táblák feltöltése után azok tartalma:
SELECT * FROM telephely;
T_ KOD T_NEV VAROS 10 Központ BUDAPEST 20 Maxi ABC BUDAPEST 30 Mini ABC DEBRECEN 40 Maxi ABC DEBRECEN 50 Kiskosár CBA EGER SELECT * FROM alkalmazott;
A_KOD A_NEV BEOSZTAS BELEPES FIZETES PREMIUM T_KOD FONOK 1001 Szabó Pál IGAZGATO 98-MÁJ-01 250000 150000 10 1002 Német Éva VEZETO 98-DEC-09 150000 20 1001 1003 Horvát Péter VEZETO 00-JÚN-01 160000 100000 30 1001 1004 Pap Éva VEZETO 01-JÚN-01 170000 110000 40 1001 1005 Nagy Ede EGYEB 98-DEC-01 100000 80000 10 1001 1006 Kelemen Edit EGYEB 03-NOV-28 60000 10 1001 1007 Kovács Edit ELADO 98-DEC-10 60000 50000 20 1002 1008 Nagy Zita SZALLITO 99-FEB-08 100000 20 1002 1009 Kis Csaba ELADO 99-MÁR-12 90000 40000 20 1002 1010 Tóth Imre ELADO 99-ÁPR-22 90000 20 1002 1011 Balog Judit ELADO 01-MÁJ-09 100000 40000 30 1003 1012 Király Linda ELADO 01-AUG-04 60000 50000 40 1004 1013 NAGY EDE ELADO 01-NOV-12 90000 50000 40 1004 1014 Bodnár Béla SZALLITO 02-OKT-08 110000 60000 40 1004 1015 KOVÁCS ILDIKÓ SZALLITO 04-MÁJ-23 90000 40 1004 1016 KIS PÁL EDE 50000 40 1004
*** Oracle adatbázis-kezelQ rendszer architektúrája, komponensei
Adatbázis szerver: DB + DBMS: összetartozó adatok halmaza fájlokban, melyet az DBMS egy egységként kezel és csak az DBMS-en keresztül férhetünk hozzá. (Egyszerqen: fájlok + kezelQ programok).
ORACLE DB szerver: ORACLE DB + ORACLE példány (Instance). Egy számítógépen több ORACLE példány futhat, mindegyik a saját adatbázisát kezeli.
DB struktúra: Fizikai szinten fájlok, a fizikai tároláshoz.
Logikai struktúra: adatbázis, táblatér, szegmens (és kiterjesztései), blokk.
Ezen szintek egymástól függetlenül menedzselhetQk a DBA által és az SQL utasításokra nincs hatással. A fejlesztQ csak a logikai struktúrán keresztül irányíthatja, hogy a fizikai tárhely hogyan legyen használva.
DB fizikai fájlok: összetartozó konzisztens fájlok alkotják a DB-t.
Adatfájlok: legalább 1 db, az adatszótár és felhasználói táblák, indexek, stb. számára.
Redo log fájlok (változásnapló): legalább 2 db, melyeket felváltva ciklikusan ír felül, és kérhetQ ezekrQl a felülírás elQtti automatikus mentés (archiválás). Az adatbázisban végbement változásokat naplózza ide, itt minden, az adatbázis helyreállításához (Recovery) szükséges adat tárolásra kerül. SQt az adatbázis fájlokba késleltetve (gyors commit, majd amikor szabad idQ van) íródnak be a committált adatok. Fontosak nagyon, ezért szoftveresen tükröztetni szokás különbözQ diszkeken. Ezt használja a rendszer az automatikus DB helyreállításhoz (pl. rendszerhiba, áramszünet esetén: committáltra tranzakciókra: Rollforward Recovery; nem committáltra: Rollback Recovery). Diszkhiba estén a DBA ezt használja a DB helyreállításhoz: kell hozzá: adatfájlok régebbi kópiája + azóta íródott redo log fájlok.
Kontroll fájlok (vezérlQ fájlok): mqködéshez szükséges információk (pl. adatbázis név, adatfájlok, redo log fájlok nevei, státuszai). Az instance indításakor az INIT.ORA inicializáló paraméterfájlból veszi ennek a fájlnak a nevét. Addig nem indul el míg az itt tárolt információk alapján az adatbázishoz tartozó fájlokat nem találja meg, vagy ezek nem konzisztensek.
DB logikai szerkezete:
Adatbázis (Database): Egy kollekciója az adatoknak, amelyet a DBMS egy egységként kezel. (Utasítások: CREATE DATABASE & ; ALTER DATABASE ...;) Az Oracle installálásával egy menetben létrehozható az adatbázis.
Táblaterület (Tablespace): Egy táblaterületet egy vagy több fizikai fájl alkot, melyek lehetnek különbözQ diszkeken is. Az elsQ tablespace neve SYSTEM az adatszótárnak, a többit a rendszer vagy a DBA hozza létre (UNDOTBS, TEMP, USERS, stb.). KésQbb - akár újabb fájlok hozzáadásával - növelhetQ a tablespacek mérete, de a méret nem csökkenthetQ, csak törölhetQ az egész. A DBA megadhatja egy felhasználónak a default táblaterületét, egyébként a SYSTEM lesz az. A felhasználó a tablespacet egységes logikai területként érzékeli, ebben tárolódnak az objektumai. Egy objektum teljes egészében egy táblaterületben van, arra már nem lehet hatni, hogy mely fájl(ok)ban legyen tárolva. (Utasítások: CREATE TABLESPACE & ; ALTER TABLESPACE ...; DROP TABLESPACE ...;)
Szegmens: Egy objektum tárolásához rendelt terület. Fajtái: Adat, Index, Undo vagy Rollback, Temp, stb. Minden szegmens tárolási paraméterekkel rendelkezik, ezek diktálják a szegmenst alkotó kiterjesztések (Extent) méretét. Ha a kezdeti méreten túl kér az objektum újabb és újabb kiterjesztést mekkorát kapjon, a szegmensek mérete dinamikus növelhetQ és a túlzott szétaprózódás elkerülhetQ. Egy kiterjesztés folytonos blokkokból áll, egy szegmenst alkotó kiterjesztések már nem biztos. Szegmenseknek odaítélt kiterjesztések nem adódnak vissza, még akkor sem ha nincs rá szükség.
Egyes szegmenseket a rendszer hozza létre automatikusan. A fejlesztQ az objektum tárolási elQírásait a definiálásakor adhatja meg. Ha nem adunk tablespacet vagy más tárolási paramétert, akkor mindig a defaultot veszi. Tárolási elQírás záradékokat lehet elhelyezni a CREATE TABLE, CREATE INDEX, CREATE MATERIALIZED VIEW, CREATE CLUSTER, CREATE ROLLBACK SEGMENT, stb. utasításokban, az ALTER utasításokban azok módosíthatók, DROP-al törölhetQk és a tárhely is felszabadul. Az Oracle korábbi verzióiban a DBA által menedzselt ROLLBACK SEGMENT (visszagörgetQ szegmens) szolgált a ROLLBACK mqvelet, az olvasási konzisztencia, stb. megvalósítására, az újabb verziókban ezt a rendszer teljesen automatikusan csinálja az UNDO szegmens és a UNDOTBS tablespace használatával.
Blokk: az adattárolás egységnyi darabja. Méretét a DB létrehozásakor lehet megadni, hardver és operációs rendszer függQ: 2-4-8 Kbyte. Általában a lemez blokkjainak a mérete vagy annak többszöröse. Adatfájlok írása/olvasása blokkonként, multiblokkonként történik.
Kézikönyvekben megvan a szegmenst alkotó blokkok szerkezetének leírása (pl. a táblák sorainak tárolása hogyan történik a blokkokban). Az blokkok kihasználása állítható paraméterekkel (pl. a blokkban lévQ sorok mezQinek késQbbi változása (méretnövekedése) miatt, meg lehet adni, mennyi szabad helyet hagyjon a rendszer a blokkban, hogy késQbb ne kelljen a teljes sort átmásolni egy új blokkba).
Néhány példa:
-- PTM tablespace létrehozása:
-- 40M-ás ptm_f1.dat fájllal az alapértelmezett meghajtón és könyvtárban,
-- a PTM-be kerülQ objektumok alapértelmezett tárolási paramétereinek megadásával.
CREATE TABLESPACE ptm
DATAFILE 'ptm_f1.dat' SIZE 40M
DEFAULT STORAGE (INITIAL 128K NEXT 128K MINEXTENTS 1 MAXEXTENTS 999);
-- PTM tablespace bQvítése egy újabb fájllal, melynek automatikusan nQ a mérete
ALTER TABLESPACE ptm
ADD DATAFILE 'ptm_f2.dat' SIZE 10M AUTOEXTEND ON NEXT 1M MAXSIZE 100M;
-- Tábla definiálása: ha nem adunk meg egy tárolási elQírást a defaultot veszi.
-- Default tablespace-ben való elhelyezés helyett, adjuk meg azt explicit módon.
-- Default tárolási paraméterek helyett, azok explicit megadása.
-- Default blokk kihasználás helyett, azok explicit megadása:
-- pl. a blokkok 15%-át hagyja szabadon, azaz 85%-osan töltse fel új sorokkal
CREATE TABLE ptm_tabla (oszlop1 NUMBER(10,2), oszlop2 VARCHAR2(100), oszlopn DATE)
TABLESPACE ptm STORAGE (INITIAL 100K NEXT 100K PCTINCREASE 20) PCTFREE 15;
Szükséges háttértár becslését segítQ függvények:
VSISE(sql_kifejezés) -- a kifejezés belsQ reprezentációjának mérete byte-ban
SELECT a_nev, VSIZE(a_nev), VSIZE(belepes), VSIZE(premium)
FROM alkalmazott;
SELECT AVG(VSIZE(a_nev)), AVG(NVL(VSIZE(belepes),0)), AVG(NVL(VSIZE(premium),0))
FROM alkalmazott;
ROWID: pszeudo oszlop minden táblában, a tábla sorának fizikai címe. Mely tartalmazza a fájl azonosítót a blokk sorszámát és a blokkon belüli sorszámot.
SELECT a_nev, ROWID FROM alkalmazott;
Néhány idetartozó DD tábla:
-- felhasználó általános paraméterei
SELECT * FROM USER_USERS;
-- erQforrás korlátozások
SELECT * FROM USER_RESOURCE_LIMITS;
-- tablespace-ek
SELECT * FROM USER_TABLESPACES;
-- tablespace kvóták
SELECT * FROM USER_TS_QUOTAS;
-- szegmensek (pl. tábla, index, stb.)
SELECT * FROM USER_SEGMENTS;
-- konkrét objektumok tárolási jellemzQi pl. táblák, indexek
SELECT * FROM USER_TABLES;
SELECT * FROM USER_INDEXES;
Memória struktúra és processzek (folyamatok):
Az Oracle - mint ahogy bármelyik többfelhasználós DBMS - a feladatait sok-sok programmodul összehangolt mqködésével látja el. Ezek alaposabb ismerete a DBA számára fontos, hogy felügyelni és menedzselni tudja a rendszer biztonságos és hatékony mqködését. Itt csak a legtöbb DBMS rendszerre jellemzQket emeljük ki, részletezés nélkül:
Memória területek típusai:
Programok amelyek futnak, vagy indítani lehet: szoftver kód terület (Software Code Areas).
Egy-egy processz által kizárólagosan használt memóriaterület: PGA (Program Global Area). Ez tartalmazza a processz által használt adatokat és vezérlQ információkat.
Közös/osztott memória terület: SGA (System/Shared Global Area) a különbözQ processzek közösen használják. Egyik célja az idQigényes I/O mqveletek és kiértékelések ismételt végrehajtásának elkerülése. Például: adatbázis-puffer gyorsítótár (Database Buffer Cache): az éppen használt adatblokkok vannak itt addig, amíg nincs szüksége a területre más blokkoknak, vagy nem íródnak lemezre. Egyéb gyorsítótárak: változásnapló-puffer (Redo Log Buffer), adatszótár-puffer gyorsítótár, osztott SQL terület (lefordított, futásra elQkészített SQL utasítások), stb. A munkamenetek (Session) adatai is itt vannak.
Processzeket két nagy struktúra egységbe lehet sorolni:
Felhasználók kéréseit kiszolgáló processzek. Oracle-ben szerver processz (Server Process)
Felhasználóhoz közeli réteg, az adatok adatmodell szerinti kezelésének/lekérdezésének biztosítása.
Háttér processzek (Background Process): hardverhez és a belsQ mqködéshez kapcsolódó réteg. Háttértár fizikai kezelése, tranzakcióvezérlés, zárolások, változásnapló vezetés, háttérmentések végzése, rendszer mqködésének figyelése (monitorozása), stb. Oracle-ben számos nevesített háttér processz végzi ezt a munkát.
Lásd ábra:
A felhasználók a kliens vagy a szerver gépen futó alkalmazásokból, eszközökbQl kapcsolódnak a DB szerverhez, elindítva egy-egy munkamenetet, majd a DB szervernek szóló utasításokat adnak ki. Az alkalmazás és a DB szerver közötti kommunikációs kapcsolatot program interfészek és hálózati kommunikációs szoftverek biztosítják. A kliens és/vagy szerver gépen megfelelQ felhasználói processzek (User Process) mqködnek.
A felhasználók kéréseit a szerver processzek szolgálják ki. Egy-egy osztott szerver processz (Shared Server Process) több felhasználót tud kiszolgálni, ez az alaphelyzet. A dedikált szerver processz (Dedicated Server Process) egyetlen felhasználóhoz van hozzárendelve a DBA által. KövetkezQ feladatokat kell ellátniuk:
Fogadják a felhasználók SQL utasításait. Lefordítják azt, a DD alapján elvégzik a szükséges ellenQrzéseket. Elkészítik az utasítás optimális végrehajtási tervét (elemi végrehajtandó utasítások sorozata, indexhasználat, stb.), ha az még nem lenne meg az SGA osztott SQL területen.
Beolvassák a szükséges adatblokkokat az SGA adatbázis-puffer gyorsítótárba, ha az még nincs ott. A végrehajtáshoz memória területet biztosítanak. Elvégzik a végrehajtást a háttér processzekkel együtt.
Végül vissza küldik az eredményt az alkalmazásoknak.
A szerver processzek a diszpécser processzek (Dispatcher Process) segítségével végzik feladatait. A diszpécserek fogadják és ütemezik a felhasználók kéréseit, majd továbbítják az SGA kérés várakozási sorba (Request Queu). Az a szerver processz, amelyik éppen szabad, végzi el a további munkát, majd az eredményt elhelyezi az SGA válasz várakozási sorba (Response Queu), melyet a diszpécserek továbbítanak a felhasználóknak.
PAGE
Dr. L. Nagy Éva, 2007. SQL_roviden.doc PAGE 1
Operációs rendszer
DBMS (DB Szerver)
Kliens gépek
DB alkalmazások, eszközök
Felhasználók
- egyszerq felhasználók
- fejlesztQk
DBA
Kliens gépek
Hardver
(pl. DB tárolás)
DBMS (DB Szerver)
Eredménytábla
? ? ?
T1 tábla
A B C 1 2 3 4 5 6 7 8 9
T2 tábla
D A 1 2 3 4
Projekció
C A 3 1 6 4 9 7
Szelekció
A B C 1 2 3 7 8 9
CROSS JOIN
A B C D A 1 2 3 1 2 1 2 3 3 4 4 5 6 1 2 4 5 6 3 4 7 8 9 1 2 7 8 9 3 4
Eredménytábla
? ?
INNER JOIN (nem equijoin)
A B C D A 1 2 3 1 2 1 2 3 3 4
EXTENT
(kiterjesztés)
FULL OUTER JOIN (equijoin)
A B C D A 1 2 3 NULL NULL 4 5 6 3 4 7 8 9 NULL NULL NULL NULL NULL 1 2
NATURAL JOIN
A B C D 4 5 6 3
T4 tábla
C D 1 2 3 4
T3 tábla
A B 1 2 1 2 3 4 5 6
UNION
A B 1 2 3 4 5 6
UNION ALL
A B 1 2 1 2 3 4 5 6 1 2 3 4
INTERSECT
A B 1 2 3 4
MINUS
A B 5 6
RIGHT OUTER JOIN (equijoin)
A B C D A NULL NULL NULL 1 2 4 5 6 3 4
INNER JOIN (equijoin)
A B C D A 4 5 6 3 4
Kliens: SQL*Plus, Net, stb Oracle DB Szerver
Kliens: Web böngészQ Alkalmazás Szerver Oracle DB Szerver
(pl. Inernet Explorer) Oracle HTTP Server, iSQL*Plus Server
LEFT OUTER JOIN (equijoin)
A B C D A 1 2 3 NULL NULL 4 5 6 3 4 7 8 9 NULL NULL
SEGMENT
(szegmens)
TABLESPACE
(táblaterület)
DATABASE
(adatbázis)
ALKALMAZOTT
TELEPHELY
BLOCK
(blokk)
FILE (fájl)
Hasonló témájú dokumentumok

- 2007-12-03 17:31:05
A mások által feltöltött dokumentumokat értékelheted. Ha úgy ítéled meg, hogy a vizsgára való felkészülés szempontjából hasznos volt egy dokumentum, akkor adj rá sokcsillagos értékelést.
Ha hibákat tartalmaz, vagy egyéb probléma van vele, akkor keveset.
A dokumentumok sorrendje az értékelések alapján adódik. Ami fentebb van a listában, azt hasznosabbnak ítélték társaid. Az új dokumentumok pedig (értékelések hiányában) szintén a lista tetején kezdenek.
Hozzászólások
Ha észrevételed van egy dokumentummal kapcsolatban (például hibát találtál benne), akkor a Hozzászólások részben jelezheted. Az olyan jellegű kérdéseket mint pl.: A 2. feladat 4. sorából milyen átalakítással jutottunk az 5. sorban szereplő képlethez? - szintén ide érdemes írni
Egy tipp az oldalhoz! - Online ZH, vizsga kidolgozás! Mi is ez? Ha feltöltesz egy régi ZH-t/vizsgát, a dokumentum oldalán Hozzászólást lehet írni. Megírhatod például, hogy "szerintem a 3-as feladat megoldása ez: "... Ha hiba van benne, más hallgató egy új hozzászólásban ezt jelezheti.