Ôåäåðàëüíîå àãåíòñòâî ïî îáðàçîâàíèþ Ðîññèéñêîé Ôåäåðàöèè Ãîñóäàðñòâåííîå îáðàçîâàòåëüíîå ó÷ðåæäåíèå âûñøåãî ïðîôåññèîíàëüíîãî îáðàçîâàíèÿ Óëüÿíîâñêèé ãîñóäàðñòâåííûé òåõíè÷åñêèé óíèâåðñèòåò
À. Ì. Íàìåñòíèêîâ
ÏÎÑÒÐÎÅÍÈÅ ÁÀÇ ÄÀÍÍÛÕ Â ÑÐÅÄÅ ORACLE Ïðàêòè÷åñêèé êóðñ
Ó÷åáíîå ïîñîáèå ïî êóðñó ¾Áàçû äàííûõ¿
Óëüÿíîâñê 2008
ÓÄÊ 519.852 + 517.977.5 (075) ÁÁÊ 73ÿ7 Í30 Ðåöåíçåíòû:
Óòâåðæäåíî ðåäàêöèîííî-èçäàòåëüñêèì ñîâåòîì óíèâåðñèòåòà â êà÷åñòâå ó÷åáíîãî ïîñîáèÿ äëÿ âóçîâ
Íàìåñòíèêîâ À.Ì.
Í30
Ïîñòðîåíèå áàç äàííûõ â ñðåäå Oracle. Ïðàêòè÷åñêèé êóðñ: Ó÷åá. ïîñîáèå äëÿ âóçîâ. Óëüÿíîâñê: ÓëÃÒÓ, 2008. 118c. ISBN 5-89146-000-0 Ñîäåðæèò îñíîâíûå ñâåäåíèÿ, íåîáõîäèìûå äëÿ ïîñòðîåíèÿ áàç äàííûõ â ñðåäå Oracle 10g ñ ïðàêòè÷åñêèìè ïðèìåðàìè. Äëÿ ñòóäåíòîâ âóçîâ, îáó÷àþùèõñÿ ïî ñïåöèàëüíîñòÿì ¾Ïðèêëàäíàÿ èíôîðìàòèêà(â ýêîíîìèêå)¿ è äðóãèì, ïðèìåíÿþùèì ÝÂÌ â çàäà÷àõ ïîñòðîåíèÿ áàç äàííûõ.
ÓÄÊ 519.852 + 517.977.5 (075) ÁÁÊ 73ÿ7
c Îôîðìëåíèå. ÓëÃÒÓ, 2008
c À.Ì. Íàìåñòíèêîâ, 2008
Íàâåðíîå íåò áîëåå ðàñïðîñòðàíåííîãî ïðèëîæåíèÿ â ìèðå èíôîðìàöèîííûõ ñèñòåì, ÷åì áàçû äàííûõ. Îíè ïðèìåíÿþòñÿ êàê â ñîñòàâå ñëîæíûõ èíòåãðèðîâàííûõ èíôîðìàöèîííûõ ñèñòåì, òàê è â âèäå ïðîñòûõ îäíîïîëüçîâàòåëüñêèõ ïðèëîæåíèé. Èíñòðóìåíòàëüíûõ ñðåä äëÿ ðåàëèçàöèè ñîâðåìåííûõ áàç äàííûõ èçâåñòíî áîëüøîå êîëè÷åñòâî è îäíîé èç íèõ ÿâëÿåòñÿ Oracle 10g.  äàííîì ó÷åáíîì ïîñîáèè ñîäåðæèòñÿ ìàòåðèàë, èñïîëüçóÿ êîòîðûé ìîæíî ïðèñòóïèòü ê ðåàëèçàöèè ñîáñòâåííîé áàçû äàííûõ â ñðåäå Oracle 10g Express Edition, êîòîðàÿ ÿâëÿåòñÿ ñâîáîäíî ðàñïðîñòðàíÿåìûì ïðîãðàììíûì ïàêåòîì. Êîíå÷íî, ìàòåðèàë, ñîäåðæàùèéñÿ â ó÷åáíîì ïîñîáèè, íå ðàñêðûâàåò âñå òîíêîñòè ïðàêòè÷åñêîé ðàáîòû ñ Oracle 10g.  ÷àñòíîñòè, íå ðàññìîòðåíû âîïðîñû àäìèíèñòðèðîâàíèÿ, áåçîïàñíîñòè è ïðèìåíåíèÿ ñòàíäàðòîâ äîñòóïà ê áàçàì äàííûõ. Äëÿ ïîëó÷åíèå äîïîëíèòåëüíîé èíôîðìàöèè ñëåäóåò îáðàùàòüñÿ ê ëèòåðàòóðå èç ïðåäëîæåííîãî ñïèñêà.
Óëüÿíîâñê, ßíâàðü 2008
À.Ì. Íàìåñòíèêîâ
3
4
Îãëàâëåíèå 1
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà
2
Ââåäåíèå â ÿçûê SQL
2.1
2.2
2.3
9 15
Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL . . . . . . . . . . . 2.1.1 Îïåðàòîð CREATE TABLE . . . . . . . . . . . . . . . 2.1.2 Îïðåäåëåíèå ïåðâè÷íûõ è àëüòåðíàòèâíûõ êëþ÷åé ñ ïîìîùüþ îïåðàòîðà ALTER . . . . . . . . . . . . . . . 2.1.3 Îïåðàòîðû DROP . . . . . . . . . . . . . . . . . . . . Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL . . . . . . . . . . . . . 2.2.1 ×òåíèå çàäàííûõ ñòîëáöîâ èç îäèíî÷íîé òàáëèöû . . 2.2.2 ×òåíèå çàäàííûõ ñòðîê èç îäèíî÷íîé òàáëèöû . . . . 2.2.3 ×òåíèå çàäàííûõ ñòðîê è ñòîëáöîâ èç îäèíî÷íîé òàáëèöû . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.4 Äèàïàçîíû, ñïåöèàëüíûå ñèìâîëû è ïóñòûå çíà÷åíèÿ â ïðåäëîæåíèÿõ WHERE . . . . . . . . . . . . . . . . 2.2.5 Âñòðîåííûå ôóíêöèè SQL . . . . . . . . . . . . . . . . 2.2.6 Âñòðîåííûå ôóíêöèè è ãðóïïèðîâêà . . . . . . . . . . 2.2.7 ×òåíèå äàííûõ èç íåñêîëüêèõ òàáëèö ñ ïðèìåíåíèåì âëîæåííûõ çàïðîñîâ . . . . . . . . . . . . . . . . . . . 2.2.8 ×òåíèå äàííûõ èç íåñêîëüêèõ òàáëèö ñ ïîìîùüþ îïåðàöèè ñîåäèíåíèÿ . . . . . . . . . . . . . . . . . . . . . 2.2.9 Âíåøíèå ñîåäèíåíèÿ . . . . . . . . . . . . . . . . . . . Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL . . . . . . . . . . 2.3.1 Âñòàâêà äàííûõ . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Èçìåíåíèå äàííûõ . . . . . . . . . . . . . . . . . . . . 2.3.3 Óäàëåíèå äàííûõ . . . . . . . . . . . . . . . . . . . . . 5
16 16 17 20 20 21 23 24 25 29 31 33 34 39 40 40 42 43
ÎÃËÀÂËÅÍÈÅ
3
Óñòàíîâêà Oracle
3.1 3.2 3.3 3.4
3.5
3.6 3.7 3.8 3.9 4
ÎÃËÀÂËÅÍÈÅ
45
Óñòàíîâêà Oracle 10g XE äëÿ Windows . . . . . . . Óñòàíîâêà Oracle 10g XE äëÿ Linux . . . . . . . . . Web-èíòåðôåéñ . . . . . . . . . . . . . . . . . . . . Ðàáîòà ñ SQL*Plus . . . . . . . . . . . . . . . . . . 3.4.1 Áóôåð ñ SQL*Plus . . . . . . . . . . . . . . 3.4.2 Èñïîëüçîâàíèå âíåøíåãî ðåäàêòîðà . . . . Ñîçäàíèå òàáëèö . . . . . . . . . . . . . . . . . . . 3.5.1 Ñîçäàíèå ñóððîãàòíûõ êëþ÷åé ñ ïîìîùüþ âàòåëüíîñòåé . . . . . . . . . . . . . . . . . 3.5.2 Ââîä äàííûõ . . . . . . . . . . . . . . . . . 3.5.3 Îïåðàòîðû DROP è ALTER . . . . . . . . . 3.5.4 Ââîä äàííûõ òèïà DATE . . . . . . . . . . Ñîçäàíèå èíäåêñîâ . . . . . . . . . . . . . . . . . . Èçìåíåíèå ñòðóêòóðû òàáëèöû . . . . . . . . . . . Ó÷åòíûå çàïèñè è ðîëè . . . . . . . . . . . . . . . Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ïîñëåäî. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46 48 48 52 53 56 57 60 62 64 64 65 66 67 68
Ïðèìåíåíèå SQL
73
4.1
73
4.2 4.3
4.4 4.5
SQL ïðåäñòàâëåíèÿ . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ ñêðûòèÿ ñòîëáöîâ è ñòðîê . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.2 Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ îòîáðàæåíèÿ âû÷èñëÿåìûõ ñòîëáöîâ . . . . . . . . . . . . . . . . . . . 4.1.3 Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ ñêðûòèÿ ñëîæíîãî ñèíòàêñèñà . . . . . . . . . . . . . . . . . . . . . . . . . SQL-îïåðàòîðû â ïðèêëàäíûõ ïðîãðàììàõ . . . . . . . . . . Òðèããåðû . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 Èñïîëüçîâàíèå òðèããåðîâ äëÿ ïðîâåðêè äîïóñòèìîñòè ââîäèìûõ äàííûõ . . . . . . . . . . . . . . . . . . 4.3.2 Èñïîëüçîâàíèå òðèããåðîâ äëÿ ïðèñâîåíèÿ çíà÷åíèé ïî óìîë÷àíèþ . . . . . . . . . . . . . . . . . . . . . . . 4.3.3 Òðèããåð, îáíîâëÿþùèé ïðåäñòàâëåíèå . . . . . . . . . 4.3.4 Òðèããåð, îáåñïå÷èâàþùèé ññûëî÷íóþ öåëîñòíîñòü . . Õðàíèìûå ïðîöåäóðû . . . . . . . . . . . . . . . . . . . . . . Ñëîâàðü äàííûõ . . . . . . . . . . . . . . . . . . . . . . . . . 6
74 76 77 80 82 83 84 86 87 90 94
ÎÃËÀÂËÅÍÈÅ
5
ÎÃËÀÂËÅÍÈÅ
Äîïîëíèòåëüíûå âîçìîæíîñòè
5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8
Ñèñòåìíàÿ òàáëèöà DUAL . . . . . . Ïñåâäîñòîëáåö ROWID . . . . . . . Ïñåâäîñòîëáåö ROWNUM . . . . . . Ôóíêöèÿ NVL . . . . . . . . . . . . . ×èñëîâûå ôóíêöèè . . . . . . . . . . Òðèãîíîìåòðè÷åñêèå ôóíêöèè . . . Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè . Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
7
97
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
97 97 99 99 100 104 104 111
ÎÃËÀÂËÅÍÈÅ
ÎÃËÀÂËÅÍÈÅ
8
Ãëàâà 1 Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà Ïåðåä íåïîñðåäñòâåííûì ðàññìîòðåíèåì ÿçûêà SQL è ñèñòåìû óïðàâëåíèÿ áàçàìè äàííûõ Oracle 10g íåîáõîäèìî îïðåäåëèòüñÿ ñ òåìè èñõîäíûìè äàííûìè, êîòîðûå áóäåì ïðèìåíÿòü â ïðèìåðàõ ó÷åáíîãî ïîñîáèÿ.  êà÷åñòâå ïðèìåðà ðàññìàòðèâàåòñÿ áàçà äàííûõ íåáîëüøîé õóäîæåñòâåííîé ãàëåðåè [1]. Ïåðå÷åíü òðåáîâàíèé ê ïðèëîæåíèþ äëÿ ãàëåðåè:
• Âåñòè ó÷åò ïîêóïàòåëåé è èõ õóäîæåñòâåííûõ èíòåðåñîâ. • Îòñëåæèâàòü ïðèîáðåòåíèÿ, êîòîðûå äåëàåò ãàëåðåÿ. • Îòñëåæèâàòü ïîêóïêè êëèåíòîâ. • Âåñòè ñïèñîê õóäîæíèêîâ è ïðîèçâåäåíèé, êîãäà-ëèáî ïîÿâëÿâøèõñÿ â ãàëåðåå. • Ãåíåðèðîâàòü îò÷åò î òîì, íàñêîëüêî áûñòðî è ñ êàêîé ïðèáûëüþ ïðîäàþòñÿ ïðîèçâåäåíèÿ êîíêðåòíîãî õóäîæíèêà. • Îòîáðàæàòü íà âåá-ñòðàíèöå ñïèñîê ïðîèçâåäåíèé, âûñòàâëåííûõ íà ïðîäàæó. Êîãäà ãàëåðåÿ ïîêóïàåò ïðîèçâåäåíèå, ñâåäåíèÿ î íåì, åãî àâòîðå, äàòå è ñòîèìîñòè ïðèîáðåòåíèÿ çàïèñûâàþòñÿ â áàçó äàííûõ.  îòäåëüíûõ ñëó÷àÿõ ãàëåðåÿ ìîæåò âûêóïèòü ïðîèçâåäåíèå ó êëèåíòà è âíîâü âûñòàâèòü åãî íà ïðîäàæó, òàê ÷òî îäíî è òî æå ïðîèçâåäåíèå ìîæåò ïîÿâëÿòüñÿ â ãàëåðåå íåîäíîêðàòíî. Ïðè ïîâòîðíîì ïðèîáðåòåíèè èíôîðìàöèÿ î ðàáîòå è åå àâòîðå íå ââîäèòñÿ çàíîâî: çàïèñûâàåòñÿ òîëüêî äàòà è ñòîèìîñòü ïîñëåäíåãî ïðèîáðåòåíèÿ. Êîãäà ðàáîòà ïðîäàåòñÿ, çàïèñûâàþòñÿ äàòà ñîâåðøåíèÿ ñäåëêè, óïëà÷åííàÿ ñóììà è ñâåäåíèÿ î ïîêóïàòåëå. 9
Ãëàâà 1.
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà
Äàííûå î ïðåäûäóùèõ ïðîäàæàõ íåîáõîäèìû ïðîäàâöàì äëÿ òîãî, ÷òîáû îíè ìîãëè óäåëÿòü áîëüøå âðåìåíè íàèáîëåå àêòèâíûì ïîêóïàòåëÿì. Èíîãäà ýòè çàïèñè èñïîëüçóþòñÿ äëÿ îïðåäåëåíèÿ ìåñòîíàõîæäåíèÿ ðàíåå ïðîäàííûõ ïðîèçâåäåíèé. Äëÿ ìàðêåòèíãîâûõ öåëåé òðåáóåòñÿ, ÷òîáû ïðèëîæåíèå áàçû äàííûõ âûäàâàëî ñïèñîê âñåõ ïðîèçâåäåíèé, êîòîðûå êîãäà-ëèáî ïîÿâëÿëèñü â ãàëåðåå, è èõ àâòîðîâ. Âëàäåëåö õîòåë áû òàêæå èìåòü âîçìîæíîñòü îïðåäåëÿòü, íàñêîëüêî áûñòðî ïðîäàþòñÿ ïðîèçâåäåíèÿ êàæäîãî èç õóäîæíèêîâ è êàêîâà ïðèáûëü îò èõ ïðîäàæè. Íàêîíåö, ïðèëîæåíèå äîëæíî îòîáðàæàòü ñïèñîê ðàáîò, èìåþùèõñÿ â íàëè÷èè.
Ðèñ. 1.1. Ìîäåëü äàííûõ äëÿ ïðàêòè÷åñêîãî ïðèìåðà Ìîäåëü äàííûõ òàêîãî ïðèìåðà ïðèâåäåíà íà ðèñ. 1.1.  íåé åñòü äâå ñèëüíûõ ñóùíîñòåé CUSTOMER (êëèåíò) è ARTIST (õóäîæíèê). Êðîìå òîãî, èìååòñÿ cóùíîñòü WORK (ïðîèçâåäåíèå), èäåíòèôèêàöèîííîçàâèñèìàÿ îò ñóùíîñòè ARTIST, è ñóùíîñòü TRANSACTION (òðàíçàêöèÿ), èäåíòèôèêàöèîííî-çàâèñèìàÿ îò ñóùíîñòè WORK. Ìåæäó ñóùíî10
Ãëàâà 1.
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà
ñòÿìè CUSTOMER è WORK èìååòñÿ íåèäåíòèôèöèðóþùàÿ ñâÿçü ïðèíàäëåæíîñòè. Ñâåäåíèÿ î õóäîæíèêå ìîãóò ïðèñóòñòâîâàòü â áàçå äàííûõ, äàæå åñëè íè îäíà èç åãî ðàáîò íå ïîÿâëÿëàñü â ãàëåðåå. Ýòî ñäåëàíî äëÿ òîãî, ÷òîáû ìîæíî áûëî ðåãèñòðèðîâàòü èíòåðåñ êëèåíòîâ ê õóäîæíèêàì, ÷üè ðàáîòû ãàëåðåÿ ìîæåò ïðèîáðåñòè â áóäóùåì. Òàêèì îáðàçîì, ñ õóäîæíèêîì ìîæåò áûòü ñâÿçàíî ëþáîå êîëè÷åñòâî ïðîèçâåäåíèé, â òîì ÷èñëå íîëü. Èäåíòèôèêàòîðîì ñóùíîñòè WORK ÿâëÿåòñÿ ãðóïïà (Title, Copy) (íàçâàíèå, íîìåð êîïèè), ïîñêîëüêó â ñëó÷àå ëèòîãðàôèé è ôîòîãðàôèé ïðîèçâåäåíèå ìîæåò ñóùåñòâîâàòü â íåñêîëüêèõ ýêçåìïëÿðàõ. Êðîìå òîãî, â òðåáîâàíèÿõ ê ïðèëîæåíèþ óêàçàíî, ÷òî îäíî è òîæå ïðîèçâåäåíèå ìîæåò íåîäíîêðàòíî ïîÿâëÿòüñÿ â ãàëåðåå, ïîýòîìó ñ êàæäûì ïðîèçâåäåíèåì ïîòåíöèàëüíî ìîæåò áûòü ñâÿçàíî ìíîãî òðàíçàêöèé. Êàæäûé ðàç, êîãäà ïðîèçâåäåíèå ïîÿâëÿåòñÿ â ãàëåðåå, íåîáõîäèìî çàïèñûâàòü äàòó è ñòîèìîñòü ïðèîáðåòåíèÿ. Òàêèì îáðàçîì, êàæäîé ðàáîòå äîëæíà ñîîòâåòñòâîâàòü ïî ìåíüøåé ìåðå îäíà òðàíçàêöèÿ. Êëèåíò ìîæåò ïðèîáðåñòè ìíîæåñòâî ðàáîò; ýòîò ôàêò îáîçíà÷åí ñâÿçüþ âèäà 1:N ìåæäó ñóùíîñòÿìè CUSTOMER è TRANSACTION. Êðîìå òîãî, ìåæäó ñóùíîñòÿìè CUSTOMER è ARTIST ñóùåñòâóåò ñâÿçü âèäà N:M. Óäàëåíèå ñòðîê â òàáëèöàõ CUSTOMER è ARTIST âûçûâàåò êàñêàäíîå óäàëåíèå â òàáëèöå CUSTOMER_ARTIST_INT. Ýòî èìååò ñìûñë, ïîñêîëüêó êîãäà ñâåäåíèÿ î êëèåíòå èëè õóäîæíèêå óäàëÿþòñÿ èç áàçû äàííûõ, íåò íóæäû ñîõðàíÿòü èíôîðìàöèþ î ïðåäïî÷òåíèÿõ äàííîãî êëèåíòà èëè èíòåðåñå ê äàííîìó õóäîæíèêó. Åñëè ñ êëèåíòîì ñâÿçàíà õîòÿ áû îäíà òðàíçàêöèÿ, ýòîò êëèåíò íå ìîæåò áûòü óäàëåí èç áàçû äàííûõ. Àíàëîãè÷íî, åñëè ñ õóäîæíèêîì ñâÿçàíà õîòÿ áû îäíà êàðòèíà, óäàëèòü åãî áóäåò íåëüçÿ. Êðîìå òîãî, çàïèñè î ðàáîòàõ, ïî êîòîðûì èìåëè ìåñòî êàêèå-ëèáî òðàíçàêöèè, óäàëåíèþ òàêæå íå ïîäëåæàò. Äàííûå äëÿ ðàññìàòðèâàåìîãî ïðèìåðà ïðèâåäåíû â òàáë. 1.1 -1.5.
11
ArtistID
3 4 5 6 8 14 15 16
Name
Nationality
Miro Kandinsky Frings Klee Moos Tobey Matisse Chagall
Spanish Russian US German US US French French
BirthDate
DeceasedDate
1870 1854 1700 1900
1950 1900 1800
Òàáëèöà 1.2. Äàííûå äëÿ òàáëèöû WORK WorkID
505 506 507 525 530
Title
Mystic Fabric Mi Vida Slow Embers Mystic Fabric Northwest by Night
Description
Copy
One of the only pr Very black, but ve From the artist's Some water damage Wonderful, moody
99/135 7/100 HC 105/135 37/50
ArtistID
14 3 14 14 16
12
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà Ãëàâà 1.
Òàáëèöà 1.1. Äàííûå äëÿ òàáëèöû ARTIST
Òàáëèöà 1.3. Äàííûå äëÿ òàáëèöû TRANSACTION TransactionID DateAcquired AcquisitionPrice PurchaseDate SalesPrice
100 101 121 122 124 129 130 135
2/27/1974 7/17/1989 11/17/1989 2/27/1999 4/7/2001 11/21/2001 11/21/2001 7/17/2002
8750 28900 4500 8000 38700 6750 21500 47000
3/18/1974 10/14/1989 11/21/2000 3/15/2000 8/17/2000 3/18/2002 10/2/2002
18500 46700 9750 17500 73500 14500 71500
AskingPrice CustomerID WorkID
20000 47000 10000 17500 75000 15000 72500
1015 1001 1040 1036 1036 1040 1015
505 505 525 506 506 507 525 530
Ãëàâà 1.
Òàáëèöà 1.4. Äàííûå äëÿ òàáëèöû CUSTOMER Name
Street
City
State Zip-
tomerID
1000 1001 1015 1033 13
1034 1036 1037 1040 1041 1051
Country Area-
Postal-
Jerey Janes David Smith
123 W. Elm St 813 Tumbleweed Lane Tiany 88-First Twilight Avenue Fred 10899-88th Smathers Ave Mary 25 South Beth Lafayette Frederickson Selma 205 Warning Burnaby Susan Wu 105 Locust Ave Donald 55 Bodega G. Gray Ave Lynda 117 C Johnson Street Chris 87 Wikens Highland Drive
Code
Phone-
Code
Number
Email
Renton
WA
98123
USA
206
555-1345 [email protected]
Loveland
CO
80345
USA
303
555-5434 [email protected]
Langley
WA
98114
USA
206
555-1000 [email protected]
Bainbridge WA Island Denver CO
98108
USA
206
555-1234 [email protected]
80210
USA
303
555-1000 [email protected]
Vancouver BC
VON 1B4 23224
Canada 253
555-1234 [email protected]
USA
721
555-1234 [email protected]
Bodega CA Bay Washington DC
92114
USA
705
555-1234 [email protected]
11345
USA
703
555-1000
Olimpia
98008
USA
206
555-1234
Atlanta
GA
WA
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà
Cus-
Îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà
Òàáëèöà 1.5. Äàííûå äëÿ òàáëèöû CUSTOMER_ARTIST_INT 3 5 5 5 5 8 8 14
CustomerID
1036 1015 1034 1041 1051 1034 1041 1001
ArtistID
14 14 14 14 14 14 14 16
CustomerID
1015 1033 1034 1036 1040 1041 1051 1015
14
Ãëàâà 1.
ArtistID
Ãëàâà 2 Ââåäåíèå â ÿçûê SQL ßçûê SQL áûë ðàçðàáîòàí ôèðìîé IBM â êîíöå 1970-õ ãîäîâ è áûë ïðèíÿò Àìåðèêàíñêèì íàöèîíàëüíûì èíñòèòóòîì ñòàíäàðòîâ (ANSI) â êà÷åñòâå íàöèîíàëüíîãî ñòàíäàðòà ÑØÀ â 1992 ãîäó [1]. ßçûê SQL îðèåíòèðîâàí íà òåêñò. Îí áûë ðàçðàáîòàí çàäîëãî äî ïîÿâëåíèÿ ãðàôè÷åñêèõ èíòåðôåéñîâ ïîëüçîâàòåëÿ, òàê ÷òî äëÿ ðàáîòû ñ íèì òðåáóåòñÿ ëèøü òåêñòîâûé ðåäàêòîð. Ðàçóìååòñÿ, â òàêèõ ÑÓÁÄ êàê Oracle èìåþòñÿ ãðàôè÷åñêèå ñðåäñòâà äëÿ âûïîëíåíèÿ ìíîãèõ èç òåõ çàäà÷, êîòîðûå ðàíåå ìîãëè áûòü âûïîëíåíû òîëüêî ñ ïîìîùüþ SQL. Íî íå âñå èç òîãî, ÷òî ïîçâîëÿåò äåëàòü SQL, ìîæíî îñóùåñòâèòü ñ ïîìîùüþ ãðàôè÷åñêèõ ñðåäñòâ; áîëåå òîãî, â ðÿäå ñëó÷àåâ, íàïðèìåð äëÿ äèíàìè÷åñêîé ãåíåðàöèè îïåðàòîðîâ SQL â ïðîãðàììíîì êîäå, SQL èñïîëüçîâàòü íåîáõîäèìî. Ñ ïîìîùüþ SQL ìîæíî îïðåäåëÿòü ñòðóêòóðû áàçû äàííûõ, à òàêæå çàïðàøèâàòü è îáíîâëÿòü èíôîðìàöèþ â áàçå äàííûõ. Ñîâîêóïíîñòü êîìàíä, ñëóæàùèõ äëÿ îïðåäåëåíèÿ äàííûõ, íàçûâàþò èíîãäà ÿçûêîì îïðåäåëåíèÿ äàííûõ (data denition language, DDL), à ñîâîêóïíîñòü êîìàíä äëÿ îáíîâëåíèÿ è çàïðîñà äàííûõ ÿçûêîì ìàíèïóëèðîâàíèÿ äàííûìè (data manipulation language, DML). Äàëåå â ó÷åáíîì ïîñîáèè áóäóò ðàññìîòðåíû îáà ýòè ïîäìíîæåñòâà ÿçûêà SQL íà ïðèìåðå, ïðèâåäåííîì â ïðåäûäóùåé ãëàâå. 15
2.1. Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL
2.1 2.1.1
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL Îïåðàòîð CREATE TABLE
Îñíîâíàÿ ôóíêöèÿ ýòîãî îïåðàòîðà ñîçäàíèå íîâîé òàáëèöû è îïèñàíèå åå ñòîëáöîâ è òèïîâ äàííûõ. Êðîìå òîãî, ýòîò îïåðàòîð ïîçâîëÿåò îïðåäåëÿòü ïåðâè÷íûå êëþ÷è, àëüòåðíàòèâíûå êëþ÷è è âíåøíèå êëþ÷è ñ íåêîòîðûìè îãðàíè÷åíèÿìè ññûëî÷íîé öåëîñòíîñòè, à òàêæå çàäàâàòü îãðàíè÷åíèÿ íà ñòîëáöû è òàáëèöû. Ëèñòèíã 2.1.
CREATE TABLE CUSTOMER( CustomerID int Name char(25) Street char(30) City char(35) State char(2) ZipPostalCode char(5) Country varchar(50) AreaCode char(3) PhoneNumber char(8) Email varchar(100)
PRIMARY KEY, NOT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 SQL èìååòñÿ ïÿòü òèïîâ îãðàíè÷åíèé: PRIMARY KEY, NULL/NOT NULL, UNIQUE, FOREIGN KEY è CHECK.  ëèñòèíãå 2.1 ñòîëáåö CustomerID ïðèíàäëåæèò ê òèïó äàííûõ Integer (öåëî÷èñëåííûé) è èìååò ñâîéñòâî Primary Key. Ñëåäóþùèé ñòîëáåö, Name, èìååò òèï äàííûõ Character (ñòðîêîâûé) ñ ìàêñèìàëüíîé äëèíîé 25 ñèìâîëîâ. Êëþ÷åâûå ñëîâà Not Null îçíà÷àþò, ÷òî ýòîò ñòîëáåö îáÿçàí èìåòü çíà÷åíèå.  SQL ïåðâè÷íûå êëþ÷è íè ïðè êàêèõ óñëîâèÿõ íå ìîãóò èìåòü ïóñòûõ çíà÷åíèé. Èìåííî ïîýòîìó äëÿ ñòîëáöà CustomerID ìîæíî ïðîñòî óêàçàòü ñâîéñòâî Primary Key, íå óòî÷íÿÿ, ÷òî îí íå äîëæåí áûòü ïóñòûì (Not Null). Êëþ÷åâûå ñëîâà Primary Key ñàìè ïî ñåáå óæå ãîâîðÿò, ÷òî ñòîëáåö CustomerID íå áóäåò èìåòü ïóñòûõ çàí÷åíèé. Äëÿ óíèêàëüíûõ ñòîëáöîâ, îäíàêî, ïóñòûå çíà÷åíèÿ âîçìîæíû. Ñåäüìîé ñòîëáåö, Country, ïðèíàäëåæèò ê òèïó äàííûõ VarChar(50) è èìååò ñâîéñòâî Null. VarChar îáîçíà÷àåò ñòðîêó ïåðåìåííîé äëèíû. Òàêèì 16
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.1. Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL
îáðàçîì, â ðàçíûõ ñòðîêàõ çíà÷åíèÿ ñòîëáöà Country ìîãóò ðàçëè÷àòüñÿ ïî äëèíå, è ìàêñèìàëüíî âîçìîæíàÿ äëèíà ñòðîêè ðàâíà 50 ñèìâîëàì. Êëþ÷åâîå ñëîâî Null óêàçûâàåò íà òî, ÷òî ïóñòûå çíà÷åíèÿ äîïóñòèìû. Çíà÷åíèÿ òèïà Char èìåþò ôèêñèðîâàííóþ äëèíó. Åñëè ñòîëáåö Name îïðåäåëåí êàê Char(25), ýòî îçíà÷àåò, ÷òî êàæäîå çíà÷åíèå ñòîëáöà Name áóäåò õðàíèòüñÿ â âèäå ñòðîêè äëèíîé 25 ñèìâîëîâ, íåçàâèñèìî îò òîãî, êàêîâà ðåàëüíàÿ äëèíà èìåíè êëèåíòà. Ïðè íåîáõîäèìîñòè èìåíà áóäóò äîïîëíÿòüñÿ ïðîáåëàìè äî 25 ñèìâîëîâ. Çíà÷åíèÿ òèïà VarChar ìîãóò èìåòü ðàçíóþ äëèíó. Åñëè íàçâàíèå ñòðàíû ñîñòîèò âñåãî èç ÷åòûðåõ ñèìâîëîâ, òî òîëüêî ýòè ÷åòûðå ñèìâîëà è áóäóò õðàíèòüñÿ â ñòîëáöå Country.  òàáë. 2.1 ïåðå÷èñëåíû íåêîòîðûå èç òèïîâ äàííûõ, ïîääåðæèâàåìûõ â ÑÓÁÄ Oracle Òàáëèöà 2.1. Òèïû äàííûõ SQL â ÑÓÁÄ Oracle Òèï äàííûõ
BLOB CHAR(n)
DATE INT NUMBER(n,d) VARCHAR(n) èëè VARCHAR2(n)
2.1.2
Îïèñàíèå
Áîëüøîé äâîè÷íûé îáúåêò. Ìîæåò áûòü äëèíîé äî 4 Ãáàéò Òåêñòîâîå ïîëå ôèêñèðîâàííîé äëèíû n. Ìàêñèìóì 2000 ñèìâîëîâ Ïîëå äëèíîé 7 áàéò, ñîäåðæàùåå äàòó è âðåìÿ Öåëîå ÷èñëî äëèíîé 38 çíàêîâ ×èñëî äëèíîé n ñ d çíàêàìè ïîñëå çàïÿòîé Òåêñòîâîå ïîëå ïåðåìåííîé äëèíû äî n ñèìâîëîâ. Ìàêñèìàëüíîå çíà÷åíèå n=4000
Îïðåäåëåíèå ïåðâè÷íûõ è àëüòåðíàòèâíûõ êëþ÷åé ñ ïîìîùüþ îïåðàòîðà ALTER
Ïîñëå òîãî êàê òàáëèöà îïðåäåëåíà, åå ñòðóêòóðó, ñâîéñòâà è îãðàíè÷åíèÿ ìîæíî èçìåíèòü, èñïîëüçóÿ îïåðàòîð ALTER. Òàê, â ëèñòèíãå 2.2 ïðåäñòàâëåí àëüòåðíàòèâíûé ñïîñîá îïðåäåëåíèÿ ïåðâè÷íîãî êëþ÷à, ïðè êîòîðîì ñíà÷àëà îïðåäåëÿåòñÿ òàáëèöà, à ïîòîì åå îïðåäåëåíèå ìîäèôèöèðóåòñÿ îïåðàòîðîì ALTER. Îïåðàòîð CREATE TABLE îïðåäåëÿåò âñå ñòîëáöû òàáëèöû CUSTOMER, íî íè îäèí èç íèõ íå óêàçûâàåòñÿ â êà÷åñòâå ïåðâè÷íîãî êëþ÷à. Çàòåì ïðè ïîìîùè îïåðàòîðà ALTER TABLE ââîäèòñÿ íîâîå îãðàíè÷åíèå ïîä íàçâàíèåì CustomerPK, êîòîðîå îïðåäåëÿåò ñòîëáåö CustomerID êàê ïåðâè÷íûé êëþ÷. 17
2.1. Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ëèñòèíã 2.2.
CREATE TABLE CUSTOMER( CustomerID int Name char(25) Street char(30) City char(35) State char(2) ZipPostalCode char(5) Country varchar(50) AreaCode char(3) PhoneNumber char(8) Email varchar(100)
NOT NULL, NOT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
ALTER TABLE CUSTOMER ADD CONSTRAINT CustomerPK PRIMARY KEY (CustomerID); CREATE TABLE ARTIST( ArtistID int Name char(25) Nationality varchar(30) BirthDate numeric(4,0) DeceasedDate numeric(4,0) CONSTRAINT ArtistPK PRIMARY
NOT NULL, NOT NULL, NULL, NULL, NULL, KEY (ArtistID));
Èìÿ äëÿ îãðàíè÷åíèÿ ìîæåò âûáèðàòüñÿ ïðîèçâîëüíî. Îäíàêî åñòü ñìûñë ïðèäåðæèâàòüñÿ íåêîòîðûì ñòàíäàðòíûì ñîãëàøåíèÿì îá èìåíîâàíèè.  ýòîì ïîñîáèè, íàïðèìåð, èìåíà ïåðâè÷íûõ êëþ÷åé îáðàçóþòñÿ ïóòåì ïðèñîåäèíåíèÿ àááðåâèàòóðû PK (Primary Key - ïåðâè÷íûé êëþ÷) ê íàçâàíèþ òàáëèöû. Îáà ñïîñîáà îïðåäåëåíèÿ ïåðâè÷íûõ êëþ÷åé äëÿ òàáëèö CUSTOMER (ëèñòèíã 2.1 è ëèñòèíã 2.2) ÿâëÿþòñÿ ïðàâèëüíûìè. Ðàçëè÷èå ñîñòîèò â òîì, ÷òî âî âòîðîì ëèñòèíãå ðàçðàáîò÷èê óêàçàë ÿâíî èìÿ îðãàíè÷åíèÿ ïåðâè÷íîãî êëþ÷à. Îãðàíè÷åíèþ ïåðâè÷íîãî êëþ÷à òàáëèöû CUSTOMER (ëèñòèíã 2.1) òàêæå áóäåò äàíî èìÿ, íî âûáåðåò åãî óæå ÑÓÁÄ, ÷òî î÷åíü ÷àñòî çàòðóäíÿåò çàäà÷è àäìèíèñòðèðîâàíèÿ äàííûõ. Ïîýòîìó âòîðîé ìåòîä áîëåå ïðåäïî÷òèòåëåí. 18
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.1. Ñðåäñòâà îïðåäåëåíèÿ äàííûõ ÿçûêà SQL
Îïðåäåëåíèå òàáëèöû ARTIST â ëèñòèíãå 2.2 äåìîíñòðèðóåò åùå îäèí ñïîñîá îïðåäåëåíèÿ ïåðâè÷íîãî êëþ÷à. Çäåñü îãðàíè÷åíèå îïðåäåëÿåòñÿ â òåëå îïåðàòîðà CREATE, ïîñëå òîãî êàê îïðåäåëåíû âñå ñòîëáöû. Èñïîëüçóÿ ýòîò ïîäõîä, ðàçðàáîò÷èê ìîæåò ïðèñâàèâàòü èìåíà îãðàíè÷åíèÿì â ìîìåíò ñîçäàíèÿ òàáëèö, íå ïðèáåãàÿ ê èñïîëüçîâàíèþ îïåðàòîðà ALTER. Ëèñòèíã 2.3.
CREATE TABLE CUSTOMER_ARTIST_INT( ArtistID int NOT NULL, CustomerID int NOT NULL, CONSTRAINT CustomerArtistPK PRIMARY KEY (ArtistID, CustomerID), CONSTRAINT Customer_Artist_Int_ArtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) ON DELETE CASCADE, CONSTRAINT Customer_Artist_Int_CustomerFK FOREIGN KEY (CustomerID) REFERENCES CUSTOMER (CustomerID) ON DELETE CASCADE);
Êîìïîçèòíûé êëþ÷ îïðåäåëÿåòñÿ ïóòåì ïåðå÷èñëåíèÿ èìåí àòðèáóòîâ â ñêîáêàõ. Ïåðâè÷íûé êëþ÷ òàáëèöû CUSTOMER_ARTIST_INT ïðåäñòàâëÿåò ñîáîé ñî÷åòàíèå {ArtistID, CustomerID}. Êîìïîçèòíûé ïåðâè÷íûé êëþ÷ íå ìîæåò áûòü îïðåäåëåí ñ ïîìîùüþ òîãî ìåòîäà, êîòîðûé ïðåäñòàâëåí â ëèñòèíãå 2.1. Ïîñðåäñòâîì îïåðàòîðà ALTER ìîæíî òàêæå îïðåäåëÿòü âíåøíèå êëþ÷è (ñì. ëèñòèíã 2.3). Îãðàíè÷åíèå Customer_Artist_Int_ArtistFK óêàçûâàåò, ÷òî ñòîëáåö ArtistID ÿâëÿåòñÿ âíåøíèé êëþ÷îì, êîòîðûé óêàçûâàåò íà ñòîëáåö ARTIST.ArtistID. Àááðåâèàòóðà FK îçíà÷àåò âíåøíèé êëþ÷ (foreign key).  îïðåäåëåíèè âíåøíåãî êëþ÷à ìîæíî óêàçàòü ïðîöåäóðó îáåñïå÷åíèÿ ññûëî÷íîé öåëîñòíîñòè ïðè óäàëåíèè: ON DELETE CASCADE. 19
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
2.1.3
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Îïåðàòîðû DROP
Îäíèì èç ñàìûõ ïîëåçíûõ îïåðàòîðîâ îïðåäåëåíèÿ äàííûõ SQL ÿâëÿåòñÿ îïåðàòîð DROP TABLE. Íî îí îäíîâðåìåííî ÿâëÿåòñÿ è îäíèì èç ñàìûõ îïàñíûõ, ïîñêîëüêó óäàëÿåò òàáëèöó èç áàçû äàííûõ âìåñòå ñî âñåìè ñîäåðæàùèìèñÿ â íåé äàííûìè. Åñëè íåîáõîäèìî óäàëèòü èç áàçû äàííûõ òàáëèöó CUSTOMER è âñå ñîäåðæàùèåñÿ â íåé äàííûå, òî ìîæíî èñïîëüçîâàòü ñëåäóþùèé îïåðàòîð:
DROP TABLE CUSTOMER Îïåðàòîð DROP TABLE íå âûïîëíÿåòñÿ, åñëè òàáëèöà ñîäåðæèò èëè ìîæåò ñîäåðæàòü çíà÷åíèÿ, íåîáõîäèìûå äëÿ ñîáëþäåíèÿ îãðàíè÷åíèé ññûëî÷íîé öåëîñòíîñòè. Íàïðèìåð, ñòîëáåö ArtistID òàáëèöû ARTIST ìîæåò ñîäåðæàòü çíà÷åíèÿ, íåîáõîäèìûå äëÿ ñîáëþäåíèÿ îãðàíè÷åíèÿ âíåøíåãî êëþ÷à Customer_Artist_Int_ArtistFK. Ïîïûòêà ïåðåäàòü ÑÓÁÄ íà âûïîëíåíèå îïåðàòîð DROP TABLE ARTIST îêîí÷èòñÿ íåóäà÷åé è ñèñòåìà âûäàñò ñîîáùåíèå îá îøèáêå. Åñëè íåîáõîäèìî óäàëèòü òàáëèöó ARTIST, íóæíî ñíà÷àëà óäàëèòü ëèáî îãðàíè÷åíèå âíåøíåãî êëþ÷à Customer_Artist_Int_ArtistFK, ëèáî âñþ òàáëèöó CUSTOMER_ARTIST_INT. Óäàëèòü îãðàíè÷åíèå ìîæíî ïðè ïîìîùè ñëåäóþùåãî îïåðàòîðà:
ALTER TABLE CUSTOMER_ARTIST_INT DROP CONSTRAINT Customer_Artist_Int_ArtistFK Â äðóãîé ãëàâå áóäóò ðàññìîòðåíû äîïîëíèòåëüíûå ïðèìåíåíèÿ îïåðàòîðà ALTER.
2.2
Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ñîçäàâ òàáëèöó, ìîæíî çàïèñûâàòü â íåå äàííûå, èçìåíÿòü èõ çíà÷åíèÿ è óäàëÿòü äàííûå èç òàáëèöû. Ïðåäïîëàãàåòñÿ, ÷òî äàííûå, ïðèâåäåííûå â òàáë. 1.1-1.5 óæå ââåäåíû â áàçó äàííûõ. Îïåðàòîðû, êîòîðûå ïîçâîëÿþò äîáàâëÿòü, ìîäèôèöèðîâàòü è óäàëèòü ñòðîêè â òàáëèöàõ áóäóò ðàññìîòðåíû â ðàçäåëå 2.3. 20
Ãëàâà 2.
2.2.1
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
×òåíèå çàäàííûõ ñòîëáöîâ èç îäèíî÷íîé òàáëèöû
Ñëåäóþùèé îïåðàòîð çàïðîñèò (ïðî÷èòàåò) òðè èç ïÿòè ñòîëáöîâ òàáëèöû ARTIST:
SELECT Name, Nationality, BirthDate FROM ARTIST; Èìåíà çàïðàøèâàåìûõ ñòîëáöîâ ïåðå÷èñëÿþòñÿ ïîñëå êëþ÷åâîãî ñëîâà SELECT, à èìÿ îòíîøåíèÿ, èç êîòîðîãî ñ÷èòûâàþòñÿ äàííûå, óêàçûâàþòñÿ ïîñëå êëþ÷åâîãî ñëîâà FROM. Ðåçóëüòàòîì ýòîãî îïåðàòîðà ïðè èñïîëüçîâàíèè äàííûõ èç òàáëèöû ARTIST (ñì. òàáë. 1.1) áóäåò ñëåäóþùàÿ òàáëèöà: Miro Kandinsky Frings Klee Moos Tobey Matisse Chagall
Spanish Russian US German US US French French
1870 1854 1700 1900
Ðåçóëüòàòîì ðàáîòû îïåðàòîðà SELECT âñåãäà ÿâëÿåòñÿ îòíîøåíèå. Ýòîò îïåðàòîð áåðåò îäíî èëè íåñêîëüêî îòíîøåíèé, ìàíèïóëèðóåò èìè îïðåäåëåííûì îáðàçîì è âûäàåò íà âûõîäå îäíî îòíîøåíèå. Äàæå åñëè ðåçóëüòàòîì ÿâëÿåòñÿ âñåãî ëèøü îäíî ÷èñëî, ýòî ÷èñëî ðàññìàòðèâàåòñÿ êàê îòíîøåíèå, èìåþùåå îäíó ñòðîêó è îäèí ñòîëáåö. Ïîðÿäîê ñòîëáöîâ â ðåçóëüòèðóþùåé òàáëèöå îïðåäåëÿåòñÿ ïîðÿäêîì ñëåäîâàíèÿ èõ èìåí ïîñëå êëþ÷åâîãî ñëîâà SELECT. Ïðåäïîëîæèì, ÷òî ïîðÿäîê èìåí ñòîëáöîâ â îïåðàòîðå SELECT áóäåò ñëåäóþùèì:
SELECT Nationality, Name, BirthDate FROM ARTIST; Ðåçóëüòàò ðàáîòû îïåðàòîðà áóäåò ñëåäóþùèì: 21
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Spanish Russian US German US US French French
Miro Kandinsky Frings Klee Moos Tobey Matisse Chagall
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
1870 1854 1700 1900
Ñëåäóþùèé îïåðàòîð SELECT èçâëåêàåò èç òàáëèöû ARTIST òîëüêî ñòîëáåö Nationality:
SELECT Nationality FROM ARTIST; Ðåçóëüòàòîì áóäåò òàáëèöà: Spanish Russian US German US US French French Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî â ïîñëåäíåé òàáëèöå åñòü îäèíàêîâûå ñòðîêè. Ñîãëàñíî îïðåäåëåíèþ îòíîøåíèÿ, ïîâòîðåíèÿ ñòðîê â îòíîøåíèè íåäîïóñòèìî. Îäíàêî ïðîöåññ ïîèñêà è óäàëåíèÿ òàêèõ ïîâòîðåíèé îòíèìàåò ìíîãî âðåìåíè. Òàêèì îáðàçîì, íà ïðàêòèêå âñå æå ïðèõîäèòñÿ ñòàëêèâàòüñÿ ñ îäèíàêîâûìè ñòðîêàìè. Åñëè íóæíî, ÷òîáû ÑÓÁÄ íàøëà è óäàëèëà ïîâòîðÿþùèåñÿ ñòðîêè, ïðè çàïðîñå íåîáõîäèìî èñïîëüçîâàòü êëþ÷åâîå ñëîâî DISTINCT:
SELECT DISTINCT Nationality FROM ARTIST; Ðåçóëüòàò áóäåò èìåòü âèä: 22
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Spanish Russian US German French 2.2.2
×òåíèå çàäàííûõ ñòðîê èç îäèíî÷íîé òàáëèöû
Ðàíåå ðàññìîòðåííûå îïåðàòîðû SQL âûáèðàëè îïðåäåëåííûå ñòîëáöû âñåõ ñòðîê òàáëèöû. Òåïåðü ðàññìîòðèì îïåðàòîðû, ïîçâîëÿþùèå âûáèðàòü ñòîëáöû îïðåäåëåííûõ ñòðîê. Ñëåäóþùèé îïåðàòîð çàïðàøèâàåò âñå ñòîëáöû èç òåõ ñòðîê òàáëèöû ARTIST, êîòîðûå ñîäåðæàò ñâåäåíèÿ î õóäîæíèêàõ ôðàíöóçñêîé íàöèîíàëüíîñòè:
SELECT ArtistID, Name, Nationality, BirthDate, DeceasedDate FROM ARTIST WHERE Nationality = 'French'; Ðåçóëüòàò èìååò ñëåäóþùèé âèä: 15 16
Matisse Chagall
French French
Âòîðîé ñïîñîá çàïðîñèòü âñå ñòîëáöû òàáëèöû - èñïîëüçîâàòü ñïåöèàëüíûé ñèìâîë * ïîñëå êëþ÷åâîãî ñëîâà SELECT. Ïðèâåäåííûé íèæå îïåðàòîð ýêâèâàëåíòåí ïðåäûäóùåìó:
SELECT * FROM ARTIST WHERE Nationality = 'French'; Øàáëîí SELECT/FROM/WHERE ýòî ôóíäàìåíòàëüíûé øàáëîí ïîñòðîåíèÿ SQL-îïåðàòîðîâ SELECT.  ïðåäëîæåíèè WHERE ìîãóò ñîäåðæàòüñÿ ðàçëè÷íîãî ðîäà óñëîâèÿ. Íàïðèìåð, ñëåäóþùèé çàïðîñ èçâëåêàåò âñå ñòîëáöû èç òåõ ñòðîê òàáëèöû ARTIST, ãäå çíà÷åíèå ñòîëáöà BirthDate ìåíüøå 1880:
SELECT ArtistID, Name, Nationality, BirthDate, DeceasedDate FROM ARTIST WHERE BirthDate < 1880; 23
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ðåçóëüòàò ñëåäóþùèé: 3 4 5
Miro Kandinsky Frings
Spanish Russian US
1870 1854 1700
1950 1900 1800
Ñëåäóåò îáðàòèòü âíèìàíèå íà òî, ÷òî êîãäà ñòîëáåö èìååò òèï äàííûõ Char èëè VarChar, ñðàâíèâàåìûå çíà÷åíèÿ äîëæíû ïîìåùàòüñÿ â îäèíî÷íûå êàâû÷êè. Åñëè ñòîëáåö èìååò òèï äàííûõ Integer èëè Numeric, êàâû÷êè íåîáÿçàòåëüíû.  ïðåäëîæåíèè WHERE ìîæíî óêàçàòü áîëåå îäíîãî óñëîâèÿ, åñëè èñïîëüçîâàòü êëþ÷åâîå ñëîâî AND:
SELECT * FROM ARTIST WHERE Nationality = 'US' AND BirthDate < 1800; Ðåçóëüòàò áóäåò ñëåäóþùèé: 5
Frings
2.2.3
US
1700
1800
×òåíèå çàäàííûõ ñòðîê è ñòîëáöîâ èç îäèíî÷íîé òàáëèöû
Îáúåäèíèâ îïèñàííûå âûøå ìåòîäû, ìîæíî âûáèðàòü èç òàáëèöû îïðåäåëåííûå ñòîëáöû è îïðåäåëåííûå ñòðîêè. Ñëåäóþùèé îïåðàòîð èçâëåêàåò èç òàáëèöû ARTIST ñòîëáöû Name è Nationality ñîòðóäíèêîâ ôðàíöóçñêîé íàöèîíàëüíîñòè:
SELECT Name, Nationality FROM ARTIST WHERE Nationality = 'French'; Ýòîò çàïðîñ âûäàñò ñëåäóþùóþ òàáëèöó: Matisse Chagall
French French
Åùå îäíà ôîðìà ïðåäëîæåíèÿ WHERE ïðåäïîëàãàåò çàäàíèÿ ñïèñêà çíà÷åíèé, êîòîðûå ìîæåò èìåòü ñòîëáåö. Ýòî äåëàåòñÿ ñ ïîìîùüþ êëþ÷åâîãî ñëîâà IN: 24
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
SELECT Name, Nationality FROM ARTIST WHERE Nationality IN ('Russian', 'German'); Ðåçóëüòàò áóäåò ñëåäóþùèì: Kandinsky Klee
Russian German
Ñòðîêà èñõîäíîãî îòíîøåíèÿ âîéäåò â ðåçóëüòèðóþùóþ òàáëèöó, åñëè åå ñòîëáåö Nationality èìååò çíà÷åíèå 'Russian' èëè 'German'. ×òîáû âûáðàòü ñòðîêè, ó êîòîðûõ ñòîëáåö Nationality íå ðàâåí íè îäíîìó èç ýòèõ çíà÷åíèé, èñïîëüçóéòå êëþ÷åâîå ñëîâî NOT IN:
SELECT Name, Nationality FROM ARTIST WHERE Nationality NOT IN ('Russian', 'German'); Ðåçóëüòàò ýòîãî çàïðîñà áóäåò ñëåäóþùèì: Miro Frings Moos Tobey Matisse Chagall
Spanish US US US French French
Îáðàòèòå âíèìàíèå íà ïðèíöèïèàëüíîå ðàçëè÷èå ìåæäó êëþ÷åâûìè ñëîâàìè IN è NOT IN. Ïðè èñïîëüçîâàíèè IN ñòîëáåö ìîæåò èìåòü ëþáîå èç çíà÷åíèé, óêàçàííûõ â ñïèñêå. Ïðè èñïîëüçîâàíèè NOT IN ñòîëáåö íå äîëæåí ïðèíèìàòü íè îäíî èç ïåðå÷èñëåííûõ çíà÷åíèé. 2.2.4
Äèàïàçîíû, ñïåöèàëüíûå ñèìâîëû è ïóñòûå çíà÷åíèÿ â ïðåäëîæåíèÿõ WHERE
 ïðåäëîæåíèÿõ WHERE ìîãóò òàêæå óêàçûâàòüñÿ äèàïàçîíû è øàáëîíû ïîèñêà. Äëÿ çàäàíèÿ äèàïàçîíîâ èñïîëüçóåòñÿ êëþ÷åâîå ñëîâî BETWEEN. Íàïðèìåð, îïåðàòîð 25
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
SELECT Name, Nationality FROM ARTIST WHERE BirthDate BETWEEN 1700 AND 1890; äàñò ñëåäóþùèé ðåçóëüòàò: Miro Kandinsky Frings
Spanish Russian US
Ýòîò îïåðàòîð ýêâèâàëåíòåí ñëåäóþùåìó:
SELECT Name, Nationality FROM ARTIST WHERE BirthDate >= 1700 AND BirthDate <= 1890; Òàêèì îáðàçîì, äèàïàçîí, çàäàâàåìûé êëþ÷åâûì ñëîâîì BETWEEN, âêëþ÷àåò â ñåáÿ ãðàíè÷íûå çíà÷åíèÿ (â äàííîì ñëó÷àå 1700 è 1890). Äëÿ çàäàíèÿ øàáëîíîâ ïîèñêà â SQL èñïîëüçóåòñÿ êëþ÷åâîå ñëîâî LIKE. Ñèìâîë ïîä÷åðêèâàíèÿ (_) ïðåäñòàâëÿåò ëþáîé îäèíî÷íûé ñèìâîë. Ñ åãî ïîìîùüþ ìîæíî íàõîäèòü çíà÷åíèÿ, óäîâëåòâîðÿþùèå çàäàííîìó øàáëîíó:
SELECT * FROM ARTIST WHERE Nationality LIKE 'S_anish'; Ïîä÷åðêèâàíèå îçíà÷àåò, ÷òî äàííîì ìåñòå ìîæåò ñòîÿòü ëþáîé ñèìâîë. Ðåçóëüòàòîì ýòîãî îïåðàòîðà ÿâëÿåòñÿ ñëåäóþùàÿ òàáëèöà: 3
Miro
Spanish
1870
1950
Ñëåäóåò îáðàòèòü îñîáîå âíèìàíèå íà òàêóþ ñèòóàöèþ. ×òîáû íàéòè âñåõ õóäîæíèêîâ, ÷üå èìÿ íà÷èíàåòñÿ íà áóêâó 'Ì' è ñîñòîèò èç ÷åòûðåõ ñèìâîëîâ, íåëüçÿ èñïîëüçîâàòü ñëåäóþùèé øàáëîí:
SELECT * FROM ARTIST WHERE Name LIKE 'M___'; 26
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ðåçóëüòàòîì áóäåò òàáëèöà, ñîñòîÿùàÿ èç íóëåâîãî êîëè÷åñòâà ñòðîê. Ïðè÷èíà òàêîãî ðåçóëüòàòà çàêëþ÷àåòñÿ â òîì, ÷òî ñòîëáåö Name èìååò òèï Char(25). Ñëåäîâàòåëüíî, êàæäîå èìÿ áóäåò ñîäåðæàòü äâàäöàòü ïÿòü ñèìâîëîâ, à íå ÷åòûðå, êàê ïðåäïîëàãàëîñü â øàáëîíå. Ñèìâîë ïðîöåíòà (%) ïðåäñòàâëÿåò ïîñëåäîâàòåëüíîñòü èç îäíîãî èëè íåñêîëüêèõ ïðîèçâîëüíûõ ñèìâîëîâ. Çàïðîñ, âîçâðàùàþùèé ñòðîêè õóäîæíèêîâ, ÷üè èìåíà íà÷èíàþòñÿ ñ áóêâû 'Ì', ìîæíî çàïèñàòü ñëåäóþùèì îáðàçîì:
SELECT * FROM ARTIST WHERE Name LIKE 'M%'; Ðåçóëüòàò áóäåò ñëåäóþùèì: 3 8 15
Miro Moos Matisse
Spanish US French
1870
1950
Åñëè òðåáóåòñÿ íàéòè âñåõ õóäîæíèêîâ, ÷üè íàöèîíàëüíîñòè çàêàí÷èâàþòñÿ íà áóêâó 'h', ìîæíî èñïîëüçîâàòü ñèìâîë ïðîöåíòà ñëåäóþùèì îáðàçîì:
SELECT * FROM ARTIST WHERE Nationality LIKE '%h'; Ðåçóëüòàò áóäåò òàêèì: 3 15 16
Miro Matisse Chagall
Spanish French French
1870
1950
Äëÿ ïîèñêà ïóñòûõ çíà÷åíèé â ïðåäëîæåíèè WHERE ñëóæèò êîíñòðóêöèÿ IS NULL. Ñëåäóþùèé çàïðîñ âûäàåò èìåíà è íàöèîíàëüíîñòè âñåõ õóäîæíèêîâ, ó êîòîðûõ íå óêàçàí ãîä ðîæäåíèÿ:
SELECT Name, Nationality FROM ARTIST WHERE BirthDate IS NULL; 27
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ðåçóëüòàò çàïðîñà áóäåò òàêèì: Moos Tobey Matisse Chagall
US US French French
Ñîðòèðîâêà ðåçóëüòàòîâ
Ïîðÿäîê ñòðîê â òàáëèöå, âîçâðàùàåìîé îïåðàòîðîì SELECT, ÿâëÿåòñÿ ïðîèçâîëüíûì. Åñëè íóæíî îòñîðòèðîâàòü ñòðîêè ðåçóëüòàòà, ýòî ìîæíî ñäåëàòü ñ ïîìîùüþ êîíñòðóêöèè ORDER BY. Íàïðèìåð, ñëåäóþùèé çàïðîñ âîçâðàùàåò èìåíà è íàöèîíàëüíîñòè õóäîæíèêîâ, îòñîðòèðîâàííûõ â àëôàâèòíîì ïîðÿäêå ïî èìåíàì:
SELECT Name, Nationality FROM ARTIST ORDER BY Name; Ðåçóëüòàòîì áóäåò ñëåäóþùàÿ òàáëèöà: Chagall Frings Kandinsky Klee Matisse Miro Moos Tobey
French US Russian German French Spanish US US
Ïî óìîë÷àíèþ ñîðòèðîâêà â SQL ïðîèçâîäèòñÿ â ïîðÿäêå âîçðàñòàíèÿ. Äëÿ ÿâíîãî óêàçàíèÿ ïîðÿäêà ñîðòèðîâêè ìîæíî èñïîëüçîâàòü êëþ÷åâûå ñëîâà ASC (ïî âîçðàñòàíèþ) è DESC (ïî óáûâàíèþ). Íàïðèìåð, ñëåäóþùèé çàïðîñ îòñîðòèðóåò õóäîæíèêîâ ïî èìåíàì â îáðàòíîì ïîðÿäêå:
SELECT Name, Nationality FROM ARTIST ORDER BY Name DESC; 28
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ðåçóëüòàò áóäåò òàêèì: Tobey Moos Miro Matisse Klee Kandinsky Frings Chagall
US US Spanish French German Russian US French
Ñîðòèðîâàòü ìîæíî è áîëåå ÷åì ïî îäíîìó ñòîëáöó. ×òîáû îòñîðòèðîâàòü ñïèñîê èìåí õóäîæíèêîâ è èõ íàöèîíàëüíîñòåé ñíà÷àëà ïî íàöèîíàëüíîñòÿì â îáðàòíîì ïîðÿäêå, à ïîòîì âíóòðè êàæäîé íàöèîíàëüíîñòè ïî èìåíàì â ïðÿìîì ïîðÿäêå, ìîæíî áûëî áû èñïîëüçîâàòü òàêîé çàïðîñ:
SELECT Name, Nationality FROM ARTIST ORDER BY Nationality DESC, Name ASC; Ýòî ïðèâåäåò ê ñëåäóþùåìó ðåçóëüòàòó: Frings Moos Tobey Miro Kandinsky Klee Chagall Matisse 2.2.5
US US US Spanish Russian German French French
Âñòðîåííûå ôóíêöèè SQL
 SQL èìååòñÿ ïÿòü âñòðîåííûõ ôóíêöèé: COUNT, SUM, AVG, MAX è MIN. Îíè âûïîëíÿþò ðàçëè÷íûå äåéñòâèÿ íàä ðåçóëüòàòàìè îïåðàòîðà SELECT. Ôóíêöèÿ COUNT ðàáîòàåò âíå çàâèñèìîñòè îò òèïà äàííûõ ñòîëáöà, à ôóíêöèè SUM, AVG, MAX è MIN îïåðèðóþò òîëüêî ÷èñëîâûìè ñòîëáöàìè (Integer, Numeric è ò.ä.). 29
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ôóíêöèÿ COUNT ïîäñ÷èòûâàåò êîëè÷åñòâî ñòðîê â ðåçóëüòàòå, à ôóíêöèÿ SUM âû÷èñëÿåò ñóììó çíà÷åíèé ÷èñëîâîãî ñòîëáöà. Íàïðèìåð, ñëåäóþùèé SQL-îïåðàòîð ïîäñ÷èòûâàåò êîëè÷åñòâî ñòðîê â òàáëèöå ARTIST:
SELECT COUNT(*) FROM ARTIST; Ðåçóëüòàòîì ýòîãî îïåðàòîðà ÿâëÿåòñÿ ñëåäóþùåå îòíîøåíèå: 8 Êàê óæå ãîâîðèëîñü ðàíåå, ðåçóëüòàòîì SQL-îïåðàòîðà SELECT âñåãäà ÿâëÿåòñÿ îòíîøåíèå. Åñëè, êàê â äàííîì ñëó÷àå, ðåçóëüòàò ïðåäñòàâëÿåò ñîáîé îäèíî÷íîå ÷èñëî, ýòî ÷èñëî âñå ðàâíî ñ÷èòàåòñÿ îòíîøåíèåì, èìåþùèì îäíó ñòðîêó è îäèí ñòîëáåö. Ðàññìîòðèì ñëåäóþùèå äâà îïåðàòîðà:
SELECT COUNT(Nationality) FROM ARTIST; è
SELECT COUNT(DISTINCT Nationality) FROM ARTIST; Ðåçóëüòàòîì ïåðâîãî îïåðàòîðà áóäåò îòíîøåíèå 8 Ðåçóëüòàòîì ïåðâîãî îïåðàòîðà áóäåò îòíîøåíèå 5 Ðàçíèöà â îòâåòàõ âîçíèêàåò ïîòîìó, ÷òî âòîðîé îïåðàòîð SELECT íå ó÷èòûâàåò ïîâòîðÿþùèåñÿ ñòðîêè. Âîò åùå îäèí ïðèìåð èñïîëüçîâàíèÿ âñòðîåííûõ ôóíêöèé:
SELECT MIN(SalesPrice), MAX(SalesPrice), SUM(SalesPrice) FROM TRANSACTION WHERE TransactionID < 125; 30
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ðåçóëüòàòîì áóäåò ñëåäóþùàÿ òàáëèöà: 9750
73500
165950
Êðîìå ñëó÷àÿ ñ èñïîëüçîâàíèåì êëþ÷åâûõ ñëîâ GROUP BY (ñì. äàëåå), èìåíà ñòîëáöîâ íå ìîãóò ñìåøèâàòüñÿ ñî âñòðîåííûìè ôóíêöèÿìè. Íàïðèìåð, ñëåäóþùèé îïåðàòîð íåäîïóñòèì :
SELECT CustomerID, SUM(SalesPrice) FROM TRANSACTION WHERE TransactionID < 125; 2.2.6
Âñòðîåííûå ôóíêöèè è ãðóïïèðîâêà
Ïîëåçíîñòü âñòðîåííûõ ôóíêöèé óâåëè÷èâàåò òîò ôàêò, ÷òî èõ ìîæíî ïðèìåíÿòü ê ãðóïïàì ñòðîê äàííûõ. Íàïðèìåð, ñëåäóþùèé îïåðàòîð ïîäñ÷èòûâàåò êîëè÷åñòâî õóäîæíèêîâ êàæäîé íàöèîíàëüíîñòè:
SELECT Nationality, COUNT(*) FROM ARTIST GROUP BY Nationality; Ðåçóëüòàò áóäåò òàêèì: US French Russian Spanish German
3 2 1 1 1
Êëþ÷åâîå ñëîâî GROUP BY ïðåäïèñûâàåò ÑÓÁÄ îòñîðòèðîâàòü òàáëèöó ïî óêàçàííîìó ñòîëáöó, à çàòåì ïðèìåíèòü âñòðîåííûå ôóíêöèè ê ãðóïïàì ñòðîê, èìåþùèì îäèíàêîâûå çíà÷åíèÿ äàííîãî ñòîëáöà. Ïðè èñïîëüçîâàíèè GROUP BY èìÿ ñòîëáöà, ïî êîòîðîìó ïðîèçâîäèòñÿ ãðóïïèðîâêà, è âñòðîåííûå ôóíêöèè ìîãóò ñîñóùåñòâîâàòü â ïðåäëîæåíèè SELECT. Ýòî åäèíñòâåííûé ñëó÷àé, êîãäà èìÿ ñòîëáöà ìîæåò ïîÿâëÿòüñÿ âìåñòå ñî âñòðîåííûìè ôóíêöèÿìè. 31
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Äàëåå îãðàíè÷èòü ìíîæåñòâî âûäàâàåìûõ ðåçóëüòàòîâ ìîæíî, ïðèìåíÿÿ ê ôîðìèðóåìûì ãðóïïàì ðàçëè÷íûå óñëîâèÿ. Íàïðèìåð, åñëè íàñ èíòåðåñóþò òîëüêî òå ãðóïïû, â êîòîðûõ èìååòñÿ áîëåå îäíîé çàïèñè, ìû ìîãëè áû íàïèñàòü ñëåäóþùåå:
SELECT Nationality, COUNT(*) FROM ARTIST GROUP BY Nationality HAVING COUNT(*)>1; Ðåçóëüòàòîì ýòîãî îïåðàòîðà áóäåò ñëåäóþùàÿ òàáëèöà: US French
3 2
Âìåñòå ñ êëþ÷åâûì ñëîâîì GROUP BY ìîæíî èñïîëüçîâàòü è ïðåäëîæåíèå WHERE. Îäíàêî çäåñü èìååò ìåñòî íåîäíîçíà÷íîñòü. Åñëè óñëîâèå â ïðåäëîæåíèè WHERE ïðèìåíÿåòñÿ äî ôîðìèðîâàíèÿ ãðóïï, ðåçóëüòàò áóäåò èíûì, ÷åì êîãäà ýòî óñëîâèå ïðèìåíÿåòñÿ ê óæå ñôîðìèðîâàííûì ãðóïïàì. Äëÿ óñòðàíåíèÿ ýòîé íåîäíîçíà÷íîñòè ñòàíäàðò SQL óñòàíàâëèâàåò, ÷òî â ñëó÷àÿõ, êîãäà ïðåäëîæåíèÿ WHERE è GROUP BY èñïîëüçóþòñÿ îäíîâðåìåííî, ïåðâûì äîëæíî ïðèìåíÿòüñÿ óñëîâèå, çàïèñàííîå â ïðåäëîæåíèè WHERE. Ðàññìîòðèì, íàïðèìåð, ñëåäóþùèé îïåðàòîð:
SELECT Nationality, COUNT(*) FROM ARTIST WHERE ArtistID < 10 GROUP BY Nationality HAVING COUNT(*)>1; Ïðè âûïîëíåíèè äàííîãî îïåðàòîðà ñíà÷àëà ïðèìåíÿåòñÿ óñëîâèå èç ïðåäëîæåíèÿ WHERE, êîòîðîå îòáèðàåò õóäîæíèêîâ, ÷åé èäåíòèôèêàòîð ìåíüøå 10. Çàòåì, ïîñëå ôîðìèðîâàíèÿ ãðóïï, ïðèìåíÿåòñÿ óñëîâèå èç ïðåäëîæåíèÿ HAVING. Ðåçóëüòàò èìååò ñëåäóþùèé âèä: US
2 32
Ãëàâà 2.
2.2.7
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
×òåíèå äàííûõ èç íåñêîëüêèõ òàáëèö ñ ïðèìåíåíèåì âëîæåííûõ çàïðîñîâ
Âñå çàïðîñû, ðàññìîòðåííûå ðàíåå, ñ÷èòûâàëè äàííûå èç îäèíî÷íîé òàáëèöû. Áûâàåò, îäíàêî, ÷òî äëÿ ïîëó÷åíèÿ òðåáóåìîé èíôîðìàöèè íåîáõîäèìî îáðàáîòàòü áîëåå îäíîé òàáëèöû. Ïðåäïîëîæèì, íàïðèìåð, ÷òî ìû õîòèì çíàòü íàçâàíèÿ ðàáîò, êîòîðûå áûëè ïðîäàíû ãàëåðååé äîðîæå 20000. Íàçâàíèÿ ðàáîò õðàíÿòñÿ â òàáëèöå WORK, à ñòîèìîñòè ïðîäàæ â òàáëèöå TRANSACTION. Åñëè áû ìû çíàëè, ÷òî äîðîæå 20000 áûëè ïðîäàíû ðàáîòû ñ íîìåðàìè 505, 506 è 530, ìû ìîãëè áû ïîëó÷èòü íàçâàíèÿ ýòèõ ðàáîò ñ ïîìîùüþ ñëåäóþùåãî îïåðàòîðà:
SELECT Title FROM WORK WHERE WorkID IN (505, 506, 530); Íî â òîì-òî è äåëî, ÷òî â óñëîâèè çàäà÷è íîìåðà ðàáîò íàì íå çàäàíû. Íè÷òî, îäíàêî, íå ìåøàåò íàì óçíàòü ýòè íîìåðà, èíèöèèðîâàâ ñëåäóþùèé çàïðîñ:
SELECT DISTINCT WorkID FROM TRANSACTION WHERE AskingPrice > 20000; Ðåçóëüòàòîì áóäåò òàáëèöà: 505 506 530 Òåïåðü ìû ìîæåì îáúåäèíèòü ýòè äâà SQL-îïåðàòîðà ïðè ïîìîùè òàê íàçûâàåìîãî âëîæåííîãî çàïðîñà (subquery):
SELECT Title FROM WORK WHERE WorkID IN (SELECT DISTINCT WorkID FROM TRANSACTION WHERE AskingPrice > 20000); 33
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ðåçóëüòàòîì ýòîãî îïåðàòîðà áóäåò ñëåäóþùåå: Mystic Fabric Mi Vida Northwest by Night È äåéñòâèòåëüíî, çäåñü ìû âèäèì íàçâàíèÿ ðàáîò, êîòîðûå áûëè ïðîäàíû ãàëåðååé äîðîæå 20000. Ïîäîáíûì îáðàçîì âëîæåííîñòü çàïðîñîâ ìîæåò áûòü ðàñøèðåíà äî òðåõ, ÷åòûðåõ è áîëåå óðîâíåé. 2.2.8
×òåíèå äàííûõ èç íåñêîëüêèõ òàáëèö ñ ïîìîùüþ îïåðàöèè ñîåäèíåíèÿ
Âëîæåííûå çàïðîñû ïîäõîäÿò äëÿ îáðàáîòêè íåñêîëüêèõ òàáëèö äî òåõ ïîð, ïîêà ðåçóëüòàòû (ñòîëáöû â ïðåäëîæåíèè SELECT) îòíîñÿòñÿ ê îäíîé è òîé æå òåáëèöå. Åñëè æå íàì íóæíî èçâëå÷ü äàííûå èç äâóõ èëè áîëåå òàáëèö, ïðè ïîìîùè âëîæåííîãî çàïðîñà ýòî ñäåëàòü íå óäàñòñÿ. Âìåñòî ýòîãî íåîáõîäèìî èñïîëüçîâàòü îïåðàöèþ ñîåäèíåíèÿ (join). Îñíîâíàÿ èäåÿ çäåñü ñîçäàòü íîâîå îòíîøåíèå, ñâÿçàâ ìåæäó ñîáîé ñîäåðæèìîå äâóõ èëè áîëåå èñõîäíûõ îòíîøåíèé. Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
SELECT Title, AskingPrice FROM WORK, TRANSACTION WHERE WORK.WorkID = TRANSACTION.WorkID; Ñìûñë ýòîãî îïåðàòîðà çàêëþ÷àåòñÿ â òîì, ÷òî ñîçäàåòñÿ íîâàÿ òàáëèöà ñ äâóìÿ ñòîëáöàìè Title è AskingPrice. Ýòè ñòîëáöû áåðóòñÿ ñîîòâåòñòâåííî èç òàáëèö WORK è TRANSACTION ïðè óñëîâèè, ÷òî ñòîëáåö WorkID â òàáëèöå WORK ðàâåí îäíîèìåííîìó ñòîëáöó â òàáëèöå TRANSACTION. Îáîçíà÷åíèÿ WORK.WorkID è TRANSACTION.WorkID íåîáõîäèìû äëÿ óñòðàíåíèÿ êîíôëèêòà èìåí ñòîëáöîâ. Ýòó îïåðàöèþ ìîæíî ïðåäñòàâèòü ñåáå ñëåäóþùèì îáðàçîì. Íà÷íåì ñ ïåðâîé ñòðîêè òàáëèöû TRANSACTION. Âîçüìåì çíà÷åíèå ñòîëáöà WorkID â äàííîé ñòðîêå (â òàáë. 1.3 ýòî 505) è ïðîñìîòðèì ñòðîêè òàáëèöû WORK (òàáë. 1.2). Íàéäÿ â òàáëèöå WORK ñòðîêó, ãäå WorkID òàêæå ðàâíÿåòñÿ 505, ñîåäèíèì ñòîëáåö Title òîëüêî ÷òî íàéäåííîé ïåðâîé 34
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
ñòðîêè òàáëèöû WORK ñî ñòîëáöîì AskingPrice ïåðâîé ñòðîêè òàáëèöû TRANSACTION. Ïåðâàÿ ñòðîêà òàáëèöû WORK (ñì. òàáë. 1.2) èìååò WorkID, ðàâíûé 505, ïîýòîìó ìû ñîåäèíÿåì ñòîëáåö Title ïåðâîé ñòðîêè òàáëèöû WORK ñî ñòîëáöîì AskingPrice ïåðâîé ñòðîêè òàáëèöû TRANSACTION, è ïîëó÷àåì òåì ñàìûì ïåðâóþ ñòðîêó ñîåäèíåíèÿ: Mystic Fabric
20000
Òåïåðü, ïî-ïðåæíåìó èñïîëüçóÿ WorkID=505, íàéäåì ñëåäóþùóþ ñòðîêó â îòíîøåíèè WORK, êîòîðàÿ èìååò WorkID, ðàâíûé 505. Òàêèõ ñòðîê áîëüøå íåò, ïîýòîìó ïåðåõîäèì êî âòîðîé ñòðîêå òàáëèöû TRANSACTION. Òàê êàê â ýòîé ñòðîêå WorkID òàê æå ðàâåí 505, ñíîâà íàéäåì ïåðâóþ ñòðîêó â îòíîøåíèè WORK, êîòîðàÿ èìååò WorkID, ðàâíûé 505. Ñîåäèíèâ ñòîëáåö Title ïåðâîé ñòðîêè òàáëèöû WORK ñî ñòîëáöîì AskingPrice âòîðîé ñòðîêè òàáëèöû TRANSACTION, ìû ïîëó÷èì âòîðóþ ñòðîêó ñîåäèíåíèÿ: Mystic Fabric Mystic Fabric
20000 47000
Òàêèì îáðàçîì ïåðåáèðàÿ âñå ñòðîêè îòíîøåíèÿ TRANSACTION ïîëó÷àåì îêîí÷àòåëüíûé ðåçóëüòàò: Mystic Fabric Mystic Fabric Mystic Fabric Mi Vida Mi Vida Slow Embers Mystic Fabric Northwest by Night
20000 47000 10000 17500 75000 15000 72500
Òàáëèöó, ïîëó÷èâøóþñÿ â ðåçóëüòàòå ñîåäèíåíèÿ, ìîæíî îáðàáàòûâàòü òàêæå, êàê è ëþáóþ äðóãóþ òàáëèöó. Íàïðèìåð, ìû ìîæåì ñãðóïïèðîâàòü ñòðîêè ïî íàçâàíèÿì êàðòèí è ïðîñóììèðîâàòü âûðó÷åííûå ñóììû ïî êàæäîé èç êàðòèí. Ýòî ñäåëàåò ñëåäóþùèé çàïðîñ: 35
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
SELECT Title, SUM(AskingPrice) FROM WORK, TRANSACTION WHERE WORK.WorkID = TRANSACTION.WorkID GROUP BY Title; Ðåçóëüòàòîì áóäåò ñëåäóþùàÿ òàáëèöà: Slow Embers Northwest by Night Mystic Fabric Mi Vida
15000 72500 77000 92500
Ïðåäëîæåíèå WHERE ìû òàêæå ìîæåì ïðèìåíèòü â ïðîöåññå ñîçäàíèÿ ñîåäèíåíèÿ:
SELECT Title, AskingPrice FROM WORK, TRANSACTION WHERE WORK.WorkID = TRANSACTION.WorkID AND AskingPrice > 20000; Ðåçóëüòàò ñîåäèíåíèÿ áóäåò òàêèì: Mystic Fabric Mi Vida Northwest by Night
47000 75000 72500
Ýòî òàêàÿ æå òàáëèöà, ïîýòîìó âñå îïèñàííûå âûøå SQL-îïåðàòîðû ê íåé ïðèìåíèìû. Òåïåðü ðàññìîòðèì ñëó÷àé, êîãäà òðåáóåòñÿ ñîåäèíèòü òðè òàáëèöû. Ïðåäïîëîæèì, íàì íóæíî çíàòü ïî êàæäîé êàðòèíå âûðó÷åííóþ ñóììó è èìÿ õóäîæíèêà. Äëÿ ýòîãî íàì íóæíî ñîåäèíèòü òðè òàáëèöû: TRANSACTION (ïîëå AskingPrice), WORK (ïîëå Title) è ARTIST (ïîëå Name):
SELECT Title, AskingPrice, Name FROM WORK, TRANSACTION, ARTIST WHERE WORK.WorkID = TRANSACTION.WorkID AND WORK.ArtistID = ARTIST.ArtistID; 36
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ðåçóëüòàòîì ñîåäèíåíèÿ áóäåò ñëåäóþùàÿ òàáëèöà: Mystic Fabric Mystic Fabric Mystic Fabric Mi Vida Mi Vida Slow Embers Mystic Fabric Northwest by Night
20000 47000 10000 17500 75000 15000
Tobey Tobey Tobey Miro Miro Tobey Tobey Chagall
72500
 ñòàíäàðòå SQL-92 ââåäåí àëüòåðíàòèâíûé ñèíòàêñèñ ñîåäèíåíèÿ, ñòàâøèé âåñüìà ïîïóëÿðíûì, ïîñêîëüêó åãî ëåã÷å èíòåðïðåòèðîâàòü. Çäåñü âìåñòî WHERE èñïîëüçóþòñÿ êëþ÷åâûå ñëîâà JOIN è ON:
SELECT Title, AskingPrice FROM WORK JOIN TRANSACTION ON WORK.WorkID = TRANSACTION.WorkID; Ðåçóëüòàò èìååò ñëåäóþùèé âèä: Mystic Fabric Mystic Fabric Mystic Fabric Mi Vida Mi Vida Slow Embers Mystic Fabric Northwest by Night
20000 47000 10000 17500 75000 15000 72500
Ñäåëàòü îïåðàòîð ñîåäèíåíèÿ áîëåå óäîáíûì äëÿ ÷òåíèÿ ìîæíî, èñïîëüçóÿ ïñåâäîíèìû äëÿ èìåí òàáëèö. Âûðàæåíèå FROM WORK W ïðèñâàèâàåò òàáëèöå WORK ïñåâäîíèì W. Ýòî ïîçâîëÿåò ïåðåïèñàòü ïðåäûäóùèé îïåðàòîð ñëåäóþùèì îáðàçîì:
SELECT Title, AskingPrice FROM WORK W JOIN TRANSACTION T ON W.WorkID = T.WorkID; 37
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ñîåäèíåíèå òðåõ òàáëèö ìîæíî âûïîëíèòü ïóòåì äîáàâëåíèÿ ïðåäëîæåíèÿ JOIN â êîíåö ïåðâîãî îïåðàòîðà SELECT:
SELECT W.Title, AskingPrice, A.Name FROM WORK W JOIN TRANSACTION T ON W.WorkID = T.WorkID JOIN ARTIST A ON W.ArtistID = A.ArtistID; Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî êîãäà òðåáóåòñÿ óêàçàòü èìÿ ñòîëáöà â ïåðâîé ñòðîêå îïåðàòîðà SELECT, íåîáõîäèìî èñïîëüçîâàòü ïñåâäîíèì, à íå èìÿ òàáëèöû. Òàê, â âûøå ïðèâåäåííîì îïåðàòîðå SELECT èñïîëüçóåòñÿ çàïèñü W.Title, à íå WORK.Title. Ïî ìåðå òîãî, êàê çàïðîñû óñëîæíÿþòñÿ, ýòîò ôîðìàò îêàçûâàåòñÿ ëåã÷å èíòåðïðåòèðîâàòü, è èìåííî îí áóäåò èñïîëüçîâàòüñÿ äëÿ ñîåäèíåíèé äàëåå. Íà ïðàêòèêå íåîáõîäèìî çíàòü îáà ôîðìàòà, ïîñêîëüêó è òîò, è äðóãîé ïðèìåíÿþòñÿ â ïðîìûøëåííîñòè. Òåïåðü ðàññìîòðèì ðàçëè÷èÿ ìåæäó âëîæåííûì çàïðîñîì è ñîåäèíåíèåì. Íà ïðàêòèêå ñîåäèíåíèå âî ìíîãèõ ñëó÷àÿõ ìîæíî èñïîëüçîâàòü â êà÷åñòâå àëüòåðíàòèâû âëîæåííûì çàïðîñàì. Íàïðèìåð, ðàíåå â ðàçäåëå 2.2.7 áûë èñïîëüçîâàí âëîæåííûé çàïðîñ äëÿ íàõîæäåíèÿ íàçâàíèÿ ðàáîò, êîòîðûå áûëè ïðîäàíû ãàëåðååé äîðîæå 20000. Ýòîò æå çàïðîñ ìîæíî ðåàëèçîâàòü è ñ ïîìîùüþ ñîåäèíåíèÿ:
SELECT DISTINCT Title FROM WORK JOIN TRANSACTION ON WORK.WorkID = TRANSACTION.WorkID AND AskingPrice > 20000; Õîòÿ ñèòóàöèè, êîãäà ñîåäèíåíèå ìîæíî èñïîëüçîâàòü âìåñòî âëîæåííîãî çàïðîñà, íåðåäêè, òàêàÿ çàìåíà âñå æå âîçìîæíà íå âñåãäà. Íàïðèìåð, ñîåäèíåíèÿ íå ìîãóò çàìåíèòü êîððåëèðîâàííûå âëîæåííûå çàïðîñû, à òàêæå çàïðîñû ñ èñïîëüçîâàíèåì êëþ÷åâûõ ñëîâ EXISTS è NOT EXISTS (áóäóò ðàññìàòðèâàòüñÿ äàëåå â äðóãèõ ðàçäåëàõ ïîñîáèÿ). È íàîáîðîò, íå âñåãäà âëîæåííûé çàïðîñ ìîæåò ñëóæèòü çàìåíîé äëÿ ñîåäèíåíèÿ.  ñîåäèíåíèè çàïðàøèâàåìûå ñòîëáöû ìîãóò ïðèíàäëåæàòü ëþáîé èç ñîåäèíÿåìûõ òàáëèö, à âî âëîæåííîì çàïðîñå âñå âîçâðàùàåìûå 38
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.2. Ñðåäñòâà çàïðîñà äàííûõ ÿçûêà SQL
ñòîëáöû äîëæíû ïðèíàäëåæàòü òîëüêî îäíîé òàáëèöå, à èìåííî òîé, êîòîðàÿ óêàçàíà â ïðåäëîæåíèè FROM ñàìîãî ïåðâîãî îïåðàòîðà SELECT. Íàïðèìåð, â ñëåäóþùåì âëîæåííîì çàïðîñå â ðåçóëüòàò âîéäóò òîëüêî ñòîëáöû òàáëèöû ARTIST:
SELECT DISTINCT Name FROM ARTIST WHERE ArtistID IN (SELECT ArtistID FROM WORK WHERE WorkID IN (SELECT WorkID FROM TRANSACTION WHERE AskingPrice > 20000)); Åñëè íóæíî âêëþ÷èòü â ðåçóëüòàò ñòîëáöû WORK.Title, ïðèäåòñÿ èñïîëüçîâàòü ñîåäèíåíèå:
SELECT A.Name, W.Title FROM ARTIST A JOIN WORK W ON A.ArtistID = W.ArtistID JOIN TRANSACTION ON TRANSACTION.WorkID = W.WorkID AND AskingPrice > 20000; 2.2.9
Âíåøíèå ñîåäèíåíèÿ
Ïðè âûïîëíåíèè ñîåäèíåíèÿ âîçìîæíà ñèòóàöèÿ, êîãäà ìîãóò áûòü ïîòåðÿíû äàííûå.  ÷àñòíîñòè, åñëè ñòðîêà èìååò çíà÷åíèå, êîòîðîå íå óäîâëåòâîðÿåò óñëîâèþ, çàäàííîìó â ïðåäëîæåíèè WHERE, ýòà ñòðîêà íå áóäåò âêëþ÷åíà â ðåçóëüòàò ñîåäèíåíèÿ. Òàêàÿ ïîòåðÿ ìîæåò áûòü íåæåëàòåëüíîé, è äëÿ ïðåäîòâðàùåíèÿ ïîäîáíûõ ñèòóàöèé áûë ââåäåí ñïåöèàëüíûé òèï ñîåäèíåíèÿ âíåøíåå ñîåäèíåíèå (outer join). Åñëè íóæíî ïîñòðîèòü ñîåäèíåíèå òàêèì îáðàçîì, ÷òîáû â ðåçóëüòàòû âîøëè êàæäàÿ ñòðîêà òàáëèöû ñëåâà îò êëþ÷åâîãî ñëîâà JOIN, äàæå åñëè äëÿ ýòîé ñòðîêè íå èìååòñÿ ñîîòâåòñòâèÿ âî âòîðîé òàáëèöå, òî íåîáõîäèìî èñïîëüçîâàòü ñëåäóþùèé ñèíòàêñèñ: 39
2.3. Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
SELECT Name, Title FROM ARTIST LEFT JOIN WORK ON WORK.ArtistID = ARTIST.ArtistID; Ñìûñë ýòîãî îïåðàòîðà â òîì, ÷òî ñòðîêè òàáëèöû ARTIST ñîåäèíÿþòñÿ ñî ñòðîêàìè òàáëèöû WORK, êàê è ðàíüøå, íî òåïåðü, åñëè êàêàÿ-òî ñòðîêà â òàáëèöå ñëåâà îò êëþ÷åâîãî ñëîâà JOIN (çäåñü ýòî òàáëèöà ARTIST) íå èìååò ñîîòâåòñòâèÿ â òàáëèöå, íàõîäÿùåéñÿ ñïðàâà, ýòà ñòðîêà âñå ðàâíî áóäåò âêëþ÷åíà â ðåçóëüòàò. Òàêîå ñîåäèíåíèå íàçûâàåòñÿ ëåâûì âíåøíèì ñîåäèíåíèåì (left outer join). Äëÿ äàííûõ èç òàáë. 1.1 è òàáë. 1.2 ðåçóëüòàò ýòîãî çàïðîñà áóäåò òàêèì: Tobey Miro Tobey Tobey Chagall Moos Matisse Klee Kandinsky
Mystic Fabric Mi Vida Slow Embers Mystic Fabric Northwest by Night
(right outer join) ôóíêöèîíèðóåò àíàëîãè÷íûì îáðàçîì, òîëüêî â ðåçóëüòàò âêëþ÷àþòñÿ âñå ñòðîêè òàáëèöû, íàõîäÿùåéñÿ ñïðàâà îò êëþ÷åâîãî ñëîâà JOIN. Ïðàâîå âíåøíåå ñîåäèíåíèå
2.3
Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
Ìîäèôèêàöèÿ äàííûõ ïîäðàçóìåâàåò òðè âîçìîæíûõ îïåðàöèè: âñòàâêà, èçìåíåíèå è óäàëåíèå. Â ýòîì ðàçäåëå ïîêàçûâàåòñÿ êàê âûïîëíÿþòñÿ ýòè îïåðàöèè ñðåäñòâàìè ÿçûêà SQL. 2.3.1
Âñòàâêà äàííûõ
Äëÿ âñòàâêè äàííûõ â òàáëèöû ñëóæèò SQL-îïåðàòîð INSERT. Ýòîò îïåðàòîð èìååò äâå ôîðìû, â çàâèñèìîñòè îò òîãî, âñåì ëè ñòîëáöàì òàáëèöû ïðèñâàèâàþòñÿ çíà÷åíèÿ. Åñëè óêàçûâàþòñÿ çíà÷åíèÿ âñåõ ñòîëáöîâ, òî îïåðàòîð èìååò ñëåäóþùèé âèä: 40
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
2.3. Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
INSERT INTO WORK VALUES (505, 'Mystic Fabric', 'One of the only pr', '99/135', 14); Îáðàòèòå âíèìàíèå, ÷òî çíà÷åíèÿ òèïà Integer è Numeric íå çàêëþ÷àþòñÿ â êàâû÷êè, â îòëè÷èå îò Char è VarChar. Åñëè äàííûå äëÿ êàêèõ-òî ñòîëáöîâ îòñóòñòâóþò, ìîæíî èñïîëüçîâàòü êëþ÷åâîå ñëîâî NULL äëÿ ïðîïóñêàåìûõ çíà÷åíèé:
INSERT INTO ARTIST VALUES (15, 'Matisse', 'French', NULL, NULL); Âòîðàÿ ôîðìà îïåðàòîðà INSERT, êîòîðàÿ äîïóñêàåò ïðîïóñê çíà÷åíèé íåêîòîðûõ ñòîëáöîâ, ïðåäïîëàãàåò ïåðå÷èñëåíèå èìåí ñòîëáöîâ, êîòîðûì áóäóò ïðèñâîåíû çíà÷åíèÿ. Íàïðèìåð, ñëåäóþùèé îïåðàòîð äîáàâëÿåò â òàáëèöó ARTIST ñòðîêó, â êîòîðîé ñòîëáöàì ArtistID, Name è Nationality ïðèñâîåíû çíà÷åíèÿ, à ñòîëáöû BirthDate è DeceasedDate îñòàâëåíû ïóñòûìè:
INSERT INTO ARTIST (Name, Nationality, ArtistID) VALUES ('Repin', 'Russian', 20); Åñëè äëÿ êàêîãî-ëèáî ñòîëáöà ïðè ñîçäàíèè òàáëèöû áûëî îïðåäåëåíî íà÷àëüíîå çíà÷åíèå, òîãäà íåñìîòðÿ íà òî, ÷òî â îïåðàòîðå INSERT çíà÷åíèå ýòîìó ñòîëáöó ìîæåò è íå ïðèñâàèâàòüñÿ, ÑÓÁÄ âñå ðàâíî óñòàíîâèò åãî ðàâíîå çíà÷åíèþ ïî óìîë÷àíèþ. Åñòü íåñêîëüêî äîïîëíèòåëüíûõ çàìå÷àíèé, êîòîðûå ñëåäóåò ñäåëàòü ïî ïîâîäó âòîðîé ôîðìû îïåðàòîðà INSERT. Âî-ïåðâûõ, ïîðÿäîê, â êîòîðîì ïåðå÷èñëÿþòñÿ çíà÷åíèÿ ñòîëáöîâ, äîëæåí ñîîòâåòñòâîâàòü ïîðÿäêó ñëåäîâàíèÿ èõ èìåí.  ïðåäûäóùåì ïðèìåðå èìåíà ñòîëáöîâ èäóò â ïîðÿäêå (Name, Nationality, ArtistID), ïîýòîìó ñíà÷àëà äîëæíî áûòü óêàçàíî çíà÷åíèå ñòîëáöà Name, çàòåì - Nationality è, íàêîíåö, ArtistID. Ñëåäóåò îòìåòèòü, ÷òî ñòîëáöû â òàáëèöå èäóò â äðóãîì ïîðÿäêå (ñì. òàáë. 1.1). Âî-âòîðûõ, ÷òîáû âñòàâêà áûëà âûïîëíåíà, íåîáõîäèìî çàäàòü çíà÷åíèÿ âñåõ ñòîëáöîâ, îïðåäåëåííûõ êàê NOT NULL. Åñëè òðåáóåòñÿ ñêîïèðîâàòü áîëüøîå êîëè÷åñòâî äàííûõ èç äðóãîé òàáëèöû, èõ çíà÷åíèÿ ìîæíî ïîëó÷èòü ñ ïîìîùüþ îïåðàòîðà SELECT. Íàïðèìåð, ñëåäóþùèé îïåðàòîð êîïèðóåò çíà÷åíèÿ ñòîëáöîâ ArtistID, Name è Nationality èç òàáëèöû ARTIST â òàáëèöó ARTIST_NEW (êîòîðàÿ äîëæíà áûòü ñîçäàíà çàðàíåå): 41
2.3. Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
INSERT INTO ARTIST_NEW (ArtistID, Name, Nationality) SELECT ArtistID, Name, Nationality FROM ARTIST; Îáðàòèòå âíèìàíèå, ÷òî â ýòîì ñëó÷àå êëþ÷åâîå ñëîâî VALUES íå âõîäèò â îïåðàòîð SELECT. 2.3.2
Èçìåíåíèå äàííûõ
Çíà÷åíèå ñóùåñòâóþùèõ äàííûõ ìîãóò áûòü èçìåíåíû ñ ïîìîùüþ SQLîïåðàòîðà UPDATE. Íóæíî ïðèíèìàòü âî âíèìàíèå, ÷òî ýòî ìîùíàÿ êîìàíäà è åå ñëåäóåò èñïîëüçîâàòü ñ îñòîðîæíîñòüþ. Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
UPDATE WORK SET Copy = '99/100' WHERE WorkID = 506; Ýòîò îïåðàòîð óñòàíàâëèâàåò çíà÷åíèå ñòîëáöà Copy â ñòðîêå ïðîèçâåäåíèÿ ñ íîìåðîì 506 ðàâíûì '99/100'. Òåïåðü ïîñìîòðèì, ÷òî èìåëîñü â âèäó, êîãäà ðå÷ü øëà îá îñòîðîæíîñòè. Äîïóñòèì, ÷òî ñîáèðàÿñü ïðîèçâåñòè ýòî èçìåíåíèå, âû ñäåëàëè îøèáêó è çàáûëè ïðî ïðåäëîæåíèå WHERE. Òàêèì îáðàçîì, áûë ïåðåäàí íà èñïîëíåíèå ÑÓÁÄ ñëåäóþùèé îïåðàòîð:
UPDATE WORK SET Copy = '99/100'  èòîãå, åñëè íå íàðóøàþòñÿ îãðàíè÷åíèÿ ñòîëáöà Copy (íàïðèìåð, îãðàíè÷åíèÿ ïî óíèêàëüíîñòè), òî âî âñåé òàáëèöå WORK ó ñòîëáöà Copy áóäåò îäíî çíà÷åíèå - '99/100'. Èòîã òàêîâ: îïåðàòîð UPDATE âåñüìà ìîùåí è ïðîñò â èñïîëüçîâàíèè, íî ìîæåò ïðèâåñòè ê ïå÷àëüíûì ïîñëåäñòâèÿì. Ñ ïîìîùüþ îïåðàòîðà UPDATE ìîæíî îáíîâëÿòü è íåñêîëüêî ñòîëáöîâ çà îäèí ïðèåì. Ýòî äåìåíñòðèðóåò ñëåäóþùèé ïðèìåð:
UPDATE WORK SET Copy = '99/100', Description = 'Very nice' WHERE WorkID = 506; Ýòà êîìàíäà èçìåíÿåò çíà÷åíèÿ ñòîëáöîâ Copy è Description äëÿ óêàçàííîé ðàáîòû. 42
Ãëàâà 2.
2.3.3
Ââåäåíèå â ÿçûê SQL
2.3. Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
Óäàëåíèå äàííûõ
Äëÿ óäàëåíèÿ ñòðîê ñëóæèò SQL-îïåðàòîð DELETE. Ê íåìó îòíîñÿòñÿ òå æå ñàìûå ïðåäîñòåðåæåíèÿ, ÷òî è ê îïåðàòîðó UPDATE. Îí îáìàí÷èâî ïðîñò â èñïîëüçîâàíèè, è íåîñòîðîæíîå åãî ïðèìåíåíèå ìîæåò ïðèâåñòè ê ñàìûì íåîæèäàííûì ïîñëåäñòâèÿì. Ñëåäóþùèé îïåðàòîð óäàëÿåò èç òàáëèöû CUSTOMER_ARTIST_INT ñòðîêó, â êîòîðîé ñòîëáåö ArtistID ðàâåí 16:
DELETE FROM CUSTOMER_ARTIST_INT WHERE ArtistID = 16; Êàê è â ñëó÷àå ñ îïåðàòîðîì UPDATE, åñëè âû çàáóäåòå óêàçàòü ïðåäëîæåíèå WHERE, ïîñëåäñòâèÿ ìîãóò áûòü êàòàñòðîôè÷åñêèìè. Íàïðèìåð, ñëåäóþùèé îïåðàòîð óäàëèò âñå ñòðîêè èç îòíîøåíèÿ CUSTOMER_ARTIST_INT:
DELETE FROM CUSTOMER_ARTIST_INT Çäåñü ñëåäóåò îáðàòèòü âíèìàíèå íà ïðîöåäóðó îáåñïå÷åíèÿ ññûëî÷íîé öåëîñòíîñòè ìåæäó òàáëèöàìè ARTIST è CUSTOMER_ARTIST_INT. Åñëè ìû ïîïûòàåìñÿ âûïîëíèòü ñëåäóþùóþ êîìàíäó, òî íàñ ïîñòèãíåò íåóäà÷à, ïîñêîëüêó óêàçàííàÿ ñòðîêà òàáëèöû ARTIST èìååò äî÷åðíèå ñòðîêè â òàáëèöå CUSTOMER_ARTIST_INT (ñì. ëèñòèíã 2.3):
DELETE FROM ARTIST WHERE ArtistID = 16;
43
2.3. Ñðåäñòâà ìîäèôèêàöèè äàííûõ ÿçûêà SQL
44
Ãëàâà 2.
Ââåäåíèå â ÿçûê SQL
Ãëàâà 3 Óñòàíîâêà Oracle è ïîäãîòîâêà äàííûõ Oracle 10g XE (eXpress Edition) áåñïëàòíàÿ âåðñèÿ ÑÓÁÄ Oracle â ñîñòàâå ïðîãðàììíîãî ïðîäóêòà. Âåðñèÿ XE ñîäåðæèò ðÿä îãðàíè÷åíèé:
• ïîääåðæèâàåòñÿ áàçà äàííûõ ðàçìåðîì äî 4 Ãáàéò; • íà îäíîì êîìïüþòåðå ìîæåò áûòü çàïóùåí òîëüêî îäèí ýêçåìïëÿð áàçû Oracle XE; • ïðè íàëè÷èè íà ñåðâåðå íåñêîëüêèõ ïðîöåññîðîâ Oracle XE èñïîëüçóåò òîëüêî îäèí èç íèõ; • Oracle XE èñïîëüçóåò íå áîëåå 1 Ãáàéò íåçàâèñèìî îò îáúåìà äîñòóïíîé îïåðàòèâíîé ïàìÿòè. Íåñìîòðÿ íà äàííûå îãðàíè÷åíèÿ, íà îñíîâå Oracle XE ìîæíî ñîçäàâàòü ïðèëîæåíèÿ äëÿ ðåøåíèÿ øèðîêîãî êðóãà çàäà÷. À åñëè ïî ìåðå ðîñòà áàçû äàííûõ è óâåëè÷åíèÿ êîëè÷åñòâà ïîëüçîâàòåëåé Oracle XE ïåðåñòàíåò ñïðàâëÿòüñÿ ñ ïîñòàâëåííûìè çàäà÷àìè èëè áóäeò äîñòèãíóò ïðåäåëüíûé äëÿ Oracle XE ðàçìåð áàçû, òî ïðåâåñòè çàäà÷è íà îäíó èç ïëàòíûõ âåðñèé Oracle íå ñîñòàâèò îñîáîãî òðóäà.  íàñòîÿùåå âðåìÿ ñóùåñòâóþò âåðñèè Oracle XE äëÿ ïëàòôîðì Linux (Debian, Mandriva, Novell, Red Hat è Ubuntu) è Windows. Oracle SQL*Plus ýòî óòèëèòà äëÿ îáðàáîòêè çàïðîñîâ íà ÿçûêå SQL è ñîçäàíèÿ òàêèõ êîìïîíåíòîâ, êàê õðàíèìûå ïðîöåäóðû è òðèããåðû (î íèõ áóäåò ñêàçàíî äàëåå â ãëàâå 4). Äàííàÿ óòèëèòà íåèçìåííî ïðèñóòñòâóåò âî âñåõ âàðèàíòàõ êîíôèãóðàöèè ïðîäóêòà. Ñ ïîìîùüþ SQL*Plus ìîæíî ïåðåäàâàòü Oracle êîìàíäû íà ÿçûêàõ SQL è PL/SQL. PL/SQL ýòî ÿçûê, 45
3.1. Óñòàíîâêà ORACLE 10G XE äëÿ WINDOWS
Ãëàâà 3. Óñòàíîâêà ORACLE
ðàñøèðÿþùèé âîçìîæíîñòè SQL çà ñ÷åò âêëþ÷åíèÿ â íåãî êîíñòðóêöèé, õàðàêòåðíûõ äëÿ ÿçûêîâ ïðîãðàììèðîâàíèÿ.
3.1
Óñòàíîâêà Oracle 10g XE äëÿ Windows
Äèñòðèáóòèâ Oracle 10g XE äëÿ Windows ñîñòîèò èç åäèíñòâåííîãî ôàéëà OracleXE*.exe, ÿâëÿþùåãîñÿ èíñòàëëÿòîðîì. Ñåãîäíÿ äîñòóïíî äâå ðàçíîâèäíîñòè Oracle XE âåðñèÿ äëÿ Çàïàäíîé Åâðîïû (áàçà äàííûõ â êîäèðîâêå 1252, èìÿ ôàéëà äèñòðèáóòèâà OracleXE.exe) è Unicode-âåðñèÿ (ñîîòâåòñòâåííî Unicode è OracleXEUniv.exe). Ïðîöåññ óñòàíîâêè ìàêñèìàëüíî óïðîùåí, íî, ê ñîæàëåíèþ, óïðàâëåíèå ýòèì ïðîöåññîì ïðàêòè÷åñêè íåâîçìîæíî. Áàçà äàííûõ è ïðîãðàììíûé êîä óñòàíàâëèâàþòñÿ â îäíó ïàïêó (êîòîðóþ ìîæíî çàäàòü) (ðèñ. 3.1), çàòåì òðåáóåòñÿ ââåñòè ïàðîëè äëÿ ïîëüçîâàòåëåé SYS è SYSTEM. Ñîáñòâåííî, íà ýòîì âñå íàñòðîéêè çàêàí÷èâàþòñÿ è íà÷èíàåòñÿ èíñòàëëÿöèÿ, êîòîðàÿ äëèòñÿ äâå-òðè ìèíóòû. Ïî çàâåðøåíèè èíñòàëëÿöèè ïðåäëàãàåòñÿ çàïóñòèòü áðàóçåð è ïåðåéòè íà ñòðàíèöó ìåíåäæåðà óïðàâëåíèÿ áàçîé äàííûõ. Õàðàêòåðíîé îñîáåííîñòüþ èíñòàëëÿòîðà ÿâëÿåòñÿ âîçìîæíîñòü óñòàíîâêè â ðåæèìå Silent Install, â êîòîðîì îò ïîëüçîâàòåëÿ íå òðåáóåòñÿ âçàèìîäåéñòâèå ñ èíñòàëëÿòîðîì. Ýòîò ðåæèì óñòàíîâêè óäîáåí â ñëó÷àå âêëþ÷åíèÿ Oracle XE â ñîñòàâ äèñòðèáóòèâà ñîáñòâåííîãî ïðîäóêòà. Ðåàëèçàöèÿ Silent Install îñíîâàíà íà ôàéëàõ îòâåòîâ äëÿ óñòàíîâêè, âîññòàíîâëåíèÿ è óäàëåíèÿ Oracle XE. Ýòè ôàéëû ìîæíî ñêà÷àòü ñ ñàéòà Oracle. Çàïóñê èíñòàëëÿòîðà ñ ôàéëîì îòâåòîâ ïðîèçâîäèòñÿ ïðè ïîìîùè êëþ÷åé êîìàíäíîé ñòðîêè:
OracleXE.exe /S /f1"<ôàéë îòâåòîâ> /f2"<èìÿ ôàéëà äëÿ ïðîòîêîëà èíñòàëëÿöèè> Â íàñòîÿùåå âðåìÿ íà ñàéòå Oracle äîñòóïíî òðè ôàéëà îòâåòîâ:
• OracleXE-install.iss äëÿ óñòàíîâêè Oracle. Íåîáõîäèìî îòðåäàêòèðîâàòü ýòîò ôàéë: â ïàðàìåòðå Dir ãðóïïû ¾*SdComponentDialog-0¿ íóæíî óêàçàòü ïóòü ê ïàïêå äëÿ óñòàíîâêè Oracle XE, â ïàðàìåòðå SYSPassword ãðóïïû ¾*AskSYSPassword-13011¿ ñëåäóåò óêàçàòü ïàðîëü ïîëüçîâàòåëÿ SYS (ïî óìîë÷àíèþ â ýòîì ôàéëå çàäàí ïàðîëü oraclexe); 46
Ãëàâà 3. Óñòàíîâêà ORACLE
3.1. Óñòàíîâêà ORACLE 10G XE äëÿ WINDOWS
Ðèñ. 3.1. Äèàëîãîâîå îêíî èíñòàëëÿòîðà Oracle 10g XE
• OracleXE-repair.iss âîññòàíîâëåíèå Oracle XE; • OracleXE-remove.iss óäàëåíèå Oracle XE âìåñòå ñ áàçîé äàííûõ. Ïåðåä óñòàíîâêîé ñëåäóåò óáåäèòüñÿ, ÷òî ïîðòû 1521/TCP è 8080/TCP íå èñïîëüçóþòñÿ äðóãèìè ïðèëîæåíèÿìè. Ïîðò 1521 ïî óìîë÷àíèþ èñïîëüçóåòñÿ ïðîñëóøèâàþùèì ïðîöåññîì (listener), à ïîðò 8080 ïðåäíàçíà÷åí äëÿ Web-èíòåðôåéñà. Èçìåíèòü íîìåð ïîðòîâ ìîæíî ïðè èíñòàëëÿöèè â àâòîìàòè÷åñêîì ðåæèìå: â ôàéëå OracleXE-install.iss íåîáõîäèìî çàäàòü ñïåöèôè÷åñêèå çíà÷åíèÿ íîìåðîâ ïîðòîâ ñ ïîìîùüþ ïàðàìåòðîâ TNSPort, MTSPort è HTTPPort. Êðîìå äàííûõ Oracle XE, äëÿ áåñïëàòíîé çàãðóçêè äîñòóïåí Oracleêëèåíò äëÿ Windows, óñòàíîâêà êîòîðîãî ìîæåò ïðîèçâîäèòüñÿ â ðó÷íîì è àâòîìàòè÷åñêîì ðåæèìàõ. 47
3.2. Óñòàíîâêà ORACLE 10G XE äëÿ LINUX
3.2
Ãëàâà 3. Óñòàíîâêà ORACLE
Óñòàíîâêà Oracle 10g XE äëÿ Linux
Ïîñëå çàãðóçêè äèñòðèáóòèâà â âèäå RPM-ïàêåòà, Oracle Database XE óñòàíàâëèâàåòñÿ òàê æå, êàê è ëþáîé äðóãîé RPM-ïàêåò èñïîëüçóÿ óòèëèòó RPM. Òàêèì îáðàçîì, óñòàíàâëèâàåòñÿ ïðîãðàììíîå îáåñïå÷åíèå è ïîëíîñòüþ ðàáîòîñïîñîáíàÿ áàçà äàííûõ. Äëÿ òîãî, ÷òîáû ïîäãîòîâèòü áàçó äàííûõ ê èñïîëüçîâàíèþ, íåîáõîäèìî âûïîëíèòü ñëåäóþùèå íåñëîæíûå äåéñòâèÿ (íåêîòîðûå íåçíà÷èòåëüíûå äåòàëè îïóùåíû):
# /etc/init.d/oracle-xe configureSpecify the HTTP port that will be used for HTML DB [8080]: Specify a port that will be used for the database listener [1521]: Specify a password to be used for database accounts: Do you want Oracle Database 10g Express Edition to be started on boot(y/n) [y]: Çà èñêëþ÷åíèåì ïàðîëÿ, êîòîðûé îáÿçàòåëüíî äîëæåí áûòü çàäàí, âñåì îñòàëüíûì ïàðàìåòðàì ìîæíî îñòàâèòü çíà÷åíèÿ ïî óìîë÷àíèþ. Íî, åñëè âû óæå èñïîëüçóåòå TCP/IP ïîðòû 8080 èëè 1521, âû ìîæåòå óêàçàòü àëüòåðíàòèâíûå çíà÷åíèÿ. Ïåðâûé ïîðò (HTTP port) ýòî ïîðò, íà êîòîðîì äîñòóïåí àäìèíèñòðàòèâíûé web-èíòåðôåéñ ê XE. Âòîðîé ïîðò ïîðò ïðîñëóøèâàþùåãî ïðîöåññà (Oracle Net listener), èñïîëüçóåìûé äëÿ ïîäêëþ÷åíèÿ ê áàçå äàííûõ ñ ëþáûõ ñèñòåì çà èñêëþ÷åíèåì òîé, íà êîòîðîé óñòàíîâëåíà XE. Ïîëíîñòüþ ïðîöåññ óñòàíîâêè îáû÷íî çàíèìàåò 10-15 ìèíóò.
3.3
Web-èíòåðôåéñ
Óïðàâëåíèå áàçîé äàííûõ ïðåäåëüíî ïðîñòî è ìîæåò îñóùåñòâëÿòüñÿ ÷åðåç Web-èíòåðôåéñ. Ïîäîáíûé ïîäõîä îáëåã÷àåò àäìèíèñòðèðîâàíèå, îñîáåííî â ñëó÷àå äèñòàíöèîííîãî óïðàâëåíèÿ ÷åðåç Èíòåðíåò.  òåêóùåé âåðñèè Oracle XE Web-èíòåðôåéñ ñîäåðæèò ÷åòûðå ãðóïïû èíñòðóìåíòîâ: Administration, Object Browser, SQL è Utilities (ðèñ. 3.2). Íàáîð ñðåäñòâ Administration ïðåäíàçíà÷åí äëÿ àäìèíèñòðèðîâàíèÿ è ìîíèòîðèíãà áàçû: 48
Ãëàâà 3. Óñòàíîâêà ORACLE
3.3. WEB-èíòåðôåéñ
Ðèñ. 3.2. Web-èíòåðôåéñ óïðàâëåíèÿ áàçîé
• Storage ïðîñìîòð èíôîðìàöèè î ôàéëàõ áàçû äàííûõ è òàáëè÷íûõ ïðîñòðàíñòâàõ; • Memory ïðîñìîòð ðàñïðåäåëåíèÿ ïàìÿòè ñ âîçìîæíîñòüþ íàñòðîéêè ðàçìåðà îáëàñòåé SGA (System Global Area) è PGA (Process Global Area); • Database Users èíñòðóìåíò äëÿ ïðîñìîòðà ñïèñêà ïîëüçîâàòåëåé áàçû äàííûõ ñ âîçìîæíîñòüþ ïðîñòåéøåãî àäìèíèñòðèðîâàíèÿ (ñîçäàíèå, óäàëåíèå, áëîêèðîâêà ó÷åòíîé çàïèñè, ñìåíà ïàðîëÿ, îñíîâíûå ïðèâèëåãèè); • Monitor ìîíèòîðèíã ýêçåìïëÿðà.  ÷àñòíîñòè, ìîæíî ïðîñìàòðè49
3.3. WEB-èíòåðôåéñ
Ãëàâà 3. Óñòàíîâêà ORACLE
âàòü ñïèñîê ñåññèé, áëîêèðîâîê è îòêðûòûõ êóðñîðîâ. Èç ñïèñêà ñåññèé ìîæíî âûçâàòü ñòðàíèöó ñ äåòàëèçèðîâàííîé èíôîðìàöèåé ïî êàæäîé ñåññèè. Íà ñòðàíèöå ñ äåòàëèçèðîâàííîé èíôîðìàöèåé èìååòñÿ êíîïêà äëÿ ïðèíóäèòåëüíîãî çàêðûòèÿ ñåññèè. Êðîìå òîãî, ïðåäóñìîòðåíû äîïîëíèòåëüíûå âèäû àíàëèçà, â òîì ÷èñëå ïîèñê íàèáîëåå ðåñóðñîåìêèõ çàïðîñîâ è îïåðàöèé, âûïîëíÿåìûõ äëèòåëüíîå âðåìÿ;
• About Database ïðîñìîòð íàñòðîåê ýêçåìïëÿðà. Èíñòðóìåíò Object Browser ÿâëÿåòñÿ áðàóçåðîì îáúåêòîâ áàçû äàííûõ, ïîçâîëÿþùèì ïðîñìàòðèâàòü ñóùåñòâóþùèå îáúåêòû â áàçå è ìàíèïóëèðîâàòü èìè. Âîçìîæíîñòè ýòîãî ñðåäñòâà äîñòàòî÷íî øèðîêè, ïðè÷åì áîëüøèíñòâî îïåðàöèé âûïîëíÿþòñÿ âèçóàëüíî, à îò ïîëüçîâàòåëÿ íå òðåáóåòñÿ çíàíèå ÿçûêà SQL. Ýòîò èíñòðóìåíò î÷åíü óäîáåí äëÿ íà÷èíàþùèõ, òàê êàê ïîçâîëÿåò âèçóàëüíî ñîçäàâàòü îáúåêòû âñåõ îñíîâíûõ òèïîâ.  èíñòðóìåíò SQL âõîäÿò ñðåäñòâà äëÿ âûïîëíåíèÿ SQL-êîìàíä:
• SQL Commands äëÿ âûïîëíåíèÿ ïðîèçâîëüíûõ SQL-îïåðàòîðîâ (ðèñ. 3.3). Ïî óìîë÷àíèþ ó ýòîãî èíñòðóìåíòà óñòàíîâëåí ïåðåêëþ÷àòåëü Autocommit, ÷òî ïðèâîäèò ê àâòîìàòè÷åñêîìó âûïîëíåíèþ COMMIT ïîñëå êàæäîé îïåðàöèè. Ïîëüçîâàòåëü ìîæåò ñîõðàíèòü ëþáóþ ââåäåííóþ êîìàíäó, ïðè÷åì ïðè ñîõðàíåíèè çàäàåòñÿ èìÿ è êðàòêîå îïèñàíèå. Ñîõðàíåííûå îïåðàòîðû ìîãóò áûòü âïîñëåäñòâèè çàãðóæåíû â ðåäàêòîð èç çàêëàäêè ¾Saved SQL¿.  ñëó÷àå âûïîëíåíèÿ çàïðîñà îòîáðàæàþòñÿ âîçâðàùàåìûå èì äàííûå è ïëàí âûïîëíåíèÿ çàïðîñà; • SQL Scripts ñðåäñòâî äëÿ ðàáîòû ñ SQL-ñêðèïòàìè, ïîçâîëÿþùåå ñîçäàâàòü è ðåäàêòèðîâàòü SQL-ñêðèïòû, ñîõðàíÿòü èõ ïîä çàäàííûìè èìåíàìè è âûïîëíÿòü. Ðåçóëüòàòû âûïîëíåíèÿ ñêðèïòîâ ñîõðàíÿþòñÿ è ìîãóò âïîñëåäñòâèè áûòü ïðîñìîòðåíû è ïðîàíàëèçèðîâàíû; • Query Builder âèçóàëüíûé ïîñòðîèòåëü çàïðîñîâ, ïðèíöèï ðàáîòû êîòîðîãî ÿâëÿåòñÿ ñòàíäàðòíûì äëÿ óòèëèò ïîäîáíîãî òèïà è íàïîìèíàåò ïîñòðîèòåëü çàïðîñîâ â Microsoft Access. Âèçóàëüíûé ïîñòðîèòåëü ïîçâîëÿåò çàäàâàòü ïðîñòåéøèå óñëîâèÿ ôèëüòðàöèè è ïðàâèëà ñîðòèðîâêè ïî êàæäîìó èç ïîëåé (ðèñ. 3.4). Ïîñëå çàâåðøåíèÿ âèçóàëüíîãî ïîñòðîåíèÿ çàïðîñà ìîæíî ïðîñìîòðåòü è ñêîïèðîâàòü ïîëó÷åííûé òåêñò SQL-çàïðîñà èëè âûïîëíèòü çàïðîñ è ïðîñìîòðåòü 50
Ãëàâà 3. Óñòàíîâêà ORACLE
3.3. WEB-èíòåðôåéñ
ðåçóëüòèðóþùèå äàííûå. Òàêîå âèçóàëüíîå ñðåäñòâî ìîæåò ïðåäñòàâëÿòü èíòåðåñ íå ñòîëüêî äëÿ ðàçðàáîò÷èêîâ, ñêîëüêî äëÿ ïîñòàíîâùèêîâ çàäà÷ è äëÿ ñïåöèàëèñòîâ, îòâå÷àþùèõ çà òåñòèðîâàíèå è òåõíè÷åñêóþ ïîääåðæêó ïðîäóêòà.
Ðèñ. 3.3. Âûïîëíåíèå çàïðîñà ê áàçå Èíñòðóìåíò Utilities ñîäåðæèò ðàçëè÷íûå óòèëèòû äëÿ ðàáîòû ñ áàçîé äàííûõ:
• ñòðàíèöà Data Load/Unload èíñòðóìåíòû äëÿ âûãðóçêè è çàãðóçêè äàííûõ. Ïîääåðæèâàåòñÿ ðàáîòà ñ òåêñòîâûìè äàííûìè (ðàçìåùåí51
3.4. Ðàáîòà ñ SQL*PLUS
Ãëàâà 3. Óñòàíîâêà ORACLE
Ðèñ. 3.4. Âèçóàëüíîå ïîñòðîåíèå çàïðîñà íûìè â òåêñòîâîì ôàéëå èëè êîïèðóåìûìè ÷åðåç áóôåð îáìåíà) è XML-ôàéëàìè;
• ñòðàíèöà Generate DDL èíñòðóìåíò ãåíåðàöèè DDL-ñêðèïòîâ äëÿ óêàçàííûõ îáúåêòîâ ñõåìû; • ñòðàíèöà Object Reports èíñòðóìåíòû äëÿ ãåíåðàöèè ðÿäà îò÷åòîâ, íåîáõîäèìûõ ïðè àäìèíèñòðèðîâàíèè è àíàëèçå áàçû äàííûõ.
3.4
Ðàáîòà ñ SQL*Plus
×òîáû çàïóñòèòü SQL*Plus, íàéäèòå çíà÷îê ýòîé ïðîãðàììû â ìåíþ Ïóñê I Ïðîãðàììû I Oracle Database 10g Express Edition I Run SQL Command Line è ùåëêíèòå íà íåì.  ðåçóëüòàòå âû äîëæíû óâèäåòü îêíî, ïîäîáíîå èçîáðàæåííîìó íà ðèñ. 3.5. 52
Ãëàâà 3. Óñòàíîâêà ORACLE
3.4. Ðàáîòà ñ SQL*PLUS
Ðèñ. 3.5. Ïðèãëàøåíèå SQL*Plus Äëÿ ñîåäèíåíèÿ ñ áàçîé äàííûõ íåîáõîäèìî â îòâåò íà ïðèãëàøåíèå SQL*Plus íàáðàòü
connect èìÿ ïîëüçîâàòåëÿ Åñëè óêàçàííûé ïîëüçîâàòåëü ñóùåñòâóåò â áàçå, òî äàëåå íåîáõîäèìî ââåñòè ïàðîëü. Äëÿ îïðåäåëåíèÿ èìåíè ïîëüçîâàòåëÿ è ïàðîëÿ íåîáõîäèìî îáðàòèòüñÿ ê àäìèíèñòðàòîðó áàçû äàííûõ. Åñëè âñå áûëî ñäåëàíî ïðàâèëüíî, òî ÑÓÁÄ ñîîáùèò îá óñïåøíîì ïðèñîåäèíåíèè ê áàçå äàííûõ (ðèñ. 3.6). 3.4.1
Áóôåð ñ SQL*Plus
Ñðåäè ìíîæåñòâà ôóíêöèé SQL*Plus åñòü è ôóíêöèÿ òåñòîâîãî ðåäàêòîðà. Ðàáîòà ñ Oracle ñòàíîâèòñÿ ïðîùå, åñëè çíàòü îá ýòèõ ôóíêöèÿõ. Êîãäà âû ââîäèòå ÷òî-òî ñ êëàâèàòóðû â SQL*Plus, ââîäèìûå âàìè ñèìâîëû ïîìåùàþòñÿ â áóôåð. Ïðè íàæàòèè êëàâèøè Enter SQL*Plus ñîõðàíÿåò òî, ÷òî âû ââåëè â âèäå ñòðîêè â áóôåðå è ïåðåõîäèò íà íîâóþ ñòðîêó, íî íå çàâåðøàåò îïåðàòîð è íå ïûòàåòñÿ åãî âûïîëíèòü. 53
3.4. Ðàáîòà ñ SQL*PLUS
Ãëàâà 3. Óñòàíîâêà ORACLE
Ðèñ. 3.6. Óñïåøíîå ñîåäèíåíèå ïîëüçîâàòåëÿ student ñ áàçîé äàííûõ Íà ðèñ. 3.7 ïîëüçîâàòåëü ââåë SQL-îïåðàòîð èç äâóõ ñòðîê. Ïðè íåîáõîäèìîñòè ïîëüçîâàòåëü ìîæåò ââåñòè áîëüøåå êîëè÷åñòâî ñòðîê. Êîãäà ïîëüçîâàòåëü ââîäèò òî÷êó ñ çàïÿòîé è íàæèìàåò Enter, SQL*Plus îòìå÷àåò êîíåö îïåðàòîðà è âûïîëíÿåò åãî. ×òîáû óâèäåòü ñîäåðæèìîå áóôåðà íåîáõîäèìî ââåñòè êîìàíäó LIST, êàê ïîêàçàíî â íèæíåé ÷àñòè ðèñ. 3.8. Ñòðîêà, ïîìå÷åííàÿ çâåçäî÷êîé, â äàííîì ñëó÷àå ñòðîêà 3 ÿâëÿåòñÿ òåêóùåé ñòðîêîé. ×òîáû ñäåëàòü òåêóùåé äðóãóþ ñòðîêó, ââåäèòå LIST è íîìåð ñòðîêè, íàïðèìåð LIST 1. ×òîáû èçìåíèòü ñîäåðæèìîå òåêóùåé ñòðîêè, ââåäèòå êîìàíäó
change /ñòðîêà1/ñòðîêà2/. Çäåñü ñòðîêà1 ýòî ïîñëåäîâàòåëüíîñòü ñèìâîëîâ, êîòîðóþ íóæíî çàìåíèòü, à ñòðîêà2 ïîñëåäîâàòåëüíîñòü ñèìâîëîâ, íà êîòîðóþ ïðîèçâîäèòñÿ çàìåíà. Ñëåäóåò îòìåòèòü, ÷òî â Oracle êîìàíäû, èìåíà ñòîëáöîâ, òàáëèö è ïðåäñòàâëåíèé, à òàêæå ïðî÷èå ýëåìåíòû áàçû äàííûõ íå ÷óâñòâèòåëüíû ê ðåãèñòðó. LIST ýòî òî æå ñàìîå, ÷òî è list. Åäèíñòâåííûé ñëó÷àé, êî54
Ãëàâà 3. Óñòàíîâêà ORACLE
3.4. Ðàáîòà ñ SQL*PLUS
Ðèñ. 3.7. Ìíîãîñòðî÷íûé áóôåð SQL*Plus ãäà ðåãèñòð èìååò çíà÷åíèå, âíóòðè êàâû÷åê â ñòðîêîâûõ âûðàæåíèÿõ. Òàê, âûðàæåíèÿ
SELECT * from ARTIST è
select * FROM artist èäåíòè÷íû. Íî âûðàæåíèÿ
SELECT * FROM ARTIST WHERE Name = 'Miro' è
SELECT * FROM ARTIST WHERE Name = 'MIRO' ÿâëÿþòñÿ ðàçëè÷íûìè. Ðåãèñòð âíóòðè êàâû÷åê âàæåí. 55
3.4. Ðàáîòà ñ SQL*PLUS
Ãëàâà 3. Óñòàíîâêà ORACLE
Ðèñ. 3.8. Èñïîëüçîâàíèå êîìàíäû LIST Åñòü òàêæå ðàçíèöà ìåæäó òî÷êîé ñ çàïÿòîé (;) è êîñîé ÷åðòîé (/). Òî÷êà ñ çàïÿòîé ÿâëÿåòñÿ ñèìâîëîì êîíöà îïåðàòîðà, à êîñàÿ ÷åðòà ïðåäïèñûâàåò Oracle âûïîëíèòü îïåðàòîðû, íàõîäÿùèåñÿ â áóôåðå. Åñëè èìååòñÿ òîëüêî îäèí îïåðàòîð è îòñóòñòâóåò íåîïðåäåëåííîñòü ïî ïîâîäó òîãî, ÷òî òðåáóåòñÿ ñäåëàòü, Oracle áóäåò èíòåðïðåòèðîâàòü òî÷êó ñ çàïÿòîé è êîñóþ ÷åðòó îäèíàêîâî. Òàê, â âûðàæåíèè
select * FROM user_tables; òî÷êà ñ çàïÿòîé îäíîâðåìåííî ñëóæèò ñèìâîëîì êîíöà îïåðàòîðà è çàñòàâëÿåò Oracle âûïîëíèòü ýòîò îïåðàòîð. 3.4.2
Èñïîëüçîâàíèå âíåøíåãî ðåäàêòîðà
Âîçìîæíîñòåé âñòðîåííîãî òåêñòîâîãî ðåäàêòîðà SQL*Plus âïîëíå õâàòàåò äëÿ âíåñåíèÿ íåáîëüøèõ èçìåíåíèé, íî ïðè ðåäàêòèðîâàíèè äëèííûõ âûðàæåíèé, òàêèõ êàê õðàíèìûå ïðîöåäóðû, îí ñòàíîâèòñÿ íåóäîáíûì. Â 56
Ãëàâà 3. Óñòàíîâêà ORACLE
3.5. Ñîçäàíèå òàáëèö
ñâÿçè ñ ýòèì â SQL*Plus ïðåäóñìîòðåíà âîçìîæíîñòü ðàáîòû ñ âíåøíèì òåêñòîâûì ðåäàêòîðîì. ×òîáû íàñòðîèòü SQL*Plus äëÿ ðàáîòû ñ âíåøíèì ðåäàêòîðîì (ïî óìîë÷àíèþ Áëîêíîò), íåîáõîäèìî ïðåæäå âñåãî ñîçäàòü ïàïêó äëÿ ðàáî÷èõ ôàéëîâ è óêàçàòü íà íåå SQL*Plus. Äëÿ ýòîãî íà çíà÷êå SQL*Plus íóæíî îòêðûòü äèàëîã Ñâîéñòâà (Properties) è ââåñòè èìÿ ñîçäàííîé ïàïêè â òåêñòîâîå ïîëå Ðàáî÷àÿ ïàïêà (Start In). Ïîñëå ýòîãî ïîÿâëÿåòñÿ âîçìîæíîñòü ñîçäàâàòü, ñîõðàíÿòü è ðåäàêòèðîâàòü ôàéëû âî âíîâü ñîçäàííîé ïàïêå. Äëÿ òîãî, ÷òîáû îòêðûòü ôàéë íà ðåäàêòèðîâàíèå, íåîáõîäèìî ââåñòè ñëåäóþùóþ êîìàíäó:
edit èìÿ_ôàéëà Çàïóñê îïåðàòîðîâ èç ôàéëà îñóùåñòâëÿåòñÿ ïî êîìàíäå
start èìÿ_ôàéëà èëè
@èìÿ_ôàéëà Ïî óìîë÷àíèþ äëÿ ôàéëîâ â SQL*Plus èñïîëüçóåòñÿ ðàñøèðåíèå .sql.
3.5
Ñîçäàíèå òàáëèö
Îïåðàòîðû, ñîçäàþùèå òàáëèöû áàçû äàííûõ íàøåãî ïðèìåðà, ïîêàçàíû â ëèñòèíãå 3.1. Ýòè îïåðàòîðû áûëè îôîðìëåíû â âèäå òåêñòîâîãî ôàéëà ïîä íàçâàíèåì create_tables.sql è çàòåì âûïîëíåíû èç êîìàíäíîé îáîëî÷êè SQL*Plus ïîñðåäñòâîì êîìàíäû start create_tables. Ëèñòèíã 3.1.
CREATE TABLE CUSTOMER( CustomerID int Name char(25) Street char(30) City char(35) State char(2) ZipPostalCode char(5)
NOT NULL, NOT NULL, NULL, NULL, NULL, NULL, 57
3.5. Ñîçäàíèå òàáëèö
Ãëàâà 3. Óñòàíîâêà ORACLE
Country varchar(50) NULL, AreaCode char(3) NULL, PhoneNumber char(8) NULL, Email varchar(100) NULL, CONSTRAINT CustomerPK PRIMARY KEY (CustomerID)); CREATE TABLE ARTIST( ArtistID int NOT NULL, Name char(25) NOT NULL, Nationality varchar(30) NULL, BirthDate numeric(4,0) NULL, DeceasedDate numeric(4,0) NULL, CONSTRAINT ArtistPK PRIMARY KEY (ArtistID), CONSTRAINT ArtistAK1 UNIQUE (Name), CONSTRAINT NationalityValues CHECK (Nationality IN ('Canadian', 'English', 'French', 'German', 'Mexican', 'Russian', 'Spanish', 'US')), CONSTRAINT BirthValuesCheck CHECK (BirthDate < DeceasedDate), CONSTRAINT ValidBirthYear CHECK ((BirthDate > 1000) AND (BirthDate < 2100)), CONSTRAINT ValidDeathYear CHECK ((DeceasedDate > 1000) AND (DeceasedDate < 2100))); CREATE TABLE CUSTOMER_ARTIST_INT( ArtistID int NOT NULL, CustomerID int NOT NULL, CONSTRAINT CustomerArtistPK PRIMARY KEY (ArtistID, CustomerID), CONSTRAINT Customer_Artist_Int_ArtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID) ON DELETE CASCADE, CONSTRAINT Customer_Artist_Int_CustomerFK FOREIGN KEY (CustomerID) REFERENCES CUSTOMER (CustomerID) 58
Ãëàâà 3. Óñòàíîâêà ORACLE
3.5. Ñîçäàíèå òàáëèö
ON DELETE CASCADE); CREATE TABLE WORK( WorkID int NOT NULL, Title varchar(25) NOT NULL, Description varchar(1000) NULL, Copy varchar(8) NOT NULL, ArtistID int NOT NULL, CONSTRAINT WorkPK PRIMARY KEY (WorkID), CONSTRAINT WorkAK1 UNIQUE (Title, Copy), CONSTRAINT ArtistFK FOREIGN KEY (ArtistID) REFERENCES ARTIST (ArtistID)); CREATE TABLE TRANSACTION( TransactionID int NOT NULL, DateAcquired Date NOT NULL, AcquisitionPrice Numeric(8,2) NULL, PurchaseDate Date NULL, SalesPrice Numeric(8,2) NULL, AskingPrice Numeric(8,2) NULL, CustomerID int NULL, WorkID int NOT NULL, CONSTRAINT TransactionPK PRIMARY KEY (TransactionID), CONSTRAINT SalesPriceRange CHECK ((SalesPrice > 1000) AND (SalesPrice <= 200000)), CONSTRAINT ValidTransDate CHECK (DateAcquired <= PurchaseDate), CONSTRAINT TransactionWorkFK FOREIGN KEY (WorkID) REFERENCES WORK (WorkID), CONSTRAINT TransactionCustomerFK 59
3.5. Ñîçäàíèå òàáëèö
Ãëàâà 3. Óñòàíîâêà ORACLE
FOREIGN KEY (CustomerID) REFERENCES CUSTOMER (CustomerID)); Âûïîëíèâ ýòè îïåðàòîðû, ìîæíî ïðîâåðèòü ñîñòîÿíèå òàáëèö ñ ïîìîùüþ êîìàíäû DESCRIBE. Íà ðèñ. 3.9 ïîêàçàíî èñïîëüçîâàíèå êîìàíäû DESCRIBE äëÿ òàáëèöû CUSTOMER. Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî ìîæíî èñïîëüçîâàòü äâå ôîðìû ýòîé êîìàíäû: DESCRIBE è DESC.
Ðèñ. 3.9. Èñïîëüçîâàíèå êîìàíäû DESCRIBE Âñå òàáëèöû áàçû äàííûõ ðàññìàòðèâàåìîãî ïðèìåðà, çà èñêëþ÷åíèåì CUSTOMER_ARTIST_INT, èìåþò ñóððîãàòíûå êëþ÷è. Oracle íå ïîçâîëÿåò íàïðÿìóþ îïðåäåëÿòü ñóððîãàòíûå êëþ÷è. Âìåñòî ýòîãî íåîáõîäèìî èñïîëüçîâàòü òàê íàçûâàåìûå ïîñëåäîâàòåëüíîñòè. 3.5.1
Ñîçäàíèå ñóððîãàòíûõ êëþ÷åé ñ ïîìîùüþ ïîñëåäîâàòåëüíîñòåé
(sequence) ýòî îáúåêò, êîòîðûé ãåíåðèðóåò ðÿä ïîñëåäîâàòåëüíûõ óíèêàëüíûõ ÷èñåë. Ñëåäóþùèé îïåðàòîð îïðåäåëÿåò ïîñëåäîâàòåëüíîñòü ïîä íàçâàíèåì CustID, êîòîðàÿ íà÷èíàåòñÿ ñ 100 è óâåëè÷èâàåòñÿ íà 1 ïðè êàæäîì èñïîëüçîâàíèè: Ïîñëåäîâàòåëüíîñòü
60
Ãëàâà 3. Óñòàíîâêà ORACLE
3.5. Ñîçäàíèå òàáëèö
Create Sequence CustID Increment by 1 start with 100; Äëÿ íàñ ÿâëÿþòñÿ âàæíûìè äâà ìåòîäà ïîñëåäîâàòåëüíîñòåé. Ìåòîä NextVal âûäàåò ñëåäóþùåå çíà÷åíèå â ïîñëåäîâàòåëüíîñòè, à ìåòîä CurrVal âûäàåò òåêóùåå çíà÷åíèå â ïîñëåäîâàòåëüíîñòè. Òàê, CustID.NextVal âûäàåò ñëåäóþùåå çíà÷åíèå â ïîñëåäîâàòåëüíîñòè CustID. Ñ ïîìîùüþ ïîñëåäîâàòåëüíîñòè ìîæíî âñòàâèòü ñòðîêó â òàáëèöó CUSTOMER, êàê ïîêàçàíî íèæå:
INSERT INTO CUSTOMER (CustomerID, Name, AreaCode, PhoneNumber) VALUES (CustID.NextVal, 'Mary Jones', '350', '555-1234'); Ýòîò îïåðàòîð ñîçäàñò â òàáëèöå CUSTOMER ñòðîêó, ãäå ñòîëáöó CustomerID áóäåò ïðèñâîåíî ñëåäóþùåå çíà÷åíèå â ïîñëåäîâàòåëüíîñòè CustID. Ê ñîæàëåíèþ, èñïîëüçîâàíèå ïîñëåäîâàòåëüíîñòåé íå ãàðàíòèðóåò êîððåêòíîñòü çíà÷åíèé ñóððîãàòíûõ êëþ÷åé. Âî-ïåðâûõ, ëþáîé ðàçðàáîò÷èê ìîæåò èñïîëüçîâàòü ñóùåñòâóþùóþ ïîñëåäîâàòåëüíîñòü äëÿ ïðîèçâîëüíûõ öåëåé. Åñëè ïîñëåäîâàòåëüíîñòü èñïîëüçóåòñÿ äëÿ êàêèõ-ëèáî èíûõ öåëåé, íåæåëè ãåíåðàöèÿ ñóððîãàòíûõ êëþ÷åé, íåêîòîðûå çíà÷åíèÿ â íåé áóäóò ïðîïóùåíû. Âòîðàÿ, áîëåå ñåðüåçíàÿ ïðîáëåìà çàêëþ÷àåòñÿ â òîì, ÷òî â ñõåìå íåò íè÷åãî, ÷òî çàïðåùàëî áû âûïîëíèòü âñòàâêó áåç èñïîëüçîâàíèÿ ïîñëåäîâàòåëüíîñòè. Òàê, Oracle ïðèìåò áåç âîçðàæåíèé îïåðàòîð
INSERT INTO CUSTOMER (CustomerID, Name, AreaCode, PhoneNumber) VALUES (324, 'Mary Jones', '350', '555-1234'); Âîçìîæíî, ÷òî âûïîëíåíèå ýòîãî îïåðàòîðà ïðèâåäåò ê ïîÿâëåíèþ îäèíàêîâûõ çíà÷åíèé ñóððîãàòíîãî êëþ÷à.  ýòîì ñëó÷àå Oracle íå ïîçâîëèò âûïîëíèòü âñòàâêó, ïîñêîëüêó àòðèáóò CustomerID îïðåäåëåí êàê ïåðâè÷íûé êëþ÷. Ñëåäîâàòåëüíî, âîçíèêàåò ïîòðåáíîñòü â êîäå, êîòîðûé áû îáðàáàòûâàë ýòó èñêëþ÷èòåëüíóþ ñèòóàöèþ. Íàêîíåö, åñòü âåðîÿòíîñòü, ÷òî êòî-òî ñëó÷àéíî èñïîëüçóåò íå òó ïîñëåäîâàòåëüíîñòü äëÿ âñòàâêè â òàáëèöó. 61
3.5. Ñîçäàíèå òàáëèö
Ãëàâà 3. Óñòàíîâêà ORACLE
Íåñìîòðÿ íà âîçìîæíîñòü òàêèõ ïðîáëåì, ïîñëåäîâàòåëüíîñòè ïðåäñòàâëÿþò ñîáîé ëó÷øèé ñïîñîá ðàáîòû ñ ñóððîãàòíûìè êëþ÷àìè â Oracle. 3.5.2
Ââîä äàííûõ
Òåïåðü ñ ïîìîùüþ ïîñëåäîâàòåëüíîñòåé åñòü âîçìîæíîñòü çàïîëíÿòü òàáëèöû äàííûìè. Â ëèñòèíãå 3.2 ïîêàçàí ñîçäàííûé âî âíåøíåì ðåäàêòîðå ôàéë, ñîñòîÿùèé èç ïîñëåäîâàòåëüíîñòè îïåðàòîðîâ INSERT. Ëèñòèíã 3.2.
INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal, INSERT INTO ARTIST (ArtistID.NextVal,
VALUES 'Miro', 'Spanish', 1870, 1950); VALUES 'Kandinsky', 'Russian', 1854, 1900); VALUES 'Frings', 'US', 1700, 1800); VALUES 'Klee', 'German', 1900, NULL); VALUES 'Moos', 'US', NULL, NULL); VALUES 'Tobey', 'US', NULL, NULL); VALUES 'Matisse', 'French', NULL, NULL); VALUES 'Chagall', 'French', NULL, NULL);
INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Jeffrey Janes', '123 W. Elm St', 'Renton', 'WA', '98123', 'USA', '206', '555-1345', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'David Smith', '813 Tumbleweed Lane', 'Loveland', 'CO', '80345', 'USA', '303', '555-5434', '[email protected]'); 62
Ãëàâà 3. Óñòàíîâêà ORACLE
3.5. Ñîçäàíèå òàáëèö
INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Tiffany Twilight', '88 - First Avenue', 'Langley', 'WA', '98114', 'USA', '206', '555-1000', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Fred Smathers', '10899-88th Ave', 'Bainbridge Island', 'WA', '98108', 'USA', '206', '555-1234', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Mary Beth Frederickson', '25 South Lafayette', 'Denver', 'CO', '80210', 'USA', '303', '555-1000', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Selma Warning', '205 Burnaby', 'Vancouver', 'BC', 'VON1B', 'Canada', '253', '555-1234', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Susan Wu', '105 Locust Ave', 'Atlanta', 'GA', '23224', 'USA', '721', '555-1234', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Donald G. Gray', '55 Bodega Ave', 'Bodega Bay', 'CA', '92114', 'USA', '705', '555-1345', '[email protected]'); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Lynda Johnson', '117 C Street', 'Washington', 'DC', '11345', 'USA', '703', '555-1000', ''); INSERT INTO CUSTOMER VALUES (CustID.NextVal, 'Chris Wilkens', '87 Highland Drive', 'Olympia', 'WA', '98008', 'USA', '206', '555-1234', '');
63
3.5. Ñîçäàíèå òàáëèö
3.5.3
Ãëàâà 3. Óñòàíîâêà ORACLE
Îïåðàòîðû DROP è ALTER
Ñ ïîìîùüþ îïåðàòîðà DROP ìîæíî óäàëÿòü ðàçëè÷íûå ñòðóêòóðû èç áàçû äàííûõ. Íàïðèìåð, îïåðàòîðû
DROP TABLE MyTable; DROP SEQUENCE MySequence; óäàëÿò èç áàçû äàííûõ òàáëèöó MyTable è ïîñëåäîâàòåëüíîñòü MySequence. Âñå äàííûå èç òàáëèöû MyTable áóäóò ïîòåðÿíû. Ñ ïîìîùüþ îïåðàòîðà DROP ìîæíî òàêæå óäàëèòü ñòîëáåö èç òàáëèöû, êàê ïîêàçàíî íèæå:
ALTER TABLE MyTable DROP COLUMN MyColumn; 3.5.4
Ââîä äàííûõ òèïà DATE
Ââîä äàííûõ â ñòîëáöû, èìåþùèå òèï äàííûõ DATE, ìîæåò ïðåäñòàâëÿòü ïðîáëåìó â Oracle. Oracle òðåáóåò, ÷òîáû äàòû ââîäèëèñü â îïðåäåëåííîì ôîðìàòå, íî èíîãäà áûâàåò òðóäíî îïðåäåëèòü, â êàêîì èìåííî. Â ýòîé ñèòóàöèè íà ïîìîùü ìîæåò ïðèéòè ôóíêöèÿ TO_DATE. Ýòà ôóíêöèÿ ïðèíèìàåò äâà ïàðàìåòðà, êàê ïîêàçàíî íèæå:
TO_DATE('11/12/2002', 'MM/DD/YYYY') Ïåðâûé ïàðàìåòð ýòî çíà÷åíèå äàòû, à âòîðîé øàáëîí, êîòîðûé äîëæåí èñïîëüçîâàòüñÿ äëÿ èíòåðïðåòàöèè ýòîãî çíà÷åíèÿ.  äàííîì ïðèìåðå ÷èñëî 11 óêàçûâàåò ìåñÿö, à 12 äåíü ìåñÿöà. Ôóíêöèþ TO_DATE ìîæíî èñïîëüçîâàòü â îïåðàòîðå INSERT äëÿ çàïèñè äàòû âî âíîâü ñîçäàâàåìûå ñòðîêè. Ïóñòü, íàïðèìåð, òàáëèöà T1 èìååò äâà ñòîëáöà, A è B, ãäå A èìååò òèï INT, à B DATE. Òîãäà íîâóþ ñòðîêó â òàáëèöó T1 ìîæíî âñòàâèòü ñ ïîìîùüþ ñëåäóþùåãî îïåðàòîðà:
INSERT INTO T1 VALUES (100, TO_DATE('05/01/2007', 'MM/DD/YYYY')); Ðåçóëüòàòîì áóäåò ñòðîêà, ñîäåðæàùàÿ çíà÷åíèå 100 è äàòó 1 ìàÿ 2007 ãîäà â ôîðìàòå Oracle. Ôóíêöèþ TO_DATE ìîæíî òàêæå èñïîëüçîâàòü â îïåðàòîðàõ UPDATE. 64
Ãëàâà 3. Óñòàíîâêà ORACLE
3.6
3.6. Ñîçäàíèå èíäåêñîâ
Ñîçäàíèå èíäåêñîâ
Èíäåêñû ñîçäàþòñÿ äëÿ îáåñïå÷åíèÿ óíèêàëüíîñòè ñòîëáöîâ, óïðîùåíèÿ ñîðòèðîâêè è áûñòðîãî ïîèñêà äàííûõ ïî çíà÷åíèÿì ñòîëáöîâ. Ñòîëáöû, êîòîðûå ÷àñòî ôèãóðèðóþò â óñëîâèÿõ ðàâåíñòâà â ïðåäëîæåíèÿõ WHERE, ÿâëÿþòñÿ õîðîøèìè êàíäèäàòàìè íà ñîçäàíèå èíäåêñà. Óñëîâèÿ ðàâåíñòâà ìîãóò îòíîñèòüñÿ ê îäíîé òàáëèöå èëè æå ê ñîåäèíåíèþ. Ýòè äâà ñëó÷àÿ ïðåäñòàâëåíû â ñëåäóþùèõ ïðèìåðàõ:
SELECT * FROM MyTable WHERE Column1 = 100; è
SELECT * FROM MyTable1, MyTable2 WHERE MyTable1.Column1 = MyTable2.Column2; Åñëè ïîäîáíûå îïåðàòîðû âûïîëíÿþòñÿ ÷àñòî, òî ñòîëáöû Column1 è Column2 ÿâëÿþòñÿ ïåðñïåêòèâíûìè êàíäèäàòàìè íà ñîçäàíèå èíäåêñîâ. Ñëåäóþùèé îïåðàòîð ñîçäàåò èíäåêñ ïî ñòîëáöó Name òàáëèöû CUSTOMER:
CREATE INDEX CustNameIdx ON CUSTOMER(Name); Èíäåêñó äàíî èìÿ CustNameIdx. È çäåñü èìÿ íå èãðàåò îñîáîé ðîëè äëÿ Oracle. ×òîáû ñîçäàòü óíèêàëüíûé èíäåêñ, ïåðåä êëþ÷åâûì ñëîâîì INDEX íóæíî âñòàâèòü êëþ÷åâîå ñëîâî UNIQUE. Íàïðèìåð, ÷òîáû ãàðàíòèðîâàòü, ÷òî íè îäíî ïðîèçâåäåíèå íå áóäåò çàïèñàíî äâàæäû â òàáëèöó WORK, ìîæíî ñîçäàòü óíèêàëüíûé èíäåêñ ïî ñòîëáöàì (Title, Copy, ArtistID), êàê ïîêàçàíî íèæå:
CREATE UNIQUE INDEX WorkUniqueIndex ON WORK(Title, Copy, ArtistID); 65
3.7. Èçìåíåíèå ñòðóêòóðû òàáëèöû
3.7
Ãëàâà 3. Óñòàíîâêà ORACLE
Èçìåíåíèå ñòðóêòóðû òàáëèöû
Ïîñëå ñîçäàíèÿ òàáëèöû åå ñòðóêòóðó ìîæíî èçìåíÿòü ñ ïîìîùüþ îïåðàòîðà ALTER TABLE. Íåîáõîäèìà íåêîòîðàÿ îñòîðîæíîñòü ñ ýòèì îïåðàòîðîì, ïîñêîëüêó ïðè åãî èñïîëüçîâàíèè âîçìîæíà ïîòåðÿ äàííûõ. Äîáàâëåíèå èëè óäàëåíèå ñòîëáöà îñóùåñòâëÿåòñÿ ïðîñòî:
ALTER TABLE MyTable ADD C1 NUMBER(4); ALTER TABLE MyTable DROP COLUMN C1; Ïåðâûé îïåðàòîð äîáàâëÿåò ñòîëáåö ñ èìåíåì C1 è ïðèñâàèâàåò åìó òèï ÷èñëà äëèíîé ÷åòûðå ñèìâîëà. Âòîðîé îïåðàòîð óäàëÿåò òîëüêî ÷òî ñîçäàííûé ñòîëáåö. Îáðàòèòå âíèìàíèå, ÷òî ïðè ñîçäàíèè ñòîëáöà êëþ÷åâîå ñëîâî COLUMN îïóñêàåòñÿ. ×òîáû óáåäèòüñÿ â òîì, ÷òî æåëàåìûå èçìåíåíèÿ äåéñòâèòåëüíî áûëè ïðîèçâåäåíû, ïîñìîòðèòå ñòðóêòóðó òàáëèöû ñ ïîìîùüþ îïåðàòîðà DESCRIBE. Ñòîëáåö ìîæíî óäàëèòü â ëþáîé ìîìåíò. Ïðè ýòîì, îäíàêî, âñå äàííûå èç ýòîãî ñòîëáöà áóäóò ïîòåðÿíû. Òàêæå â ëþáîé ìîìåíò ìîæíî äîáàâèòü ïóñòîé, èëè íåîáÿçàòåëüíûé (NULL), ñòîëáåö. ×òîáû äîáàâèòü îáÿçàòåëüíûé (NOT NULL) ñòîëáåö, ñíà÷àëà íóæíî ñîçäàòü åãî â òàáëèöå êàê íåîáÿçàòåëüíûé, çàïîëíèòü âñå åãî ñòðîêè äàííûìè, à çàòåì îáúÿâèòü åãî îáÿçàòåëüíûì ïðè ïîìîùè êîíñòðóêöèè MODIFY. Ïðåäïîëîæèì, íàïðèìåð, ÷òî äîáàâëÿåòñÿ ñòîëáåö C1 â òàáëèöó T1. Ïîñëå òîãî êàê ýòîò ñòîëáåö áóäåò çàïîëíåí â êàæäîé ñòðî÷êå òàáëèöû T1, ìîæíî âûïîëíèòü ñëåäóþùèé îïåðàòîð:
ALTER TABLE T1 MODIFY C1 NOT NULL; Òåïåðü ñòîëáåö C1 áóäåò îáÿçàòåëüíî òðåáîâàòü ïðèñâîåíèÿ çíà÷åíèÿ. Ïðè ìîäèôèêàöèè ñòîëáöà ìîæíî óâåëè÷èâàòü êîëè÷åñòâî ñèìâîëîâ â òåêñòîâûõ ñòîëáöàõ è êîëè÷åñòâî öèôð â ÷èñëîâûõ ñòîëáöàõ. Òàêæå ìîæíî ñâîáîäíî óâåëè÷èâàòü èëè óìåíüøàòü êîëè÷åñòâî öèôð ïîñëå äåñÿòè÷íîé òî÷êè. Åñëè äàííûé ñòîëáåö ÿâëÿåòñÿ ïóñòûì âî âñåõ ñòðîêàõ, ìîæíî óìåíüøàòü äëèíó òåêñòîâûõ è ÷èñëîâûõ äàííûõ, à òàêæå ìåíÿòü òèï äàííûõ ñòîëáöà. 66
Ãëàâà 3. Óñòàíîâêà ORACLE
3.8
3.8. Ó÷åòíûå çàïèñè è ðîëè
Ó÷åòíûå çàïèñè è ðîëè
Êàæäàÿ áàçà Oracle ñ ìîìåíòà ñâîåãî ñîçäàíèÿ ñîäåðæèò äâå ñõåìû (ñëåäóåò îòìåòèòü, ÷òî òåðìèíû ¾ó÷åòíàÿ çàïèñü¿, ¾ñõåìà¿ è ¾ïîëüçîâàòåëü¿ îáîçíà÷àþò â Oracle îäíî è òî æå) SYS è SYSTEM. Ñõåìà SYS ñîäåðæèò âñå ñèñòåìíûå îáúåêòû âíóòðåííèå òàáëèöû áàçû äàííûõ, ïàêåòû, ïðîöåäóðû. Êðîìå òîãî, ïîëüçîâàòåëü SYS ÿâëÿåòñÿ âëàäåëüöåì ñëîâàðÿ äàííûõ. Ñëîâàðü äàííûõ Oracle ýòî ñîâîêóïíîñòü òàáëèö è ïðåäñòàâëåíèé, ïîçâîëÿþùèõ ïîëó÷èòü ëþáóþ èíôîðìàöèþ î ñòðóêòóðå áàçû äàííûõ, î åå íàñòðîéêàõ è ñîñòîÿíèè ïðè ïîìîùè ñòàíäàðòíûõ SQL-çàïðîñîâ. Ó÷åòíàÿ çàïèñü SYS ÿâëÿåòñÿ òàêæå ó÷åòíîé çàïèñüþ àäìèíèñòðàòîðà áàçû äàííûõ ñ íåîãðàíè÷åííûìè ïîëíîìî÷èÿìè. Ó÷åòíàÿ çàïèñü SYSTEM ïðåäîñòàâëÿåò äîñòóï êî âñåì îáúåêòàì áàçû è íàäåëåíà ðîëüþ DBA. Ïðè ðàáîòå ñ ó÷åòíûìè çàïèñÿìè SYS è SYSTEM íåîáõîäèìî ñîáëþäàòü ðÿä ïðàâèë:
• ðàçðàáîòêà â áàçå äàííûõ íå äîëæíà âåñòèñü îò èìåíè ïîëüçîâàòåëåé SYS è SYSTEM; • íåëüçÿ óäàëÿòü èëè èçìåíÿòü ñèñòåìíûå îáúåêòû, ðàçìåùåííûå â ýòèõ ñõåìàõ, ïîäîáíûå äåéñòâèÿ ìîãóò ïðèâåñòè ê íåïðåäñêàçóåìûì ïîñëåäñòâèÿì; • ó ó÷åòíûõ çàïèñåé SYS è SYSTEM äîëæíû áûòü çàäàíû ñëîæíû óñòîé÷èâûå ê ïîäáîðó ïàðîëè äëèíîé íå ìåíåå 6-8 ñèìâîëîâ.  ñëó÷àå íåîáõîäèìîñòè ìîæíî âîîáùå çàïðåòèòü ðåãèñòðàöèþ ïîëüçîâàòåëåé ïîä ó÷åòíûìè çàïèñÿìè SYS è SYSTEM. Ðîëè â Oracle ýòî èìåíîâàííûå ãðóïïû ïðèâèëåãèé. Ïîñëå ñîçäàíèÿ áàçû äàííûõ â íåé ñîçäàåòñÿ íåñêîëüêî ñòàíäàðòíûõ ðîëåé:
• ðîëü CONNECT ñîäåðæèò òîëüêî îäíó ïðèâèëåãèþ CREATE SESSION, ïîçâîëÿþùóþ ñîçäàâàòü ñîåäèíåíèå ñ áàçîé; • ðîëü DBA ïîëíûé íàáîð ïðèâèëåãèé, íåîáõîäèìûõ àäìèíèñòðàòîðó áàçû; • ðîëü RESOURCE áàçîâûé íàáîð ïðèâèëåãèé, íåîáõîäèìûõ ðàçðàáîò÷èêó; 67
3.9. Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
Ãëàâà 3. Óñòàíîâêà ORACLE
• ðîëü DELETE_CATALOG_ROLE ïðèâèëåãèè äëÿ óäàëåíèÿ èíôîðìàöèè èç òàáëèöû àóäèòà; • ðîëü SELECT_CATALOG_ROLE ïðèâèëåãèè äëÿ ÷òåíèÿ èíôîðìàöèè èç òàáëèö àóäèòà; • ðîëü EXP_FULL_DATABASE íåîáõîäèìà ïîëüçîâàòåëþ, èç-ïîä ó÷åòíîé çàïèñè êîòîðîãî áóäåò ïðîèçâîäèòüñÿ ïîëíûé ýêñïîðò áàçû; • ðîëü IMP_FULL_DATABASE íåîáõîäèìà ïîëüçîâàòåëþ, èç-ïîä ó÷åòíîé çàïèñè êîòîðîãî áóäåò ïðîèçâîäèòüñÿ ïîëíûé èìïîðò áàçû.
3.9
Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
Îïåðàöèè ðåçåðâíîãî êîïèðîâàíèÿ è âîññòàíîâëåíèÿ â Oracle ìîæíî ðàçäåëèòü íà òðè âèäà:
• ëîãè÷åñêîå ðåçåðâíîå êîïèðîâàíèå ïðîèçâîäèòñÿ ïðè ïîìîùè âõîäÿùåé â ñîñòàâ Oracle óòèëèòû exp, êîòîðàÿ ïîçâîëÿåò ýêñïîðòèðîâàòü âñþ áàçó, çàäàííûå ñõåìû èëè òàáëèöû.  ñëó÷àå ýêñïîðòà âñåé áàçû âûïîëíÿåòñÿ òàê íàçûâàåìûé ïîëíûé ýêñïîðò (ïðè ýòîì ýêñïîðòèðóþòñÿ âñå òàáëèöû áàçû äàííûõ) èëè èíêðåìåíòíûé (âûãðóæàþòñÿ òàáëèöû, èçìåíèâøèåñÿ ñ ìîìåíòà ïîñëåäíåãî ýêñïîðòà). Äëÿ Oracle 10g XE, â êîòîðîì îáúåì áàçû íå ïðåâûøàåò 4 Ãáàéò, ìîæíî ïîëüçîâàòüñÿ ïîëíûì ýêñïîðòîì; • ôèçè÷åñêîå ðåçåðâíîå êîïèðîâàíèå âûïîëíÿåòñÿ ïîñëå îñòàíîâêè áàçû è ïðåäïîëàãàåò êîïèðîâàíèå ôàéëîâ äàííûõ, óïðàâëÿþùèõ ôàéëîâ, îïåðàòèâíûõ æóðíàëîâ ïîâòîðà è ôàéëà init.ora ñ íàñòðîéêàìè áàçû; • îïåðàòèâíîå ðåçåðâíîå êîïèðîâàíèå îñóùåñòâëÿåòñÿ â áàçå, ôóíêöèîíèðóþùåé â ðåæèìå ARCHIVELOG.  ýòîì ðåæèìå ïðîèçâîäèòñÿ àðõèâàöèÿ îïåðàòèâíûõ æóðíàëîâ ïîâòîðà è âåäåòñÿ æóðíàë âñåõ òðàíçàêöèé. Äëÿ íåáîëüøèõ ó÷åáíûõ áàç äàííûõ íàèáîëåå ïðîñòûì è íàäåæíûì ÿâëÿåòñÿ ïîëíîå ëîãè÷åñêîå ðåçåðâíîå êîïèðîâàíèå è ôèçè÷åñêîå ðåçåðâíîå êîïèðîâàíèå. Ëîãè÷åñêîå ðåçåðâíîå êîïèðîâàíèå 68
Ãëàâà 3. Óñòàíîâêà ORACLE
3.9. Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
âûïîëíÿåòñÿ ïðè ïîìîùè óòèëèòû exp.exe, ðàçìåùåííîé â ïàïêå oraclexe\app\oracle\product\10.2.0\server\BIN\. Óòèëèòà ÿâëÿåòñÿ êîíñîëüíûì ïðèëîæåíèåì, ïîëó÷àþùèì ïàðàìåòðû ÷åðåç êîìàíäíóþ ñòðîêó. Ïîñêîëüêó ïàðàìåòðîâ îáû÷íî áûâàåò ìíîãî (5-10 øòóê), óäîáíî ñîçäàòü ïðîôèëü ñ ïàðàìåòðàìè è çàòåì ïåðåäàòü åãî óòèëèòå ýêñïîðòà ïðè ïîìîùè ïàðàìåòðà parle. Ðàññìîòðèì ïðèìåð òèïîâûõ ïðîôèëåé. Äëÿ íà÷àëà ðåøèì íàèáîëåå ðàñïðîñòðàíåííóþ çàäà÷ó ñîçäàíèå ðåçåðâíîé êîïèè îäíîé èëè íåñêîëüêèõ ñõåì.  êà÷åñòâå ïðèìåðà ðàññìîòðèì êîïèðîâàíèå ñõåìû STUDENT ñ ó÷åáíûì ïðèìåðîì. Äëÿ ýòîãî ñîçäàäèì òåêñòîâûé ôàéë exp_stud.prm, ñîäåðæàùèé ñëåäóþùèå ñòðîêè:
USERID = èìÿ/ïàðîëü LOG = ora10stud.log FILE = ora10stud.dmp OWNER= STUDENT Çàòåì ïðîèçâåäåì ýêñïîðò, âûïîëíèâ êîìàíäó exp parle=exp_stud.prm, â ðåçóëüòàòå ÷åãî áóäåò ñîçäàí ôàéë ora10stud.dmp, ñîäåðæàùèé ðåçåðâíóþ êîïèþ ñõåìû STUDENT. Ýòîò ôàéë èìååò áèíàðíûé ôîðìàò è î÷åíü õîðîøî ñæèìàåòñÿ ëþáûì àðõèâàòîðîì, ïîýòîìó äëÿ àâòîìàòèçàöèè ïðîöåäóðû ðåçåðâíîãî êîïèðîâàíèÿ óäîáíî ñîçäàòü BATôàéë, ñîäåðæàùèé êîìàíäó ýêñïîðòà è âûçîâ àðõèâàòîðà äëÿ ñæàòèÿ ïîëó÷åííîãî äàìïà.  íàøåì ñëó÷àå ïàðàìåòð USERID ñîäåðæèò èìÿ è ïàðîëü äëÿ äîñòóïà ê áàçå äàííûõ, ïàðàìåòð LOG çàäàåò èìÿ ôàéëà, â êîòîðûé çàïèñûâàåòñÿ ïðîòîêîë ðàáîòû, ïàðàìåòð FILE çàäàåò èìÿ ôàéëà ðåçåðâíîé êîïèè, OWNER îäíà èëè íåñêîëüêî ýêñïîðòèðóåìûõ ñõåì (åñëè óêàçûâàåòñÿ íåñêîëüêî ñõåì, òî îíè ïåðå÷èñëÿþòñÿ ÷åðåç çàïÿòóþ). Äëÿ âûïîëíåíèÿ ïîëíîãî ýêñïîðòà ïðîôèëü íåìíîãî èçìåíèòñÿ:
USERID = èìÿ/ïàðîëü LOG = ora10full.log FILE = ora10full.dmp FULL = Y Âàæíûì ìîìåíòîì ÿâëÿåòñÿ òî, ÷òî ýêñïîðò êîíêðåòíîé ñõåìû ìîæíî âûïîëíÿòü îò èìåíè åå âëàäåëüöà, íî äëÿ ïîëíîãî ýêñïîðòà íåîáõîäèìî 69
3.9. Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
Ãëàâà 3. Óñòàíîâêà ORACLE
îáëàäàòü ðîëüþ DBA, â ïðîòèâíîì ñëó÷àå ïîïûòêà ïîëíîãî ýêñïîðòà çàâåðøèòñÿ îøèáêîé EXP-00023 ñ ñîîáùåíèåì ¾Must be a DBA to do Full Database or Tablespace export¿. Ðàçìåð äàìïà â ñëó÷àå ïîëíîãî ýêñïîðòà ïóñòîé áàçû Oracle 10g XE ñîñòàâëÿåò 43 Ìáàéò (9 Ìáàéò ïîñëå ñæàòèÿ WinRar). Íàñòîÿòåëüíî ðåêîìåíäóåòñÿ âûïîëíÿòü ïåðèîäè÷åñêîå ðåçåðâíîå êîïèðîâàíèå äàæå íà ó÷åáíîé áàçå èçâåñòíû äåñÿòêè è ñîòíè ñëó÷àåâ, êîãäà â õîäå èçó÷åíèÿ Oracle ïðîèñõîäèò ïîâðåæäåíèå áàçû, óäàëåíèå ïîëüçîâàòåëÿ èëè èíàÿ îïåðàöèÿ, ïðèâîäÿùàÿ ê ïîòåðå ñîçäàííûõ îáúåêòîâ. Ëîãè÷åñêèé èìïîðò ÿâëÿåòñÿ çåðêàëüíîé îïåðàöèåé ïî îòíîøåíèþ ê ýêñïîðòó è âûïîëíÿåòñÿ ïðè ïîìîùè óòèëèòû IMP.  õîäå èìïîðòà íåîáÿçàòåëüíî èìïîðòèðîâàòü âñþ èìåþùóþñÿ â äàìïå èíôîðìàöèþ ìîæíî ïðîèçâåñòè èìïîðò çàäàííûõ ñõåì èëè òàáëèö. Ïàðàìåòðû óòèëèòû IMP óäîáíî ðàçìåùàòü â ïðîôèëÿõ, íàïðèìåð äëÿ èìïîðòà ñõåìû STUDENT ìîæíî ïðèìåíèòü ïðîôèëü ñëåäóþùåãî âèäà:
USERID = student/student LOG = ora10studimp.log FILE = ora10stud.dmp ROWS = Y GRANTS = Y INDEXES = Y FROMUSER= STUDENT TOUSER= STUDENT Ïàðàìåòð FROMUSER óêàçûâàåò, èç êàêèõ ó÷åòíûõ çàïèñåé â äàìïå áåðåòñÿ èíôîðìàöèÿ, à TOUSER â êàêèå ó÷åòíûå çàïèñè îíà èìïîðòèðóåòñÿ. Ýòî î÷åíü óäîáíàÿ âîçìîæíîñòü óòèëèòû èìïîðòà, òàê êàê îíà ïîçâîëÿåò èìïîðòèðîâàòü äàííûå îäíîé ñõåìû â äðóãóþ. Ïàðàìåòðû ROWS (ñòðîêè òàáëèö), GRANTS (ïîëíîìî÷èÿ íà îáúåêòû), INDEXES (èíäåêñû) óêàçûâàþò, êàêèå òèïû îáúåêòîâ èìïîðòèðóþòñÿ. Ðàññìîòðèì íåñêîëüêî òèïè÷íûõ ñèòóàöèé, âñòðå÷àþùèõñÿ íà ïðàêòèêå:
• íåîáõîäèìî èìïîðòèðîâàòü òàáëèöû, íî íå òðåáóåòñÿ çàãðóæàòü â íèõ äàííûå â ýòîì ñëó÷àå ñëåäóåò çàäàòü ïàðàìåòð ROWS=N; 70
Ãëàâà 3. Óñòàíîâêà ORACLE
3.9. Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
• íåîáõîäèìî èìïîðòèðîâàòü îáúåêòû ó÷åòíîé çàïèñè STUDENT â ó÷åòíóþ çàïèñü STUDENT1.  ýòîì ñëó÷àå ñëåäóåò çàäàòü ïàðàìåòðû FROMUSER=STUDENT è TOUSER= STUDENT1; Ïåðåä èìïîðòîì íåîáõîäèìî óäàëèòü âñå îáúåêòû èç ñõåìû, èíà÷å â ïðîöåññå èìïîðòà áóäóò âûäàâàòüñÿ îøèáêè IMP-00015 äëÿ êàæäîé èìïîðòèðóåìîé òàáëèöû (èìïîðò äàííûõ â ýòîì ñëó÷àå íå ïðîèçâîäèòñÿ). Åñëè ïî êàêèì-ëèáî ïðè÷èíàì íåîáõîäèìî çàãðóçèòü äàííûå â ñóùåñòâóþùóþ òàáëèöó, òî ìîæíî ïðèìåíèòü ïàðàìåòð IGNORE=Y, ÷òî ïðèâåäåò ê èãíîðèðîâàíèþ îøèáîê ïðè ñîçäàíèè îáúåêòîâ è ê ïðîäîëæåíèþ èìïîðòà äàííûõ. Îäíàêî â ñëó÷àå ïðèìåíåíèÿ ïàðàìåòðà IGNORE=Y íåîáõîäèìî ó÷èòûâàòü, ÷òî â òàáëèöàõ áåç ïåðâè÷íîãî êëþ÷à ìîæåò âîçíèêíóòü óäâîåíèå çàïèñåé (òàê êàê êàæäàÿ îïåðàöèÿ èìïîðòà çàãðóæàåò íîâûå äàííûå, à ñòàðûå ïðè ýòîì íå óíè÷òîæàþòñÿ). Ó IMP åñòü îäíà èíòåðåñíàÿ ôóíêöèÿ âìåñòî âûïîëíåíèÿ êîìàíä â áàçå äàííûõ ýòà óòèëèòà âûâîäèò èõ â ïðîòîêîë, ãåíåðèðóÿ òåì ñàìûì ñêðèïòû, ñîäåðæàùèå DML-îïåðàòîðû. Äëÿ âêëþ÷åíèÿ ýòîé ôóíêöèè íåîáõîäèìî óêàçàòü ïàðàìåòð SHOW=Y.
71
3.9. Ðåçåðâíîå êîïèðîâàíèå è âîññòàíîâëåíèå
72
Ãëàâà 3. Óñòàíîâêà ORACLE
Ãëàâà 4 Ïðèìåíåíèå SQL â ïðèëîæåíèÿõ 4.1
SQL ïðåäñòàâëåíèÿ
(SQL view) ýòî âèðòóàëüíàÿ òàáëèöà, ñîñòàâëåííàÿ èç äðóãèõ òàáëèö èëè ïðåäñòàâëåíèé. Ïðåäñòàâëåíèå íå èìååò ñâîèõ ñîáñòâåííûõ äàííûõ, à îáúåäèíÿåò äàííûå èç òàáëèö èëè ïåðäñòàâëåíèé, êîòîðûå â íåãî âõîäÿò. Ïðåäñòàâëåíèÿ ñîçäàþòñÿ ñ ïîìîùüþ îïåðàòîðîâ SELECT. Ñîãëàñíî ñòàíäàðòó SQL-92 ïðåäñòàâëåíèÿ íå ìîãóò âêëþ÷àòü â ñåáÿ êîíñòðóêöèþ ORDER BY, íî Oracle òàêîé âàðèàíò äîïóñêàåò. Íàïðèìåð, ñëåäóþùèé îïåðàòîð îïðåäåëÿåò ïðåäñòàâëåíèå ïîä íàçâàíèåì ArtistNameView, áàçèðóþùèéñÿ íà òàáëèöå ARTIST: SQL-ïðåäñòàâëåíèå
CREATE VIEW ArtistNameView AS SELECT Name AS ArtistName FROM ARTIST ORDER BY Name; Äëÿ ïîëó÷åíèÿ îòñîðòèðîâàííîãî ñïèñêà èìåí õóäîæíèêîâ ýòî ïðåäñòàâëåíèå ìîæíî îáðàáîòàòü ïðè ïîìîùè òàêîãî SQL-îïåðàòîðà:
SELECT * FROM ArtistNameView; Ðåçóëüòàò áóäåò âûãëÿäåòü ñëåäóþùèì îáðàçîì: 73
4.1. SQL ïðåäñòàâëåíèÿ
Ãëàâà 4. Ïðèìåíåíèå SQL
ArtistName Chagall Frings Kandinsky Klee Matisse Miro Moos Tobey Ñëåäóåò îáðàòèòü âíèìàíèå íà òî, êàê èñïîëüçóåòñÿ âûðàæåíèå SELECT * äëÿ çàïðîñà äàííûõ èç ïðåäñòàâëåíèÿ ArtistNameView. Êàê èçâåñòíî, ýòî âûðàæåíèå âîçâðàùàåò âñå ñòîëáöû.  äàííîì ñëó÷àå âîçâðàùàåòñÿ òîëüêî îäèí ñòîëáåö, òàê êàê îí ÿâëÿåòñÿ åäèíñòâåííûì â ïðåäñòàâëåíèè ArtistNameView, õîòÿ òàáëèöà ARTIST, èç êîòîðîé îí âçÿò, èìååò íåñêîëüêî ñòîëáöîâ. Òàêæå îáðàòèòå âíèìàíèå, ÷òî ñòîëáöó ARTIST.Name èç îðèãèíàëüíîé òàáëèöû â ïðåäñòàâëåíèè ArtistNameView áûëî äàíî èìÿ ArtistName.  âîçâðàùàåìûõ ÑÓÁÄ ðåçóëüòàòàõ â êà÷åñòâå èìåíè ñòîëáöà ôèãóðèðóåò èìåííî ArtistName. Ïðåäñòàâëåíèÿ èìåþò ìíîæåñòâî ïðèìåíåíèé. Âî-ïåðâûõ, ñ èõ ïîìîùüþ ìîæíî ñêðûâàòü îò äîñòóïà îòäåëüíûå ñòîëáöû èëè ñòðîêè. Êðîìå òîãî, îíè ïîçâîëÿþò îòîáðàæàòü âû÷èñëÿåìûå ñòîëáöû è ñêðûâàòü ñëîæíûå SQL-îïåðàòîðû. Òàêæå ïðåäñòàâëåíèÿ îáåñïå÷èâàþò óðîâåíü àáñòðàêöèè ìåæäó äàííûìè, îáðàáàòûâàåìûìè ïðèëîæåíèåì, è ðåàëüíûìè äàííûìè, ñîäåðæàùèìèñÿ â òàáëèöàõ. Äàëåå ðàññìàòðèâàþòñÿ ïðèìåðû êàæäîãî èç ýòèõ ïðèìåíåíèé è îáñóæäàþòñÿ íåêîòîðûå äðóãèå âàðèàíòû èñïîëüçîâàíèÿ ïðåäñòàâëåíèé. 4.1.1
Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ ñêðûòèÿ ñòîëáöîâ è ñòðîê
Ñ ïîìîùüþ ïðåäñòàâëåíèé ìîæíî ñêðûòü îòäåëüíûå ñòîëáöû òàáëèö. Ýòî äåëàåòñÿ äëÿ òîãî, ÷òîáû âîçâðàùàåìûé ðåçóëüòàò èìåë áîëåå ïðîñòîé âèä, à òàêæå äëÿ ïðåäîòâðàùåíèÿ äîñòóïà ê êîíôèäåíöèàëüíûì äàííûì. Ïðåäïîëîæèì, ÷òî ïîëüçîâàòåëÿì áàçû äàííûõ íóæíû òîëüêî èìåíà è íîìåðà òåëåôîíîâ êëèåíòîâ, íî íå èõ äîìàøíèå àäðåñà èëè 74
Ãëàâà 4. Ïðèìåíåíèå SQL
4.1. SQL ïðåäñòàâëåíèÿ
àäðåñà ýëåêòðîííîé ïî÷òû. Ñëåäóþùèé îïåðàòîð ñîçäàåò ïðåäñòàâëåíèå BasicCustomerData, ñîäåðæàùåå òîëüêî ýòè äàííûå.
CREATE VIEW BasicCustomerData AS SELECT Name, AreaCode, PhoneNumber FROM CUSTOMER; Ðåçóëüòàòû âûïîëíåíèÿ îïåðàòîðà SELECT * íàä ýòèì ïðåäñòàâëåíèåì ñëåäóþùèå: Name Jerey Janes David Smith Tiany Twilight Fred Smathers Mary Beth Frederickson Selma Warning Susan Wu Donald G. Gray Lynda Johnson Chris Wilkens
AreaCode 206 303 206 206 303 253 721 705 703 206
PhoneNumber 555-1345 555-5434 555-1000 555-1234 555-1000 555-1234 555-1234 555-1345 555-1000 555-1234
Ìîæíî ñêðûâàòü îò ïðîñìîòðà è ñòðîêè òàáëèö. Äëÿ ýòîãî â îïðåäåëåíèè ïðåäñòàâëåíèÿ äîëæíî ïðèñóòñòâîâàòü ïðåäëîæåíèå WHERE. Ñëåäóþùèé îïåðàòîð îïðåäåëÿåò ïðåäñòàâëåíèå, ñîäåðæàùåå èìåíà è íîìåðà òåëåôîíîâ âñåõ êëèåíòîâ, ïðîæèâàþùèõ â øòàòå Âàøèíãòîí:
CREATE VIEW BasicCustomerData AS SELECT Name, PhoneNumber FROM CUSTOMER WHERE State = 'WA'; Ðåçóëüòèðóþùàÿ òàáëèöà áóäåò òàêàÿ: Name Jerey Janes Tiany Twilight Fred Smathers Chris Wilkens
PhoneNumber 555-1345 555-1000 555-1234 555-1234 75
4.1. SQL ïðåäñòàâëåíèÿ
Ãëàâà 4. Ïðèìåíåíèå SQL
Êàê è òðåáîâàëîñü, â òàáëèöå ïðèñóòñòâóþò ñâåäåíèÿ òîëüêî î òåõ êëèåíòàõ, êîòîðûå ïðîæèâàþò â øòàòå Âàøèíãòîí. Äàííûé ôàêò íå ÿâëÿåòñÿ î÷åâèäíûì, ïîñêîëüêó ñòîëáåö State íå âõîäèò â ðåçóëüòàò. Ýòî ìîæåò áûòü õîðîøî èëè ïëîõî â çàâèñèìîñòè îò òîãî, êàê èñïîëüçóåòñÿ ïðåäñòàâëåíèå. Åñëè îíî èñïîëüçóåòñÿ òîëüêî â òåõ ñëó÷àÿõ, êîãäà çíà÷åíèå èìåþò ëèøü êëèåíòû èç Âàøèíãòîíà, ýòî õîðîøî; â ïðîòèâíîì ñëó÷àå ýòî áóäåò äåçîðèåíòèðîâàòü ïîëüçîâàòåëÿ, ñîçäàâàÿ âïå÷àòëåíèå, ÷òî êðîìå ïåðå÷èñëåííûõ ïåðñîí, ó ãàëåðåè áîëüøå íåò êëèåíòîâ. 4.1.2
Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ îòîáðàæåíèÿ âû÷èñëÿåìûõ ñòîëáöîâ
Åùå îäíî ïðèìåíåíèå ïðåäñòàâëåíèé îòîáðàæåíèå ðåçóëüòàòîâ âû÷èñëåíèé, íå ïðèáåãàÿ ê ââîäó ôîðìóë ïîëüçîâàòåëåì. Íàïðèìåð, ñëåäóþùåå ïðåäñòàâëåíèå îáúåäèíÿåò ñòîëáöû AreaCode è PhoneNumber è ôîðìàòèðóåò ðåçóëüòàò:
CREATE VIEW CustomerPhone AS SELECT Name, ('(' || AreaCode || ')') || PhoneNumber AS Phone FROM CUSTOMER; Äîïóñòèì, ïîëüçîâàòåëü ââîäèò ñëåäóþùèé çàïðîñ:
SELECT * FROM CustomerPhone; Ðåçóëüòàòû âûïîëíåíèÿ ýòîãî çàïðîñà áóäóò ñëåäóþùèìè: Name Jerey Janes David Smith Tiany Twilight Fred Smathers Mary Beth Frederickson Selma Warning Susan Wu Donald G. Gray Lynda Johnson Chris Wilkens
Phone (206)555-1345 (303)555-5434 (206)555-1000 (206)555-1234 (303)555-1000 (253)555-1234 (721)555-1234 (705)555-1345 (703)555-1000 (206)555-1234 76
Ãëàâà 4. Ïðèìåíåíèå SQL
4.1. SQL ïðåäñòàâëåíèÿ
Âûïîëíåíèå íåîáõîäèìûõ âû÷èñëåíèé â ïðåäñòàâëåíèÿõ èìååò äâà ïðåèìóùåñòâà. Âî-ïåðâûõ, ýòî èçáàâëÿåò ïîëüçîâàòåëåé îò íåîáõîäèìîñòè ââîäèòü ìàòåìàòè÷åñêîå âûðàæåíèå, ÷òîáû ïîëó÷èòü æåëàåìûé ðåçóëüòàò (à òàêæå îò íåîáõîäèìîñòè çíàòü, êàê ýòî äåëàåòñÿ). Âî-âòîðûõ, ýòî îáåñïå÷èâàåò åäèíîîáðàçèå ðåçóëüòàòîâ. Åñëè êàæäûé ðàçðàáîò÷èê, èñïîëüçóþùèé âû÷èñëåíèÿ, áóäåò ïèñàòü ñîáñòâåííûå âûðàæåíèÿ, òî îíè, ñêîðåå âñåãî, áóäóò íàïèñàíû ïî-ðàçíîìó, èç-çà ÷åãî ðåçóëüòàòû áóäóò èìåòü íåîäèíàêîâûé âèä. 4.1.3
Èñïîëüçîâàíèå ïðåäñòàâëåíèé äëÿ ñêðûòèÿ ñëîæíîãî ñèíòàêñèñà
Åùå îäíî ïðèìåíåíèå ïðåäñòàâëåíèé ñêðûòèå SQL-îïåðàòîðîâ ñî ñëîæíûì ñèíòàêñèñîì. Ýòî ìîæåò äåëàòüñÿ äëÿ òîãî, ÷òîáû èçáàâèòü ðàçðàáîò÷èêîâ îò íåîáõîäèìîñòè ââîäèòü ñëîæíûé îïåðàòîð âñÿêèé ðàç, êîãäà èì òðåáóåòñÿ îïðåäåëåííîå ïðåäñòàâëåíèå, èëè äëÿ òîãî, ÷òîáû ðàçðàáîò÷èêè, íå çíàþùèå SQL, ìîãëè òåì íå ìåíåå âîñïîëüçîâàòüñÿ ïðåèìóùåñòâàìè, êîòîðûå ïðåäîñòàâëÿþò ñëîæíûå SQL-îïåðàòîðû. Êðîìå òîãî, êàê è â ñëó÷àå èñïîëüçîâàíèÿ ïðåäñòàâëåíèé äëÿ âû÷èñëåíèé, ýòî îáåñïå÷èâàåò åäèíîîáðàçèå ðåçóëüòàòîâ. Äâà íàèáîëåå ðàñïðîñòðàíåííûõ âàðèàíòà èñïîëüçîâàíèÿ ïðåäñòàâëåíèé â äàííîé èïîñòàñè ýòî ñêðûòèå ñîåäèíåíèé è ñêðûòèå âëîæåííûõ çàïðîñîâ. Ïðåäïîëîæèì, ÷òî ïðîäàâöàì-êîíñóëüòàíòàì ãàëåðåè íåîáõîäèìî çíàòü, êàêèìè õóäîæíèêàìè èíòåðåñóåòñÿ òîò èëè èíîé êëèåíò. Ïîñêîëüêó ñâÿçü ìåæäó ñóùíîñòÿìè CUSTOMER è ARTIST èìååò âèä N:M, îíà ïðåäñòàâëåíà â âèäå òàáëèöû ïåðåñå÷åíèÿ. Òàêèì îáðàçîì, ÷òîáû îòîáðàçèòü ñâåäåíèÿ îá èíòåðåñàõ êëèåíòîâ, íåîáõîäèìî âûïîëíèòü äâà ñîåäèíåíèÿ: ñíà÷àëà ñîåäèíèòü òàáëèöû CUSTOMER è CUSTOMER_ARTIST_INT, à çàòåì ïîëó÷åííûé ðåçóëüòàò ñîåäèíèòü ñ òàáëèöåé ARTIST. Ïðåäñòàâëåíèå, ñîäåðæàùåå ýòè äâà ñîåäèíåíèÿ, êîíñòðóèðóåòñÿ ñ ïîìîùüþ ñëåäóþùåãî SQL-îïåðàòîðà:
CREATE VIEW CustomerInterests AS SELECT C.Name AS Customer, A.Name AS Artist FROM CUSTOMER C JOIN CUSTOMER_ARTIST_INT CI 77
4.1. SQL ïðåäñòàâëåíèÿ
Ãëàâà 4. Ïðèìåíåíèå SQL
ON C.CustomerID = CI.CustomerID JOIN ARTIST A ON CI.ArtistID = A.ArtistID; Ýòîò îïåðàòîð âûïîëíÿåò ñòàíäàðòíîå äâîéíîå ñîåäèíåíèå. Îáðàòèòå âíèìàíèå íà èñïîëüçîâàíèå ïñåâäîíèìîâ äëÿ òàáëèö (Ñ âìåñòî CUSTOMER, CI âìåñòî CUSTOMER_ARTIST_INT, A âìåñòî ARTIST). Òàêèå ïñåâäîíèìû óïðîùàþò âûðàæåíèÿ ON. Íàïðèìåð, ïðîùå íàïèñàòü C.CustomerID = CI.CustomerID, ÷åì CUSTOMER.CustomerID = CUSTOMER_ARTIST_INT.CustomerID. Èñïîëüçîâàòü ïñåâäîíèìû íå îáÿçàòåëüíî. Òàêæå îáðàòèòå âíèìàíèå íà ïåðåèìåíîâàíèå C.Name â Customer è A.Name â Artist. Òàêîå ïåðåèìåíîâàíèå âûïîëíÿòü íåîáõîäèìî, â ïðîòèâíîì ñëó÷àå â ïåðäñòàâëåíèè îêàçàëèñü áû äâà ñòîëáöà ñ èìåíåì Name. ÑÓÁÄ íå ñìîãëà áû ðàçëè÷èòü ýòè äâà ñòîëáöà è âûäàëà áû îøèáêó ïðè ñîçäàíèè ïðåäñòàâëåíèÿ. Ñëåäóþùèé îïåðàòîð çàïðàøèâàåò äàííûå èç ïðåäñòàâëåíèÿ CustomerInterests è ñîðòèðóåò ðåçóëüòàòû ïî ñòîëáöó Customer:
SELECT * FROM CustomerInterests ORDER BY Customer; Ðåçóëüòàò ïîëó÷èëñÿ ñëåäóþùèé: Customer Chris Wilkens Chris Wilkens David Smith Donald G. Gray Fred Smathers Lynda Johnson Lynda Johnson Lynda Johnson Mary Beth Frederickson Mary Beth Frederickson Mary Beth Frederickson Selma Warning
Artist Frings Tobey Tobey Tobey Tobey Tobey Moos Frings Frings Moos Tobey Tobey 78
Ãëàâà 4. Ïðèìåíåíèå SQL
Customer Selma Warning Tiany Twilight Tiany Twilight Tiany Twilight
4.1. SQL ïðåäñòàâëåíèÿ
Artist Miro Chagall Frings Tobey
Ïðåäñòàâëåíèÿ èñïîëüçóþòñÿ òàêæå äëÿ ñêðûòèÿ ãðóïïèðîâêè è âñòðîåííûõ ôóíêöèé. Ðàññìîòðèì ñëåäóþùåå îïðåäåëåíèå ïðåäñòàâëåíèÿ:
CREATE VIEW ArtistWorkNet AS SELECT W.WorkID, Name, Title, Copy, AcquisitionPrice, SalesPrice, (SalesPrice - AcquisitionPrice) AS NetPrice FROM TRANSACTION T JOIN WORK W ON T.WorkID = W.WorkID JOIN ARTIST A ON W.ArtistID = A.ArtistID; Ýòî ïðåäñòàâëåíèå ñîåäèíÿåò òàáëèöû TRANSACTION, WORK è ARTIST è ñîçäàåò âû÷èñëÿåìûé ñòîëáåö NetPrice. Ñ ýòèì ïðåäñòàâëåíèåì ìîæíî âûïîëíÿòü ðàçëè÷íûå îïåðàöèè íà ÿçûêå SQL, êàê åñëè áû NetPrice áûë îáû÷íûì ñòîëáöîì òàáëèöû. Íàïðèìåð, ÷òîáû îòîáðàçèòü ñîâîêóïíóþ ïðèáûëü îò ïðîäàæè êàæäîé êàðòèíû, ìîæíî èñïîëüçîâàòü ñëåäóþùèé îïåðàòîð:
SELECT Name, Title, Copy, SUM(NetPrice) AS TotalNet FROM ArtistWorkNet GROUP BY Name, Title, Copy; Ðåçóëüòàòû âûïîëíåíèÿ ýòîãî çàïðîñà ïîêàçàíû íèæå: Name Chagall Tobey Tobey Tobey Miro
Title Northwest by Night Slow Embers Mystic Fabric Mystic Fabric Mi Vida 79
Copy 37/50 NC 105/135 99/135 7/10
TotalNet 24500 7750 14750 27550 34800
4.2. SQL-îïåðàòîðû â ïðèêëàäíûõ ïðîãðàììàõ
Ãëàâà 4. Ïðèìåíåíèå SQL
Ó ïðåäñòàâëåíèé èìååòñÿ åùå òðè âàæíûõ ïðèìåíåíèÿ. Âî-ïåðâûõ, îíè ìîãóò îáåñïå÷èâàòü îïðåäåëåííûé óðîâåíü àáñòðàêöèè ìåæäó ïðèëîæåíèåì áàçû äàííûõ è ðåàëüíûìè òàáëèöàìè. Ýòîò óðîâåíü àáñòðàêöèè ìîæåò áûòü âàæåí, êîãäà èñòî÷íèê äàííûõ ìîæåò ìåíÿòüñÿ. ×òîáû ïîíÿòü, î ÷åì èäåò ðå÷ü, ðàññìîòðèì ñëåäóþùåå îïðåäåëåíèå ïðåäñòàâëåíèÿ:
CREATE VIEW CustomerTable1 AS SELECT * FROM CUSTOMER;  ñóùíîñòè, ýòî ïðåäñòàâëåíèå ïðèñâàèâàåò òàáëèöå CUSTOMER ïñåâäîíèì CustomerTable1. Ïðåäñòàâëåíèå CustomerTable1 ìîæíî îáðàáàòûâàòü òî÷íî òàêèì æå îáðàçîì, êàê è òàáëèöó CUSTOMER. Åñëè â êîäå ïðèëîæåíèÿ èñïîëüçóåòñÿ èìÿ CustomerTable1, òî èñòî÷íèê äàííûõ, íà êîòîðîì îñíîâàíî ýòî ïðåäñòàâëåíèå, èîæåò ìåíÿòüñÿ, íå âûçûâàÿ íåîáõîäèìîñòè ïåðåïèñûâàòü ïðèëîæåíèå. Ñëåäîâàòåëüíî, â îïðåäåëåííûé ìîìåíò â áóäóùåì, åñëè èñòî÷íèêîì äàííûõ î êëèåíòàõ ñòàíåò äðóãàÿ òàáëèöà, íàïðèìåð, NEW_CUSTOMER, âñå, ÷òî ïîòðåáóåòñÿ ñäåëàòü, ýòî ïåðåîïðåäåëèòü ïðåäñòàâëåíèå CustomerTable1 ñëåäóþùèì îáðàçîì:
CREATE VIEW CustomerTable1 AS SELECT * FROM NEW_CUSTOMER; Âåñü êîä ïðèëîæåíèÿ, â êîòîðîì èñïîëüçóåòñÿ èìÿ CustomerTable1, áåç ïðîáëåì áóäåò ðàáîòàòü ñ íîâûì èñòî÷íèêîì äàííûõ. Èç-çà ïîòåíöèàëüíîé íåîáõîäèìîñòè â èçìåíåíèè èñòî÷íèêîâ äàííûõ íåêîòîðûå îðãàíèçàöèè íèêîãäà íå ïðåäîñòàâëÿþò ðàçðàáîò÷èêàì äîñòóï ê ðåàëüíûì òàáëèöàì. Âìåñòî ýòîãî èñïîëüçóþòñÿ ïðåäñòàâëåíèÿ, áàçèðóþùèåñÿ íà äàííûõ èç ýòèõ òàáëèö. Òàêàÿ ñòðàòåãèÿ ïîâûøàåò ãèáêîñòü äëÿ áóäóùèõ ïðîåêòîâ ïî ðàçðàáîòêå áàç äàííûõ è óïðîùàåò èõ ïåðåïðîåêòèðîâàíèå.
4.2
SQL-îïåðàòîðû â ïðèêëàäíûõ ïðîãðàììàõ
SQL-îïåðàòîðû ìîæíî âñòðàèâàòü â òðèããåðû, õðàíèìûå ïðîöåäóðû è ïðàêëàäíûå ïðîãðàììû. Äëÿ òîãî, ÷òîáû âñòðîèòü SQL-îïåðàòîðû â ïðîãðàììíûé êîä, íåîáõîäèìî ïðåîäîëåòü äâà çàòðóäíåíèÿ. Âî-ïåðâûõ, íóæåí 80
Ãëàâà 4. Ïðèìåíåíèå SQL
4.2. SQL-îïåðàòîðû â ïðèêëàäíûõ ïðîãðàììàõ
êàêîé-òî ñïîñîá, ïîçâîëÿþùèé çàïèñûâàòü ðåçóëüòàòû âûïîëíåíèÿ SQLîïåðàòîðîâ â ïðîãðàììíûå ïåðåìåííûå. Ýòî ìîæíî ñäåëàòü ïî-ðàçíîìó.  îäíèõ ñëó÷àÿõ äëÿ ýòîãî èñïîëüçóþòñÿ îáúåêòíî-îðèåíòèðîâàííûå ïðîãðàììû, â äðóãèõ ïðèìåíÿþòñÿ áîëåå ïðîñòûå ìåòîäû. Íàïðèìåð, â PL/SQL ñëåäóþùèé îïåðàòîð ïðèñâàèâàåò ïåðåìåííîé rowcount çíà÷åíèå, ðàâíîå êîëè÷åñòâó ñòðîê â òàáëèöå CUSTOMER:
SELECT COUNT(*) INTO rowcount FROM CUSTOMER; Âòîðàÿ òðóäíîñòü çàêëþ÷àåòñÿ â íåñîîòâåòñòâèè ïàðàäèãì SQL ïàðàäèãìàì ÿçûêîâ ïðîãðàììèðîâàíèÿ. ßçûê SQL îïåðèðóåò ìíîæåñòâàìè: áîëüøèíñòâî îïåðàòîðîâ SQL âîçâðàùàþò òàáëèöó èëè íàáîð ñòðîê.  îòëè÷èå îò ýòîãî, ïðîãðàììû îïåðèðóþò îòäåëüíûìè ýëåìåíòàìè èëè ñòðîêàìè. Èç-çà ýòîãî îòëè÷èÿ îïåðàòîð, ïîäîáíûé ïðèâåäåííîìó íèæå, íå èìååò ñìûñëà:
SELECT Name INTO custName FROM CUSTOMER; Åñëè â òàáëèöå CUSTOMER èìååòñÿ 100 ñòðîê, òî çàïðîñ ñòîëáöà Name âîçâðàòèò 100 çíà÷åíèé, â òî âðåìÿ êàê ïåðåìåííàÿ custName ìîæåò ïðèíÿòü òîëüêî îäíî çíà÷åíèå. ×òîáû ïåðîäîëåòü ýòî çàòðóäíåíèå, ðåçóëüòàòû âûïîëíåíèÿ SQLîïåðàòîðîâ îáðàáàòûâàþòñÿ êàê ïñåâäîôàéëû. SQL-îïåðàòîð âîçâðàùàåò íàáîð ñòðîê. Íà ïåðâóþ ñòðîêó ïîìåùàåòñÿ êóðñîð, è äàííàÿ ñòðîêà îáðàáàòûâàåòñÿ. Çàòåì êóðñîð ïåðåìåùàåòñÿ íà ñëåäóþùóþ ñòðîêó, è òàê äàëåå, ïîêà íå áóäóò îáðàáîòàíû âñå ñòðîêè. Òèïè÷íûé ïðîöåññ îáðàáîòêè âûãëÿäèò òàê:
Îòêðûòü ôàéë SQL (SELECT * FROM CUSTOMER); Ïîìåñòèòü êóðñîð íà ïåðâóþ ñòðîêó; Ïîêà êóðñîð íå âûøåë çà ïðåäåëû òàáëèöû { Ïðèñâîèòü custName çíà÷åíèå ñòîëáöà Name â ñòðîêå ïîä êóðñîðîì; ... Ïðî÷èå îïåðàòîðû, èñïîëüçóþùèå çíà÷åíèå custName ... Ïåðåìåñòèòü êóðñîð íå ñëåäóþùóþ ñòðîêó; }; ... Ïðîäîëæåíèå îáðàáîòêè... 81
4.3. Òðèããåðû
Ãëàâà 4. Ïðèìåíåíèå SQL
Òàêèì îáðàçîì, ñòðîêè, âîçâðàùåííûå SQL-îïåðàòîðîì, îáðàáàòûâàþòñÿ ïî îäíîé. Èìåííî òàêèì ÿâëÿåòñÿ ïðèíöèï âñòðàèâàíèÿ SQLîïåðàòîðîâ â ïðîãðàììíûé êîä. Ïðèìåðû áóäóò ïðåäñòàâëåíû äàëåå.
4.3
Òðèããåðû
(trigger) ýòî ñïåöèàëüíàÿ ïðîãðàììà, íàçíà÷àåìàÿ òàáëèöå èëè ïðåäñòàâëåíèþ. Òðèããåð âûçûâàåòñÿ ÑÓÁÄ, êîãäà ïîëüçîâàòåëü çàïðàøèâàåò âñòàâêó, îáíîâëåíèå èëè óäàëåíèå ñòðîêè èç òàáëèöû èëè ïðåäñòàâëåíèÿ, êîòîðîìó ïðèíàäëåæèò äàííûé òðèããåð. Òðèããåðû äëÿ Oracle ìîæíî ïèñàòü íà ñîáñòâåííîì ÿçûêå ïðîãðàììèðîâàíèÿ ýòîé ÑÓÁÄ, íîñÿùèì íàçâàíèå PL/SQL (Programming Language for SQL - ÿçûê ïðîãðàììèðîâàíèÿ äëÿ SQL), èëè íà Java. Oracle ïîääåðæèâàåò òðè âèäà òðèããåðîâ: ïðåäâàðÿþùèå (BEFORE), çàìåùàþùèå (INSTEAD OF) è çàâåðøàþùèå (AFTER). Êàê è ëîãè÷íî áûëî áû îæèäàòü, ïðåäâàðÿþùèå òðèããåðû âûçûâàþòñÿ ïåðåä îáðàáîòêîé çàïðîñà íà âñòàâêó, îáíîâëåíèå èëè óäàëåíèå, çàìåùàþùèå - âìåñòî íåãî, à çàâåðøàþùèå - ïîñëå îáðàáîòêè çàïðîñà. Âñåãî èìååòñÿ äåâÿòü âîçìîæíûõ òèïîâ òðèããåðîâ: ïðåäâàðÿþùèé òðèããåð âñòàâêè, îáíîâëåíèÿ è óäàëåíèÿ, çàìåùàþùèé òðèããåð âñòàâêè, îáíîâëåíèÿ è óäàëåíèÿ è çàâåðøàþùèé òðèããåð âñòàâêè, îáíîâëåíèÿ è óäàëåíèÿ. Ïðè çàïóñêå òðèããåðà ÑÓÁÄ ïðåäîñòàâëÿåò äîñòóï ê âñòàâëÿåìûì, îáíîâëÿåìûì èëè óäàëÿåìûì èç òåëà òðèããåðà äàííûì.  ñëó÷àå âñòàâêè òðèããåðó äîñòóïíû çíà÷åíèÿ ñòîëáöîâ íîâîé ñòðîêè, â ñëó÷àå óäàëåíèÿ çíà÷åíèÿ ñòîëáöîâ óäàëÿåìîé ñòðîêè, à â ñëó÷àå îáíîâëåíèÿ òðèããåð ìîæåò îïåðèðîâàòü êàê íîâûìè, òàê è ñòàðûìè çíà÷åíèÿìè.  Oracle äëÿ ïîëó÷åíèÿ íîâûõ çíà÷åíèé íåîáõîäèìî äîáàâèòü ê èìåíè ñòîëáöà ïðåôèêñ :new. Òàê, íàïðèìåð, ïðè âñòàâêå â òàáëèöó CUSTOMER ïåðåìåííàÿ :new.Name ñîäåðæèò çíà÷åíèå ñòîëáöà Name âñòàâëÿåìîé ñòðîêè.  ñëó÷àå îáíîâëåíèÿ ïåðåìåííàÿ :new.Name ñîäåðæèò çíà÷åíèå, êîòîðîå áóäåò èìåòü ñòîëáåö Name ïîñëå âûïîëíåíèÿ çàïðîñà. Àíàëîãè÷íûì îáðàçîì, äëÿ ïîëó÷åíèÿ ñòàðûõ çíà÷åíèé íåîáõîäèìî äîáàâèòü ê èìåíè èíòåðåñóþùåãî íàñ ñòîëáöà ïðåôèêñ :old. Íàïðèìåð, ïðè óäàëåíèè ïåðåìåííàÿ :old.Name ñîäåðæèò çíà÷åíèå ñòîëáöà Name óäàëÿåìîé ñòðîêè.  ñëó÷àå îáíîâëåíèÿ ýòà ïåðåìåííàÿ ñîäåðæèò çíà÷åíèå ñòîëáöà Name äî âûïîëíåíèÿ çàïðîñà. Òðèããåð
82
Ãëàâà 4. Ïðèìåíåíèå SQL
4.3. Òðèããåðû
Òðèããåðû èìåþò ìíîæåñòâî ïðèìåíåíèé. Îñíîâíûå èç íèõ: ïðîâåðêà äîïóñòèìîñòè ââîäèìûõ äàííûõ, ïðèñâàèâàíèå çíà÷åíèé ïî óìîë÷àíèþ, îáíîâëåíèå ïðåäñòàâëåíèé è îáåñïå÷åíèå ññûëî÷íîé öåëîñòíîñòè. 4.3.1
Èñïîëüçîâàíèå òðèããåðîâ äëÿ ïðîâåðêè äîïóñòèìîñòè ââîäèìûõ äàííûõ
Ïðåäïîëîæèì, ó ãàëåðåè (ñì. îïèñàíèå ïðàêòè÷åñêîãî ïðèìåðà â ãë. 1) åñòü ïðàâèëî, ÷òî íè îäíà ðàáîòà íå ìîæåò áûòü ïðîäàíà ìåíåå, ÷åì çà 90% îò çàïðîøåííîé öåíû. ×òîáû îáåñïå÷èòü âûïîëíåíèå ýòîãî ïðàâèëà, ìîæíî íàïèñàòü òðèããåð îáíîâëåíèÿ äëÿ òàáëèöû TRANSACTION, ñðàâíèâàþùèé çíà÷åíèÿ AskingPrice è SalesPrice. Åñëè ïðàâèëî íàðóøàåòñÿ, â ñòîëáåö AskingPrice ñòàâèòñÿ èñõîäíîå çíà÷åíèå. Ìîæíî èñïîëüçîâàòü äâå ñòðàòåãèè. Îäíà çàêëþ÷àåòñÿ â òîì, ÷òîáû íàïèñàòü ïðåäâàðÿþùèé òðèããåð, êîòîðûé ïðîâåðÿåò è ïåðåóñòàíàâëèâàåò, åñëè íåîáõîäèìî, çíà÷åíèå ñòîëáöà SalesPrice äî âûïîëíåíèÿ îáíîâëåíèÿ. Âòîðàÿ ñòðàòåãèÿ íàïèñàòü çàâåðøàþùèé òðèããåð, ïðîâåðÿþùèé è ïåðåïèñûâàþùèé ñòðîêó òàáëèöû TRANSACTION ïîñëå îáíîâëåíèÿ. Ëèñòèíã 4.1.
CREATE OR REPLACE TRIGGER TRANS_SalesPriceCheck BEFORE UPDATE ON TRANSACTION FOR EACH ROW BEGIN IF :new.SalesPrice < 0.9 * :old.AskingPrice THEN UPDATE TRANSACTION SET SalesPrice = :old.AskingPrice, AskingPrice = :old.AskingPrice; END IF; END; Ëèñòèíã 4.1 ñîîòâåòñòâóåò âòîðîé ñòðàòåãèè, â êîòîðîì îïóùåíû íåêîòîðûå äåòàëè. Åñëè åñòü íåîáõîäèìîñòü â êîììåíòàðèÿõ, òî îíè ïîìåùàþòñÿ â ñêîáêè âèäà /* */. 83
4.3. Òðèããåðû
Ãëàâà 4. Ïðèìåíåíèå SQL
Ëîãèêà ðàáîòû òðèããåðà î÷åâèäíà. Åñëè íîâàÿ ïðîäàæíàÿ öåíà ñîñòàâëÿåò ìåíåå 90% îò çàïðàøèâàåìîé öåíû, ïðîäàæíàÿ öåíà óñòàíàâëèâàåòñÿ ðàâíîé çàïðàøèâàåìîé öåíå. Îáðàòèòå âíèìàíèå, ÷òî íîâàÿ ïðîäàæíàÿ öåíà ñðàâíèâàåòñÿ ñî ñòàðîé çàïðàøèâàåìîé öåíîé; â ïðîòèâíîì ñëó÷àå ìîæíî áûëî áû, èçìåíèâ îáå öåíû, óñïåøíî ñîâåðøèòü îáíîâëåíèå, íàðóøàþùåå äàííîå îãðàíè÷åíèå. Íà òîò ñëó÷àé, åñëè èìåííî òàê è ïðîèçîøëî, ñòîëáåö AskingPrice â îïåðàòîðå UPDATE óñòàíàâëèâàåòñÿ ðàâíûì :old.AskingPrice. Òàêæå ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî ýòîò òðèããåð áóäåò âûçûâàòüñÿ ðåêóðñèâíî. Îïåðàòîð UPDATE â òðèããåðå âûçîâåò îáíîâëåíèå òàáëèöû TRANSACTION, ÷òî, â ñâîþ î÷åðåäü, ïðèâåäåò ê ïîâòîðíîìó âûçîâó òðèããåðà. Íà ýòîò ðàç, îäíàêî, ñòîëáåö SalesPrice áóäåò ðàâåí :old.AskingPrice, ïîýòîìó íîâûõ îáíîâëåíèé ïðîèçâåäåíî íå áóäåò è ðåêóðñèÿ îñòàíîâèòñÿ. 4.3.2
Èñïîëüçîâàíèå òðèããåðîâ äëÿ ïðèñâîåíèÿ çíà÷åíèé ïî óìîë÷àíèþ
Ñòîëáöàì òàáëèöû ìîãóò ïðèñâàèâàòüñÿ çíà÷åíèÿ ïî óìîë÷àíèþ ñ ïîìîùüþ êâàëèôèêàòîðà DEFAULT.  êà÷åñòâå òàêèõ çíà÷åíèé ìîæíî çàäàâàòü êîíñòàíòû èëè ðåçóëüòàòû âû÷èñëåíèÿ ïðîñòûõ âûðàæåíèé. Åñëè æå çàäàíèå çíà÷åíèÿ ïî óìîë÷àíèþ òðåáóåò áîëåå ñëîæíîé ëîãèêè, íåîáõîäèìî èñïîëüçîâàòü òðèããåð.  ñëó÷àå íàøåãî ïðèìåðà ïðåäïîëîæèì, ÷òî ó ãàëåðåè èìååòñÿ ïðàâèëî, ñîãëàñíî êîòîðîìó çàïðàøèâàåìàÿ öåíà ïðîèçâåäåíèÿ óñòàíàâëèâàåòñÿ ðàâíîé óäâîåííîé ñòîèìîñòè åãî ïðèîáðåòåíèÿ èëè ñóììå îáùåé ñòîèìîñòè ïðèîáðåòåíèÿ è ÷èñòîé âûðó÷êè îò ïðîäàæè ýòîãî ïðîèçâåäåíèÿ â ïðîøëîì. Ýòî ïðàâèëî ðåàëèçóåòñÿ ñ ïîìîùüþ çàâåðøàþùåãî òðèããåðà, ïîêàçàííîãî â ëèñòèíãå 4.2. Ïðåäñòàâëåíèå, êîòîðîå èñïîëüçóåòñÿ â ðàññìàòðèâàåìîì òðèããåðå, èìååò ñëåäóþùèé âèä:
CREATE VIEW ArtistWorkNet AS SELECT W.WorkID, Name, Title, Copy, AcquisitionPrice, SalesPrice, (SalesPrice - AcqisitionPrice) AS NetPrice FROM TRANSACTION T JOIN WORK W ON T.WorkID = W.WorkID JOIN ARTIST A 84
Ãëàâà 4. Ïðèìåíåíèå SQL
4.3. Òðèããåðû
ON W.ArtistID = A.ArtistID; Ëèñòèíã 4.2.
CREATE OR REPLACE TRIGGER SetAskingPrice BEFORE INSERT ON TRANSACTION FOR EACH ROW DECLARE avgNetPrice numeric(8,2); newPrice numeric(8,2); rowcount integer; BEGIN SELECT Count(*) INTO rowcount FROM TRANSACTION WHERE WorkID = :new.WorkID; IF rowcount = 0 THEN :new.AskingPrice := 2*(:new.AcquisitionPrice); ELSE SELECT AVG(NetPrice) INTO avgNetPrice FROM ArtistWorkNet AW WHERE AW.WorkID = :new.WorkID GROUP BY AW.WorkID; newPrice := avgNetPrice + :new.AcquisitionPrice; IF newPrice > 2*(:new.AcquisitionPrice) THEN :new.AskingPrice := newPrice; ELSE :new.AskingPrice := 2*(:new.AcquisitionPrice); END IF; END IF; END; / 85
4.3. Òðèããåðû
Ãëàâà 4. Ïðèìåíåíèå SQL
Òðèããåð ñíà÷àëà ïîäñ÷èòûâàåò êîëè÷åñòâî ñòðîê â òàáëèöå TRANSACTION, â êîòîðûõ çíà÷åíèå WorkID ðàâíî :new.WorkID. Ïîñêîëüêó ýòî ïðåäâàðÿþùèé òðèããåð, ïðîèçâåäåíèå åùå íå äîáàâëåíî â áàçó äàííûõ, è êîëè÷åñòâî áóäåò ðàâíûì íóëþ, åñëè ýòî ïðîèçâåäåíèå íå ïîÿâëÿëîñü â ãàëåðåå ðàíåå.  ýòîì ñëó÷àå :new.AskingPrice óñòàíàâëèâàåòñÿ ðàâíûì óäâîåííîìó çíà÷åíèþ AcquisitionPrice. Åñëè ïðîèçâåäåíèå ïîÿâëÿëîñü â ãàëåðåå â ïðîøëîì, ðàññ÷èòûâàåòñÿ ñðåäíÿÿ ÷èñòàÿ ïðèáûëü îò åãî ïðîäàæè ñ ïîìîùüþ ïðåäñòàâëåíèÿ ArtistWorkNet. Ïîñëå ýòîãî âû÷èñëÿåòñÿ ïåðåìåííàÿ newPrice êàê ñóììà ñðåäíåé ÷èñòîé ïðèáûëè è ñòîèìîñòè ïðèîáðåòåíèÿ. Íàêîíåö, :new.AskingPrice ïðèñâàèâàåòñÿ áîëüøåå èç äâóõ çíà÷åíèé newPrice èëè óäâîåííîå çíà÷åíèå AcquisitionPrice. Òàê êàê òðèããåð ïðåäâàðÿþùèé, äëÿ óñðåäíåíèÿ ìîæíî èñïîëüçîâàòü âñòðîåííóþ ôóíêöèþ AVG: íîâàÿ ñòðîêà åùå íå äîáàâëåíà â òàáëèöó WORK, ïîýòîìó îíà íå áóäåò ó÷òåíà ïðè ðàñ÷åòå ñðåäíåãî çíà÷åíèÿ. Ñëåäóåò îáðàòèòü âíèìàíèå íà îäèí íüþàíñ: åñëè â êàêîé-ëèáî èç ñòðîê ïðåäñòàâëåíèÿ ArtistWorkNet ñòîëáåö SalesPrice èëè AcquisitionPrice ÿâëÿåòñÿ ïóñòûì, ýòî ìîæåò âûçâàòü ïðîáëåìû ïðè âû÷èñëåíèÿõ â òðèããåðå. Ðàññìîòðåííûé òðèããåð âûïîëíÿåò ïîëåçíóþ ôóíêöèþ, èçáàâëÿÿ ïåðñîíàë ãàëåðåè îò çíà÷èòåëüíîãî êîëè÷åñòâà ðó÷íîé ðàáîòû, à òàêæå ïîâûøàÿ òî÷íîñòü ðåçóëüòàòîâ. 4.3.3
Òðèããåð, îáíîâëÿþùèé ïðåäñòàâëåíèå
Îáíîâëåíèå ïðåäñòàâëåíèé â ðÿäå ñëó÷àåâ ìîæåò îêàçàòüñÿ çàòðóäíèòåëüíûì. Îäíà èç òàêèõ ïðîáëåì êàñàåòñÿ ïðåäñòàâëåíèé, ñîçäàííûõ ïðè ïîìîùè îïåðàöèè ñîåäèíåíèÿ: êàê ïðàâèëî, ÑÓÁÄ íå ñïîñîáíà îáíîâëÿòü òàáëèöû, ëåæàùèå â îñíîâå òàêèõ ïðåäñòàâëåíèé. Îäíàêî, çíàÿ ñïåöèôèêó êîíêðåòíîãî ïðèëîæåíèÿ, ìîæíî îïðåäåëèòü, êàê ñëåäóåò èíòåðïðåòèðîâàòü çàïðîñ íà îáíîâëåíèå ñîåäèíåííîãî ïðåäñòàâëåíèÿ. Ðàññìîòðèì ïðåäñòàâëåíèå CustomerInterests, îïðåäåëåííîå ðàíåå â ýòîé ãëàâå íà ñòð. 77. Îíî ñîäåðæèò ñòðîêè òàáëèö CUSTOMER è ARTIST, ñîåäèíåííûå ÷åðåç òàáëèöó ïåðåñå÷åíèÿ. Ñòîëáöó CUSTOMER.Name äàí ïñåâäîíèì Customer, à ñòîëáöó ARTIST.Name Artist. Çàïðîñ íà èçìåíåíèå èìåíè êëèåíòà â ïðåäñòàâëåíèè CustomerInterests ìîæíî èíòåðïðåòèðîâàòü êàê çàïðîñ íà èçìåíåíèå ñòîëáöà Name â òàá86
Ãëàâà 4. Ïðèìåíåíèå SQL
4.3. Òðèããåðû
ëèöå CUSTOMER. Òàêîé çàïðîñ, îäíàêî, ìîæåò áûòü îáðàáîòàí ëèøü â òîì ñëó÷àå, åñëè ýòî èìÿ ÿâëÿåòñÿ óíèêàëüíûì â òàáëèöå CUSTOMER.  ïðîòèâíîì ñëó÷àå íåâîçìîæíî áóäåò îïðåäåëèòü, êàêóþ èç ñòðîê ñëåäóåò îáíîâëÿòü.  ëèñòèíãå 4.3 ïðèâåäåí òåêñò çàìåùàþùåãî òðèããåðà, êîòîðûé îáíîâëÿåò èìÿ êëèåíòà, åñëè ýòî èìÿ ÿâëÿåòñÿ óíèêàëüíûì â áàçå äàííûõ. Âìåñòî òîãî ÷òîáû ïîäñ÷èòûâàòü êîëè÷åñòâî ñòðîê ñ äàííûì èìåíåì êëèåíòà è âûïîëíÿòü îáíîâëåíèå òîëüêî â òîì ñëó÷àå, åñëè òàêàÿ ñòðîêà âñåãî îäíà, òðèããåð îáóñëîâëèâàåò îáíîâëåíèå êëþ÷åâûì ñëîâîì NOT EXISTS. Òàêàÿ êîíñòðóêöèÿ òðèããåðà ïîçâîëÿåò Oracle îïòèìèçèðîâàòü SQL-îïåðàòîð è ïðèâîäèò ê ëó÷øåé ïðîèçâîäèòåëüíîñòè. Ëèñòèíã 4.3.
CREATE OR REPLACE TRIGGER CustomerInterests_Update INSTEAD OF UPDATE ON CustomerInterests FOR EACH ROW BEGIN UPDATE CUSTOMER C1 SET C1.Name = :new.Customer WHERE C1.Name = :old.Customer AND NOT EXISTS (SELECT * FROM CUSTOMER C2 WHERE C2.Name = C1.Name AND C2.CustomerID <> C1.CustomerID); END; / 4.3.4
Òðèããåð, îáåñïå÷èâàþùèé ññûëî÷íóþ öåëîñòíîñòü
Ñîãëàñíî ðèñ. 1.1, òàáëèöà WORK ðàññìàòðèâàåìîãî â ïîñîáèè ïðèìåðà èìååò îáÿçàòåëüíîãî ïîòîìêà â òàáëèöå TRANSACTION. Ýòî îçíà÷àåò, 87
4.3. Òðèããåðû
Ãëàâà 4. Ïðèìåíåíèå SQL
÷òî âñÿêèé ðàç êîãäà â òàáëèöó WORK âñòàâëÿåòñÿ ñòðîêà, íåîáõîäèìî âñòàâèòü ñîîòâåòñòâóþùóþ åé ñòðîêó â òàáëèöó TRANSACTION. Ðåàëèçîâàòü òàêèå îãðàíè÷åíèÿ ññûëî÷íîé öåëîñòíîñòè íåïðîñòî. Ïåðâîå, ÷òî ïðèõîäèò â ãîëîâó, ýòî ñîçäàòü çàâåðøàþùèé òðèããåð äëÿ òàáëèöû WORK, êîòîðûé áû ïðîâåðÿë, ÷òî ïðèëîæåíèå ñîçäàëî òðåáóåìóþ ñòðîêó â òàáëèöå TRANSACTION. Îäíàêî ëþáîé òàêîé òðèããåð áóäåò çàïóñêàòüñÿ íåïîñðåäñòâåííî ïîñëå âñòàâêè ñòðîêè â òàáëèöó WORK, òî åñòü äî òîãî êàê ïðèëîæåíèå ïîëó÷èò øàíñ âñòàâèòü íîâóþ ñòðîêó â òàáëèöó TRANSACTION. Òàêèì îáðàçîì, òðèããåð íå ñìîæåò óâèäåòü ñòðîêó, êîòîðóþ ñîáèðàåòñÿ âñòàâèòü ïðèëîæåíèå. Äðóãîå ðåøåíèå ïîòðåáîâàòü îò ïðèëîæåíèÿ ñîçäàòü ñòðîêó â òàáëèöå TRANSACTION ïåðåä òåì, êàê âñòàâèòü íîâóþ ñòðîêó â òàáëèöó WORK. Íî â ýòîì ñëó÷àå ìû ïåðåîïðåäåëÿåì ñâÿçü òàê, ÷òî òåïåðü ñòðîêà â òàáëèöå TRANSACTION òðåáóåò ñòðîêè â òàáëèöå WORK. Ïîýòîìó ÑÓÁÄ îòêàæåòñÿ âñòàâëÿòü â òàáëèöó TRANSACTION ñòðîêó, íå èìåþùóþ ðîäèòåëÿ, è ñäåëàåò îíà ýòî åùå äî òîãî, êàê áóäåò âûçâàí êàêîé-ëèáî òðèããåð òàáëèöû TRANSACTION. Òàêèì îáðàçîì, òðèããåð, îïðåäåëåííûé äëÿ òàáëèöû TRANSACTION, íèêîãäà íå ïîëó÷èò âîçìîæíîñòè ñîçäàòü òðåáóåìóþ ñòðîêó â òàáëèöå WORK. Îäíî âîçìîæíîå, õîòÿ è íå î÷åíü êðàñèâîå, ðåøåíèå çàêëþ÷àåòñÿ â òîì, ÷òîáû ñîçäàòü ïàðó òðèããåðîâ. Ïåðâûé èç íèõ áóäåò ñîçäàâàòü ñòðîêó â òàáëèöå TRANSACTION ïðè âñòàâêå ñòðîêè â òàáëèöó WORK. Âòîðîé òðèããåð áóäåò óäàëÿòü ñòðîêó, âñòàâëåííóþ ïî óìîë÷àíèþ, êîãäà ïðèëîæåíèå çàõî÷åò âñòàâèòü ñòðîêó â òàáëèöó TRANSACTION. Ïðè òàêîì ïîäõîäå, åñëè ïðèëîæåíèå íå ñîçäàñò òðåáóåìîé ñòðîêè, áóäåò èñïîëüçîâàòüñÿ ñòðîêà, âñòàâëåííàÿ òðèããåðîì. Åñëè ïðèëîæåíèå ñîçäàñò íîâóþ ñòðîêó â òàáëèöå TRANSACTION, òî âñòàâëåííàÿ ïî óìîë÷àíèþ ñòðîêà áóäåò ïðåäâàðèòåëüíî óäàëåíà. Ýòà ïàðà òðèããåðîâ ïðåäñòàâëåíà â ëèñòèíãàõ 4.4 è 4.5. Òðèããåð, èçîáðàæåííûé â ëèñòèíãå 4.4, ñîçäàåò ñòðîêó ïî óìîë÷àíèþ â òàáëèöå TRANSACTION. Ñíà÷àëà îí ïðîâåðÿåò, íåò ëè â ýòîé òàáëèöå ñóùåñòâóþùåé ñòðîêè ñ òàêèì WorkID; åñëè íåò, îí âñòàâëÿåò íîâóþ ñòðîêó. Âòîðîé òðèããåð (ëèñòèíã 4.5) óäàëÿåò ñòðîêó, ñîçäàííóþ ïåðâûì òðèããåðîì, êîãäà ïîëüçîâàòåëü âñòàâëÿåò ñîîòâåòñòâóþùóþ ñòðîêó â òàáëèöó TRANSACTION. 88
Ãëàâà 4. Ïðèìåíåíèå SQL
4.3. Òðèããåðû
Ëèñòèíã 4.4.
CREATE OR REPLACE TRIGGER EnforceTransChild AFTER INSERT ON WORK FOR EACH ROW DECLARE RowCount int; NewID int; BEGIN NewID := :new.WorkID; SELECT Count(*) INTO RowCount FROM TRANSACTION WHERE WorkID = NewID AND CustomerID IS NULL; IF RowCount = 0 THEN INSERT INTO TRANSACTION (TransactionID, DateAcquired, WorkID) VALUES (TransID.NextVal, SysDate, NewID); END IF; END; / Ëèñòèíã 4.5.
CREATE OR REPLACE TRIGGER RemoveDupTrans BEFORE INSERT ON TRANSACTION FOR EACH ROW BEGIN DELETE FROM TRANSACTION WHERE WorkID = :new.WorkID AND CustomerID IS NULL AND TransactionID <> :new.TransactionID; END; / 89
4.4. Õðàíèìûå ïðîöåäóðû
Ãëàâà 4. Ïðèìåíåíèå SQL
Òåì íå ìåíåå ýòî ðåøåíèå íåëüçÿ íàçâàòü óäîâëåòâîðèòåëüíûì. Åùå îäíà àëüòåðíàòèâà, áîëåå ñëîæíàÿ â ðåàëèçàöèè, íî ýñòåòè÷åñêè áîëåå ïðèâëåêàòåëüíàÿ, ïîòðåáîâàòü îò ïðèëîæåíèÿ, ÷òîáû íîâûå ïðîèçâåäåíèÿ äîáàâëÿëèñü â áàçó äàííûõ ÷åðåç ïðåäñòàâëåíèå, ñîäåðæàùåå âñå íåîáõîäèìûå äàííûå äëÿ òàáëèöû WORK è TRANSACTION.  ýòîì ñëó÷àå âñòàâêó äàííûõ èç ïðåäñòàâëåíèÿ WORK/TRANSACTION â òàáëèöû WORK è TRANSACTION îñóùåñòâëÿë áû òðèããåð, à ïðÿìóþ âñòàâêó ñòðîê â ýòè òàáëèöû ñëåäîâàëî áû çàïðåòèòü.
4.4
Õðàíèìûå ïðîöåäóðû
(stored procedure) ýòî ïðîãðàììà, êîòîðàÿ âûïîëíÿåò íåêîòîðûå äåéñòâèÿ ñ èíôîðìàöèåé â áàçå äàííûõ è ïðè ýòîì ñàìà õðàíèòñÿ â áàçå äàííûõ.  Oracle õðàíèìûå ïðîöåäóðû ìîæíî ìîæíî ïèñàòü íà ÿçûêàõ PL/SQL è Java. Õðàíèìûå ïðîöåäóðû ìîãóò âõîäíûå ïàðàìåòðû è âîçâðàùàòü ðåçóëüòàòû.  îòëè÷èå îò òðèããåðîâ, êîòîðûå ïðèíàäëåæàò îïðåäåëåííîé òàáëèöå èëè ïðåäñòàâëåíèþ, õðàíèìûå ïðîöåäóðû ïðèíàäëåæàò áàçå äàííûõ â öåëîì. Îíè ìîãóò âûçûâàòüñÿ ëþáûì ïðîöåññîì, èñïîëüçóþùèì áàçó äàííûõ, ïðè óñëîâèè, ÷òî ó ýòîãî ïðîöåññà åñòü äîñòàòî÷íûå ïðàâà äîñòóïà. Õðàíèìûå ïðîöåäóðû èñïîëüçóþòñÿ äëÿ ìíîãèõ öåëåé. Õîòÿ àäìèíèñòðàòîðû áàç äàííûõ èñïîëüçóþò èõ äëÿ âûïîëíåíèÿ ðóòèííûõ çàäà÷ àäìèíèñòðèðîâàíèÿ, ãëàâíîé îáëàñòüþ èõ ïðèìåíåíèÿ ÿâëÿþòñÿ âñå æå ïðèëîæåíèÿ áàç äàííûõ. Ýòè ïðîöåäóðû ìîãóò âûçûâàòüñÿ èç ïðèêëàäíûõ ïðîãðàìì, íàïèñàííûõ íà òàêèõ ÿçûêàõ, êàê Java, C#, C++ èëè VB.Net, à òàêæå èç âåá-ñöåíàðèåâ, íàïèñàííûõ íà VBScript èëè JavaScript. Êðîìå òîãî, ýòè ïðîöåäóðû ìîæíî âûçûâàòü â èíòåðàêòèâíîì ðåæèìå èç êîìàíäíîé îáîëî÷êè SQL*Plus. Ìîæíî âûäåëèòü ñëåäóþùèå ïðåèìóùåñòâà õðàíèìûõ ïðîöåäóð: Õðàíèìàÿ ïðîöåäóðà
• Áîëüøàÿ áåçîïàñíîñòü. • Ìåíüøèé ñåòåâîé òðàôèê. • SQL ìîæíî îïòèìèçèðîâàòü. • Ñîâìåñòíîå èñïîëüçîâàíèå êîäà ìåæäó ðàçðàáîò÷èêàìè. 90
Ãëàâà 4. Ïðèìåíåíèå SQL
4.4. Õðàíèìûå ïðîöåäóðû
 îòëè÷èå îò êîäà ïðèëîæåíèé, õðàíèìûå ïðîöåäóðû íèêîãäà íå ïåðåäàþòñÿ íà êëèåíòñêèå êîìïüþòåðû. Îíà âñåãäà íàõîäÿòñÿ â áàçå äàííûõ è âûïîëíÿþòñÿ ÑÓÁÄ íà òîì êîìïüþòåðå, ãäå ðàñïîëàãàåòñÿ ñåðâåð áàçû äàííûõ. Òàêèì îáðàçîì, îíè áîëåå áåçîïàñíû, ÷åì ðàñïðîñòðàíÿåìûé êîä ïðèëîæåíèÿ, à êðîìå òîãî, ñíèæàþò ñåòåâîé òðàôèê. Õðàíèìûå ïðîöåäóðû ïîñòåïåííî ñòàíîâÿòñÿ ïðåäïî÷òèòåëüíûì ðåæèìîì ðåàëèçàöèè ëîãèêè ïðèëîæåíèÿ â ñåòè Èíòåðíåò è êîðïîðàòèâíûõ èíòðàñåòÿõ. Åùå îäíî ïðåèìóùåñòâî õðàíèìûõ ïðîöåäóð çàêëþ÷àåòñÿ â òîì, ÷òî SQL-îïåðàòîðû â íèõ ìîãóò áûòü îïòèìèçèðîâàíû êîìïèëÿòîðîì ÑÓÁÄ. Ïðèìåð õðàíèìîé ïðîöåäóðû
Ïðåäïîëîæèì, äëÿ íàøåãî ïðèìåðà òðåáóåòñÿ âîçìîæíîñòü äîáàâëÿòü â áàçó äàííûõ ñâåäåíèÿ î íîâûõ êëèåíòàõ è î òîì, êàêèìè õóäîæíèêàìè îíè èíòåðåñóþòñÿ.  ÷àñòíîñòè, íóæíî çàïèñûâàòü èìÿ è òåëåôîí êëèåíòà, à òàêæå ñâÿçûâàòü åãî ñî âñåìè õóäîæíèêàìè âûáðàííîé íàöèîíàëüíîñòè.  ëèñòèíãå 4.6 èçîáðàæåíà õðàíèìàÿ ïðîöåäóðà, âûïîëíÿþùàÿ ýòó çàäà÷ó. Ïðîöåäóðà, êîòîðàÿ íàçûâàåòñÿ Customer_Insert, ïðèíèìàåò ÷åòûðå ïàðàìåòðà: newname (èìÿ íîâîãî êëèåíòà), newareacode (êîä ðåãèîíà), newphone (òåëåôîí) è artistnationality (íàöèîíàëüíîñòü õóäîæíèêà). Êëþ÷åâîå ñëîâî IN óêàçûâàåò íà òî, ÷òî âñå ýòè ïàðàìåòðû ÿâëÿþòñÿ âõîäíûìè. Âûõîäíûå ïàðàìåòðû (êîòîðûõ ó ýòîé ïðîöåäóðû íåò) îáîçíà÷àþòñÿ êëþ÷åâûì ñëîâîì OUT, à ïàðàìåòðû, èãðàþùèå ðîëü è âõîäíûõ è âûõîäíûõ, ñî÷åòàíèåì IN OUT. Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî äëÿ ïàðàìåòðà óêàçûâàåòñÿ òîëüêî òèï äàííûõ, à äëèíà íå óêàçûâàåòñÿ. Oracle îïðåäåëèò äëèíó èç êîíòåêñòà. Ëèñòèíã 4.6.
CREATE OR REPLACE PROCEDURE Customer_Insert ( newname IN char, newareacode IN char, newphone IN char, artistnationality IN char ) AS 91
4.4. Õðàíèìûå ïðîöåäóðû
rowcount
Ãëàâà 4. Ïðèìåíåíèå SQL
integer(2);
CURSOR artistcursor IS SELECT ArtistID FROM ARTIST WHERE Nationality = artistnationality; BEGIN SELECT Count(*) INTO rowcount FROM CUSTOMER WHERE Name = newname AND AreaCode = newareacode AND PhoneNumber = newphone; IF rowcount > 0 THEN BEGIN DBMS_OUTPUT.PUT_LINE ('There is client in DB! Count is ' || rowcount); RETURN; END; END IF; INSERT INTO CUSTOMER (CustomerID, Name, AreaCode, PhoneNumber) VALUES (CustID.NextVal, newname, newareacode, newphone); FOR artist IN artistcursor LOOP INSERT INTO CUSTOMER_ARTIST_INT (CustomerID, ArtistID) VALUES (CustID.CurrVal, artist.ArtistID); END LOOP; DBMS_OUTPUT.PUT_LINE ('Client is added!'); END; / 92
Ãëàâà 4. Ïðèìåíåíèå SQL
4.4. Õðàíèìûå ïðîöåäóðû
Ðàçäåë îáúÿâëåíèÿ ïåðåìåííûõ ñëåäóåò çà êëþ÷åâûì ñëîâîì AS. Îïåðàòîð SELECT îïðåäåëÿåò ïåðåìåííóþ-êóðñîð (cursor variable) ñ èìåíåì artistcursor. Ýòîò êóðñîð âûäåëÿåò èç òàáëèöû ARTIST äëÿ îáðàáîòêè ñòðîêè âñåõ õóäîæíèêîâ çàäàííîé íàöèîíàëüíîñòè.  ïåðâîé ÷àñòè ïðîöåäóðû ïðîâåðÿåòñÿ, åñòü ëè â áàçå èíôîðìàöèÿ î äàííîì êëèåíòå.  ýòîì ñëó÷àå íèêàêèå äåéñòâèÿ íå ïðåäïðèíèìàþòñÿ, à ïîëüçîâàòåëþ ñ ïîìîùüþ ïàêåòà Oracle DBMS_OUTPUT âûâîäèòñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå. Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òî äëÿ âûâîäà ñòðîêè è çíà÷åíèÿ ïåðåìåííîé èñïîëüçóåòñÿ ñëåäóþùèé ñèíòàêñèñ:
DBMS_OUTPUT.PUT_LINE ('<ñòðîêà>' || <ïåðåìåííàÿ>); Ïîëüçîâàòåëü ïîëó÷èò ýòî ñîîáùåíèå òîëüêî â òîì ñëó÷àå, åñëè ïðîöåäóðà áóäåò âûçâàíà èç SQL*Plus.  ñëó÷àå âûçîâà ïðîöåäóðû èíûì ïóòåì, íàïðèìåð ñ ïîìîùüþ áðàóçåðà ÷åðåç Èíòåðíåò, ïîëüçîâàòåëü íå óâèäèò ýòîãî ñîîáùåíèÿ. ×òîáû ñîîáùèòü ïîëüçîâàòåëþ îá îøèáêå, ðàçðàáîò÷èê äîëæåí âîñïîëüçîâàòüñÿ âûõîäíûì ïàðàìåòðîì èëè ñãåíåðèðîâàòü èñêëþ÷åíèå. Êðîìå òîãî, ÷òîáû òàêèå ñîîáùåíèÿ ñòàëè âèäèìûìè, ñëåäóåò âûïîëíèòü êîìàíäó
Set serveroutput on; Åñëè ïðè ðàáîòå â SQL*Plus âû íå âèäèòå ñîîáùåíèé, âûâîäèìûõ âàøèìè ïðîöåäóðàìè, òî, ñêîðåå âñåãî, âû íå âûïîëíèëè ýòîò îïåðàòîð. Îñòàâøàÿñÿ ÷àñòü ïðîöåäóðû â ëèñòèíãå 4.6 âñòàâëÿåò äàííûå î íîâîì êëèåíòå è çàòåì ïåðåáèðàåò âñåõ õóäîæíèêîâ âûáðàííîé íàöèîíàëüíîñòè. Îáðàòèòå âíèìàíèå íà èñïîëüçîâàíèå ñïåöèàëüíîé êîíñòðóêöèè PL/SQL FOR artist IN artistcursor. Ýòà êîíñòðóêöèÿ âûïîëíÿåò íåñêîëüêî çàäà÷. Ïðåæäå âñåãî, îíà îòêðûâàåò êóðñîð è ñ÷èòûâàåò ïåðâóþ ñòðîêó. Çàòåì îíà ïîñëåäîâàòåëüíî îáðàáàòûâàåò âñå ñòðîêè ïîä êóðñîðîì è ïî îêîí÷àíèè îáðàáîòêè ïåðåäàåò óïðàâëåíèå ñëåäóþùåìó îïåðàòîðó ïîñëå FOR. Çàìåòüòå òàêæå, ÷òî îáðàùåíèå ê ñòîëáöó ArtistID òåêóùåé ñòðîêè ïðîèñõîäèò ñ èñïîëüçîâàíèåì ñèíòàêñèñà artist.ArtistID, ãäå artist ýòî èìÿ ïåðåìåííîé öèêëà FOR, à íå êóðñîðà. Ïîñëå òîãî êàê ïðîöåäóðà íàïèñàíà, åå íåîáõîäèìî ñêîìïèëèðîâàòü è ñîõðàíèòü â áàçå äàííûõ. Åñëè òåêñò ïðîöåäóðû ñîõðàíåí â ôàéëå, òî ïðîöåäóðà áóäåò ñêîìïèëèðîâàíà è ñîõðàíåíà â áàçå äàííûõ àâòîìàòè÷åñêè ïîñëå ââîäà êîìàíäû 93
4.5. Ñëîâàðü äàííûõ
Ãëàâà 4. Ïðèìåíåíèå SQL
start Èìÿ_ôàéëà_ïðîöåäóðû Åñëè âû ÷òî-òî ââåëè íåïðàâèëüíî, ó âàñ ìîãóò âîçíèêíóòü îøèáêè êîìïèëÿöèè. Ê ñîæàëåíèþ, SQL*Plus íå ïîêàæåò âàì ýòè îøèáêè àâòîìàòè÷åñêè, à âûäàñò ñîîáùåíèå "Warning: Procedure created with compilation errors"(Ïðåäóïðåæäåíèå: Ïðè êîìïèëÿöèè ïðîöåäóðû îáíàðóæåíû îøèáêè). ×òîáû óâèäåòü îøèáêè, ââåäèòå êîìàíäó:
Show errors; Åñëè ñèíòàêñè÷åñêèõ îøèáîê íå áûëî, âû ïîëó÷èòå ñîîáùåíèå "Procedure created"(Ïðîöåäóðà ñîçäàíà). Òåïåðü âû ìîæåòå âûçâàòü ýòó ïðîöåäóðó ñ ïîìîùüþ êîìàíäû EXECUTE èëè EXEC:
Exec Customer_Insert('Michael Bench', '203', '555-2014', 'US'); Åñëè âîçíèêíóò îøèáêè íà ýòàïå âûïîëíåíèÿ ïðîöåäóðû, íîìåðà ñòðîê â îò÷åòå îá îøèáêàõ íå áóäóò ñîâïàäàòü ñ íîìåðàìè ñòðîê, êîòîðûå âû ìîæåòå âèäåòü â ñâîåì òåêñòîâîì ðåäàêòîðå.
4.5
Ñëîâàðü äàííûõ
Oracle ïîääåðæèâàåò èñ÷åðïûâàþùèé ñëîâàðü ìåòàäàííûõ. Ýòîò ñëîâàðü îïèñûâàåò ñòðóêòóðó òàáëèö, ïîñëåäîâàòåëüíîñòåé, ïðåäñòàâëåíèé, èíäåêñîâ, îãðàíè÷åíèé, õðàíèìûõ ïðîöåäóð è ìíîãîå äðóãîå. Îí òàêæå ñîäåðæèò èñõîäíûå òåêñòû ïðîöåäóð, ôóíêöèé è òðèããåðîâ.  òàáëèöå DICT ñëîâàðÿ ìåòàäàííûõ ñîäåðæàòñÿ äàííûå, îïèñûâàþùèå ñàì ñëîâàðü. Ìîæíî çàïðàøèâàòü äàííûå èç ýòîé òàáëèöû, ÷òîáû óçíàòü áîëüøå î ñîäåðæèìîì ñëîâàðÿ äàííûõ, íî íóæíî èìåòü â âèäó, ÷òî îíà èìååò áîëüøèå ðàçìåðû. Íàïðèìåð, åñëè çàïðîñèòü èìåíà âñåõ òàáëèö ñëîâàðÿ äàííûõ, áóäåò âîçâðàùåíî áîëåå 800 ñòðîê. Ïðåäïîëîæèì, íóæíî óçíàòü, êàêèå òàáëèöû ñ èíôîðìàöèåé î ïîëüçîâàòåëüñêèõ è ñèñòåìíûõ òàáëèöàõ èìåþòñÿ â ñëîâàðå äàííûõ.  ýòîì ìîæåò ïîìî÷ü ñëåäóþùèé çàïðîñ:
SELECT Table_Name, Contents FROM DICT WHERE Table_Name LIKE ('%TABLES%'); 94
Ãëàâà 4. Ïðèìåíåíèå SQL
4.5. Ñëîâàðü äàííûõ
Áóäåò âîçâðàùåíî îêîëî äâàäöàòè ïÿòè ñòðîê. Îäíà èç òàáëèö áóäåò íàçûâàòüñÿ USER_TABLES. ×òîáû óâèäåòü ñòîëáöû ýòîé òàáëèöû, íóæíî ââåñòè:
DESC USER_TABLES; Ìîæíî èñïîëüçîâàòü ýòó ñòðàòåãèþ äëÿ ïîëó÷åíèÿ èç ñëîâàðÿ ìåòàäàííûõ èíôîðìàöèè îá èíòåðåñóþùèõ îáúåêòàõ è ñòðóêòóðàõ.  òàáë. 4.1 ïåðå÷èñëåíû ìíîãèå èç ïåðäñòàâëåíèé è óêàçàíî èõ íàçíà÷åíèå. Òàáëèöû USER_SOURCE è USER_TRIGGERS ïîëåçíû, êîãäà òðåáóåòñÿ óçíàòü, èñõîäíûå òåêñòû êàêèõ ïðîöåäóð è òðèããåðîâ õðàíÿòñÿ â íàñòîÿùèé ìîìåíò â áàçå äàííûõ. Òàáëèöà 4.1. Ìåòàäàííûå â ÑÓÁÄ Oracle Èìÿ òàáëèöû
DICT USER_CATALOG USER_TABLES USER_TAB_COLUMNS USER_VIEW USER_CONSTRAINTS USER_CONS_COLUMNS USER_TRIGGERS
USER_SOURCE
Ñîäåðæèìîå
Ìåòàäàííûå, îïèñûâàþùèå ñëîâàðü äàííûõ Ñïèñîê òàáëèö, ïðåäñòàâëåíèé, ïîñëåäîâàòåëüíîñòåé è äðóãèõ ñòðóêòóð, ïðèíàäëåæàùèõ ïîëüçîâàòåëþ Ñòðóêòóðû òàáëèö ïîëüçîâàòåëÿ Ïîòîìîê òàáëèöû USER_TABLES. Ñîäåðæèò äàííûå î ñòîëáöàõ òàáëèö. Ñèíîíèìîì ÿâëÿåòñÿ COLS Ïîëüçîâàòåëüñêèå ïðåäñòàâëåíèÿ Ïîëüçîâàòåëüñêèå îãðàíè÷åíèÿ Ïîòîìîê òàáëèöû USER_CONSTRAINTS. Ñîäåðæèò ñòîëáöû, íà êîòîðûå íàëîæåíû îãðàíè÷åíèÿ Ìåòàäàííûå, îïèñûâàþùèå òðèããåðû. Åñòü ñìûñë çàïðàøèâàòü ñòîëáöû Trigger_Name, Trigger_Type è Trigger_Event. Ïðåäóïðåæäåíèå: Trigger_Body â äåéñòâèòåëüíîñòè íå ñîäåðæèò èñõîäíîãî êîäà òðèããåðà Èñõîäíûå òåêñòû. Íàïðèìåð, äëÿ ïîëó÷åíèÿ òåêñòà ïðîöåäóðû MYTRIGGER: SELECT Text FROM USER_SOURCE WHERE Name = 'MYTRIGGER' AND Type = 'PROCEDURE'
95
4.5. Ñëîâàðü äàííûõ
Ãëàâà 4. Ïðèìåíåíèå SQL
96
Ãëàâà 5 Äîïîëíèòåëüíûå âîçìîæíîñòè Oracle  ýòîé ãëàâå ðàññìàòðèâàþòñÿ ôóíêöèè è îïåðàòîðû Oracle, êîòîðûå ìîãóò áûòü ïîëåçíûìè ïðè ðàçðàáîòêè ðåàëüíûõ ïðåäìåòíîîðèåíòèðîâàííûõ áàç äàííûõ, à òàêæå äëÿ èõ íàñòðîéêè è òåñòèðîâàíèÿ.
5.1
Ñèñòåìíàÿ òàáëèöà DUAL
 íåêîòîðûõ ñëó÷àÿõ ìîæåò ïîòðåáîâàòüñÿ âåðíóòü ïðè ïîìîùè çàïðîñà ðåçóëüòàò ðàáîòû íåêîòîðîé õðàíèìîé ôóíêöèè èëè ðåçóëüòàò âû÷èñëåíèÿ.  ýòîì ñëó÷àå ìîæíî èñïîëüçîâàòü ñïåöèàëüíóþ ñèñòåìíóþ òàáëèöó DUAL, äîñòóïíóþ âñåì ïîëüçîâàòåëÿì è âñåãäà ñîäåðæàùóþ åäèíñòâåííûé ñòîëáåö ñ èìåíåì DUMMY è òèïîì VARCHAR2(1) è åäèíñòâåííóþ ñòðîêó. Ïðèìåð çàïðîñà, ïðîèçâîäÿùåãî âû÷èñëåíèÿ è ïðèìåíÿþùåãî òàáëèöó DUAL:
SELECT 4 + 5*20 FROM DUAL  êà÷åñòâå äðóãîãî ïðèìåðà ñ èñïîëüçîâàíèåì òàáëèöû DUAL ìîæíî ðàññìîòðåòü âûçîâ ôóíêöèè SYSDATE, âîçâðàùàþùåé òåêóùóþ äàòó:
SELECT SYSDATE FROM DUAL
5.2
Ïñåâäîñòîëáåö ROWID
Ïñåâäîñòîëáöàìè â Oracle ïðèíÿòî íàçûâàòü ñòîëáöû, êîòîðûå îòñóòñòâóþò â òàáëèöàõ â ÿâíîì âèäå, íî ìîãóò áûòü èñïîëüçîâàíû â çàïðîñàõ. 97
5.2. Ïñåâäîñòîëáåö ROWID
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
Íàèáîëåå óïîòðåáèìûì è âàæíûì èç íèõ ÿâëÿåòñÿ ROWID ïñåâäîñòîëáåö, ÿâëÿþùèéñÿ óíèêàëüíûì èäåíòèôèêàòîðîì ñòðîêè. Îí íå ïðîñòî ãàðàíòèðîâàííî óíèêàëåí â ðàìêàõ òàáëèöû áîëåå òîãî: îí óíèêàëåí â ðàìêàõ áàçû äàííûõ. Ñ ôèçè÷åñêîé òî÷êè çðåíèÿ ROWID ÿâëÿåòñÿ ñâîåîáðàçíîé êîîðäèíàòîé çàïèñè â áàçå. Íåîáõîäèìî îòìåòèòü, ÷òî ñóùåñòâîâàíèå ROWID ïðîòèâîðå÷èò êàê ìèíèìóì äâóì èç äâåíàäöàòè èçâåñòíûõ ïðàâèë Êîääà, îïèñûâàþùèõ òðåáîâàíèÿ ê ðåëÿöèîííîé ÑÓÁÄ. Âî-ïåðâûõ, ROWID íàðóøàåò ïðàâèëî íîìåð 2, êîòîðîå ãëàñèò: ¾Ê êàæäîìó ýëåìåíòó äàííûõ äîëæåí áûòü îáåñïå÷åí äîñòóï ïðè ïîìîùè êîìáèíàöèè èìåíè òàáëèöû, ïåðâè÷íîãî êëþ÷à ñòðîêè è èìåíè ñòîëáöà¿.  äàííîì ñëó÷àå ROWID íå ÿâëÿåòñÿ ïåðâè÷íûì êëþ÷îì, õîòÿ ââèäó åãî óíèêàëüíîñòè äëÿ êàæäîé ñòðîêè îí ìîæåò âûñòóïàòü â ðîëè ïåðâè÷íîãî êëþ÷à. Âî-âòîðûõ, íàðóøàåòñÿ ïðàâèëî Êîääà íîìåð 8: ¾Ïðèêëàäíûå ïðîãðàììû íå äîëæíû çàâèñåòü îò èñïîëüçóåìûõ ñïîñîáîâ õðàíåíèÿ äàííûõ íà íîñèòåëÿõ è ìåòîäîâ îáðàùåíèÿ ê íèì¿. Íàðóøåíèå ýòîãî ïðàâèëà ïðîèñõîäèò èç-çà òîãî, ÷òî ROWID ïî ñâîåé ñóòè ÿâëÿåòñÿ ôèçè÷åñêîé êîîðäèíàòîé çàïèñè, ïîýòîìó îí áóäåò èçìåíÿòüñÿ â ñëó÷àå ïåðåñîçäàíèÿ òàáëèöû, ïåðåçàãðóçêè äàííûõ, ïåðåìåùåíèÿ òàáëèöû èç îäíîãî òàáëè÷íîãî ïðîñòðàíñòâà â äðóãîå è ò.ï. Îäíàêî ROWID óíèêàëåí è íåèçìåíåí â òå÷åíèå ñåàíñà ïîëüçîâàòåëÿ, ïîýòîìó ïðèëîæåíèå ìîæåò ñ÷èòàòü åãî íåèçìåííûì. ROWID ñóùåñòâåííî óïðîùàåò ðàáîòó ñ áàçîé äàííûõ, ïîñêîëüêó ïîçâîëÿåò îäíîçíà÷íî èäåíòèôèöèðîâàòü ëþáóþ ñòðîêó òàáëèöû, ÷òî, â ÷àñòíîñòè, ïîçâîëÿåò óäàëÿòü è ðåäàêòèðîâàòü ñòðîêè òàáëèö áåç ïåðâè÷íîãî êëþ÷à. Êðîìå òîãî, ïîèñê ñòðîêè ïî åå ROWID ÿâëÿåòñÿ ñàìûì áûñòðûì èç âîçìîæíûõ, ÷òî ïîëîæèòåëüíî ñêàçûâàåòñÿ íà áûñòðîäåéñòâèè ïðèëîæåíèé, àêòèâíî ìîäèôèöèðóþùèõ äàííûå. Îäíàêî ROWID ÿâëÿåòñÿ ñïåöèôè÷åñêîé îñîáåííîñòüþ Oracle, à ñëåäîâàòåëüíî, åãî íåëüçÿ ïðèìåíÿòü ïðè ðàçðàáîòêå ïðèëîæåíèé, ðàññ÷èòàííûõ íà ðàáîòó ñ áàçàìè äðóãèõ òèïîâ. Ðàññìîòðèì ïðîñòåéøèé ïðèìåð çàïðîñà, èçâëåêàþùåãî ROWID ñòðîê:
SELECT ROWID, Name FROM ARTIST; 98
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.3
5.3. Ïñåâäîñòîëáåö ROWNUM
Ïñåâäîñòîëáåö ROWNUM
Êàê è ROWID, ïñåâäîñòîëáåö ROWNUM ÿâëÿåòñÿ ñïåöèôè÷íûì äëÿ Oracle. ROWNUM ñîäåðæèò ïîðÿäêîâûé íîìåð ñòðîêè çàïðîñà, íàïðèìåð:
SELECT ROWNUM, Name FROM ARTIST;  äàííîì çàïðîñå ïðîèçâîäèòñÿ íóìåðàöèÿ èçâëåêàåìûõ ñòðîê. Îäíàêî ÷àùå âñåãî ROWNUM ïðèìåíÿåòñÿ íå äëÿ íóìåðàöèè, à äëÿ îãðàíè÷åíèÿ êîëè÷åñòâà îáðàáàòûâàåìûõ ñòðîê. Òàê, äàííûé çàïðîñ èçâëåêàåò ïåðâûå ïÿòü ñòðîê äàííûõ:
SELECT ROWNUM, Name FROM ARTIST WHERE ROWNUM <= 5; Ïðè èñïîëüçîâàíèè ROWNUM ñëåäóåò îáðàòèòü âíèìàíèå íà îäèí î÷åíü âàæíûé ìîìåíò: â õîäå âûïîëíåíèÿ çàïðîñà ñíà÷àëà ïðîèçâîäÿòñÿ îòáîð è íóìåðàöèÿ ñòðîê, à çàòåì ñîðòèðîâêà.
5.4
Ôóíêöèÿ NVL
Ôóíêöèÿ NVL, êàê ïðàâèëî, ïðèìåíÿåòñÿ ÷àùå âñåãî. Ôóíêöèÿ ïîëó÷àåò äâà ïàðàìåòðà: NVL(expr1, expr2). Åñëè ïåðâûé ïàðàìåòð expr1 íå ðàâåí NULL, òî ôóíêöèÿ âîçâðàùàåò åãî çíà÷åíèå. Åñëè ïåðâûé ïàðàìåòð NULL, òî âìåñòî íåãî ôóíêöèÿ âîçâðàùàåò çíà÷åíèå âòîðîãî ïàðàìåòðà expr2. Ðàññìîòðèì ïðàêòè÷åñêèé ïðèìåð. Ïîëå BirthDate â òàáëèöå ARTIST ìîæåò ñîäåðæàòü çíà÷åíèÿ NULL. Ïðè âûïîëíåíèè çàïðîñà âèäà:
SELECT Name, BirthDate, NVL(BirthDate, 0) NVL_BirthDate FROM ARTIST çíà÷åíèå NULL áóäåò çàìåíåíî íà íîëü. Îáðàòèòå âíèìàíèå íà òî, ÷òî â ñëó÷àå ôîðìèðîâàíèÿ çíà÷åíèÿ ïðè ïîìîùè ôóíêöèè åìó íàçíà÷àåòñÿ ïñåâäîíèì. Ðåçóëüòàòû çàïðîñà áóäóò èìåòü âèä: 99
5.5. ×èñëîâûå ôóíêöèè
NAME Miro Kandinsky Frings Klee Moos Tobey Matisse Chagall
5.5
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
BIRTHDATE 1870 1854 1700 1900
NVL_BIRTHDATE 1870 1854 1700 1900 0 0 0 0
×èñëîâûå ôóíêöèè
 Oracle ïðåäóñìîòðåí ðÿä âñòðîåííûõ ôóíêöèé äëÿ ðàáîòû ñ ÷èñëàìè. Ôóíêöèÿ ABS(n)
Ôóíêöèÿ ABS âîçâðàùàåò àáñîëþòíîå çíà÷åíèå ÷èñëà. Íàïðèìåð:
SELECT ABS(100) X1, ABS(-100) X2, ABS(-100.2) X3 FROM DUAL X1 100
X2 100
X3 100,2
Ôóíêöèÿ CEIL(n)
Ôóíêöèÿ CEIL âîçâðàùàåò íàèìåíüøåå öåëîå, áîëüøåå èëè ðàâíîå ïåðåäàííîìó â êà÷åñòâå ïàðàìåòðà ÷èñëó n. Íàïðèìåð:
SELECT CEIL(100) X1, CEIL(-100) X2, CEIL(100.2) X3, CEIL(-100.2) X4 FROM DUAL X1 100
X2 -100
X3 101
X4 100 100
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.5. ×èñëîâûå ôóíêöèè
Ôóíêöèÿ FLOOR(n)
Ôóíêöèÿ FLOOR âîçâðàùàåò íàèáîëüøåå öåëîå, ìåíüøåå èëè ðàâíîå ïåðåäàííîìó â êà÷åñòâå ïàðàìåòðà ÷èñëó n. Íàïðèìåð:
SELECT FLOOR(100.22) X1, FLOOR(-100.22) X2, FLOOR(100.99) X3, FLOOR(100.01) X4 FROM DUAL X1 100
X2 -101
X3 100
X4 100
Ôóíêöèÿ TRUNC(n [,m])
Ôóíêöèÿ TRUNC âîçâðàùàåò ÷èñëî n, óñå÷åííîå äî m çíàêîâ ïîñëå äåñÿòè÷íîé òî÷êè. Ïàðàìåòð m ìîæåò íå óêàçûâàòüñÿ â ýòîì ñëó÷àå n óñåêàåòñÿ äî öåëîãî.
SELECT TRUNC(100.25678) X1, TRUNC(-100.25678) X2, TRUNC(100.99) X3, TRUNC(100.25678, 2) X4 FROM DUAL X1 100
X2 -100
X3 100
X4 100.25
Ôóíêöèÿ ROUND(n [,m])
Ôóíêöèÿ ROUND âîçâðàùàåò ÷èñëî n, îêðóãëåííîå äî m çíàêîâ ïîñëå äåñÿòè÷íîé òî÷êè ïî ïðàâèëàì ìàòåìàòè÷åñêîãî îêðóãëåíèÿ. Ïàðàìåòð m ìîæåò íå óêàçûâàòüñÿ â ýòîì ñëó÷àå n îêðóãëÿåòñÿ äî öåëîãî.
SELECT ROUND(100.25678) X1, ROUND(100.5) X2, ROUND(100.99) X3, ROUND(100.25678, 2) X4 FROM DUAL X1 100
X2 101
X3 101
X4 100.26 101
5.5. ×èñëîâûå ôóíêöèè
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
Ôóíêöèÿ SIGN(n)
Ôóíêöèÿ SIGN îïðåäåëÿåò çíàê ÷èñëà. Åñëè n ïîëîæèòåëüíîå, òî ôóíêöèÿ âîçâðàùàåò 1. Åñëè îòðèöàòåëüíîå âîçâðàùàåòñÿ -1. Åñëè ðàâíî íóëþ, òî âîçâðàùàåòñÿ 0. Íàïðèìåð:
SELECT SIGN(100.22) X1, SIGN(-100.22) X2, SIGN(0) X3 FROM DUAL X1 1
X2 -1
X3 0
Ôóíêöèÿ MOD(n, m)
Ôóíêöèÿ MOD âîçâðàùàåò îò äåëåíèÿ n íà m. Íàïðèìåð:
SELECT MOD(10, 3) X1, MOD(10, 2) X2, MOD(100, 0) X3 FROM DUAL X1 1
X2 0
X3 100
Èíòåðåñíîé îñîáåííîñòüþ äàííîé ôóíêöèè ÿâëÿåòñÿ âîçìîæíîñòü ïåðåäà÷è m ðàâíîãî íóëþ ïðè ýòîì íå âîçíèêàåò îøèáêè äåëåíèÿ íà 0. Ôóíêöèÿ POWER(n, m)
Ôóíêöèÿ POWER âîçâîäèò ÷èñëî n â ñòåïåíü m. Ñòåïåíü ìîæåò áûòü äðîáíîé è îòðèöàòåëüíîé, ÷òî ñóùåñòâåííî ðàñøèðÿåò âîçìîæíîñòè äàííîé ôóíêöèè.
SELECT POWER(10, 2) X1, POWER(100, 1/2) X2, POWER(1000, 1/3) X3, POWER(1000, -1/3) X4 FROM DUAL X1 100
X2 10
X3 10
X4 0.1
 íåêîòîðûõ ñëó÷àÿõ ïðè âûçîâå äàííîé ôóíêöèè ìîæåò âîçíèêíóòü èñêëþ÷èòåëüíàÿ ñèòóàöèÿ. Íàïðèìåð: 102
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.5. ×èñëîâûå ôóíêöèè
SELECT POWER(-100, 1/2) X2 FROM DUAL  äàííîì ñëó÷àå ïðîèçâîäèòñÿ ïîïûòêà âû÷èñëåíèÿ êâàäðàòíîãî êîðíÿ îò îòðèöàòåëüíîãî ÷èñëà, ÷òî ïðèâåäåò ê âîçíèêíîâåíèþ îøèáêè ORA01428 ¾Àðãóìåíò âíå äèàïàçîíà¿. Ôóíêöèÿ SQRT(n)
Äàííàÿ ôóíêöèÿ âîçâðàùàåò êâàäðàòíûé êîðåíü îò ÷èñëà n. Íàïðèìåð:
SELECT SQRT(100) X FROM DUAL Ôóíêöèè EXP(n) è LN(n)
Ôóíêöèÿ EXP âîçâîäèò e â ñòåïåíü n, à ôóíêöèÿ LN âû÷èñëÿåò íàòóðàëüíûé ëîãàðèôì îò n (ïðè ýòîì n äîëæíî áûòü áîëüøå íóëÿ). Ïðèìåð:
SELECT EXP(2) X1, LN(1) X2, LN(EXP(2)) X3 FROM DUAL X1 2,71828182845905
X2 0
X3 2
Ïîïûòêà ïåðåäàòü ôóíêöèè LN îòðèöàòåëüíîå çíà÷åíèå ïðèâîäèò ê âîçíèêíîâåíèþ îøèáêè ORA-1428. Ôóíêöèÿ LOG(n, m)
Ôóíêöèÿ LOG ïðîèçâîäèò âû÷èñëåíèå ëîãàðèôìà m ïî îñíîâàíèþ n. Ïðèìåð:
SELECT LOG(2, 8) X1, LOG(10, 100) X2 FROM DUAL X1 3
X2 2 103
5.6. Òðèãîíîìåòðè÷åñêèå ôóíêöèè
5.6
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
Òðèãîíîìåòðè÷åñêèå ôóíêöèè
Oracle ïîääåðæèâàåò âû÷èñëåíèå îñíîâíûõ òðèãîíîìåòðè÷åñêèõ ôóíêöèé:
• SIN(n) ñèíóñ n (ãäå n óãîë â ðàäèàíàõ) • COS(n) êîñèíóñ n (ãäå n óãîë â ðàäèàíàõ) • TAN(n) òàíãåíñ n (ãäå n óãîë â ðàäèàíàõ) • SINH(n) ãèïåðáîëè÷åñêèé ñèíóñ n • COSH(n) ãèïåðáîëè÷åñêèé êîñèíóñ n • TANH(n) ãèïåðáîëè÷åñêèé òàíãåíñ n Ïðèìåð:
SELECT SIN(0) X1, COS(0) X2, TAN(0) X3 FROM DUAL X1 0
5.7
X2 1
X3 0
Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
 ýòîé ÷àñòè ðå÷ü ïîéäåò î ôóíêöèÿõ ðàáîòû ñ òåêñòîâîé èíôîðìàöèåé, êîòîðûå ìîãóò ïðèìåíÿòüñÿ â çàïðîñàõ è ïðîãðàììíîì êîäå íà ÿçûêå PL/SQL. Ôóíêöèÿ CONCAT(str1, str2)
Äàííàÿ ôóíêöèÿ âûïîëíÿåò êîíêàòåíàöèþ ñòðîê str1 è str2. Åñëè îäèí èç àðãóìåíòîâ ðàâåí NULL, òî îí âîñïðèíèìàåòñÿ êàê ïóñòàÿ ñòðîêà. Åñëè îáà àðãóìåíòà ðàâíû NULL, òî ôóíêöèÿ âîçâðàùàåò NULL. Ïðèìåð: 104
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
SELECT CONCAT('Ó ïîïà ', 'áûëà ñîáàêà') x1, CONCAT('Test', NULL) x2, CONCAT(NULL, 'Test') x3, CONCAT(NULL, NULL) x4 FROM dual X1 Ó ïîïà áûëà ñîáàêà
X2 Test
X3 Test
X4 NULL
Äëÿ êîíêàòåíàöèè ñòðîê Oracle ïîääåðæèâàåò ñïåöèàëüíûé îïåðàòîð êîíêàòåíàöèè ¾||¿, êîòîðûé ðàáîòàåò àíàëîãè÷íî ôóíêöèè CONCAT, íàïðèìåð:
SELECT CONCAT('Ó ïîïà ', 'áûëà ñîáàêà') x1, 'Ó ïîïà ' || 'áûëà ñîáàêà' x2 FROM dual X1 Ó ïîïà áûëà ñîáàêà
X2 Ó ïîïà áûëà ñîáàêà
Íå ñëåäóåò ïóòàòü îïåðàòîð êîíêàòåíàöèè ¾||¿, ýêâèâàëåíòíûé âûçîâó ôóíêöèè CONCAT, è îïåðàòîð ¾+¿, ïðèìåíÿåìûé â àðèôìåòè÷åñêèõ îïåðàöèÿõ.  Oracle ýòî ðàçíûå îïåðàòîðû, íî çà ñ÷åò àâòîìàòè÷åñêîãî ïðèâåäåíèÿ òèïîâ âîçìîæíû òðóäíîóëîâèìûå îøèáêè, íàïðèìåð:
SELECT '5' + '3' x1 FROM dual  äàííîì ñëó÷àå âîçâðàùàåòñÿ ÷èñëîâîå çíà÷åíèå 8, à íå òåêñòîâàÿ ñòðîêà ¾53¿. Ýòî ñâÿçàíî ñ òåì, ÷òî, îáíàðóæèâ àðèôìåòè÷åñêóþ îïåðàöèþ ¾+¿, Oracle àâòîìàòè÷åñêè ïûòàåòñÿ ïðèâåñòè àðãóìåíòû ê òèïó NUMBER. Ôóíêöèÿ LOWER(str)
Ôóíêöèÿ LOWER ïðåîáðàçóåò âñå ñèìâîëû ñòðîêè str â ñòðî÷íûå. Ïðèìåð:
SELECT LOWER('TeXt DATA') X FROM dual 105
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
X text data Ôóíêöèÿ UPPER(str)
Ôóíêöèÿ UPPER ïðåîáðàçóåò âñå ñèìâîëû ñòðîêè str â ïðîïèñíûå. Ïðèìåð:
SELECT UPPER('TeXt DATA') X FROM dual X TEXT DATA Ôóíêöèÿ INITCAP(str)
Âîçâðàùàåò ñòðîêó str, â êîòîðîé ïåðâûå áóêâû âñåõ ñëîâ ïðåîáðàçîâàíû â ïðîïèñíûå. Ôóíêöèÿ óäîáíà äëÿ ôîðìàòèðîâàíèÿ ïîëíîãî èìåíè ïðè ïîñòðîåíèè îò÷åòîâ. Ïðèìåð:
SELECT INITCAP('Èâàíî ïåòð ñèÄîðîâè÷') X FROM dual X Èâàíîâ Ïåòð Ñèäîðîâè÷ Ôóíêöèè LTRIM(str [,set]) è RTRIM(str [,set])
Ôóíêöèÿ LTRIM óäàëÿåò âñå ñèìâîëû ñ íà÷àëà ñòðîêè äî ïåðâîãî ñèìâîëà, êîòîðîãî íåò â íàáîðå ñèìâîëîâ set. Ïî óìîë÷àíèþ set ñîñòîèò èç îäíîãî ïðîáåëà è ìîæåò íå óêàçûâàòüñÿ. Ôóíêöèÿ RTRIM àíàëîãè÷íà LTRIM, íî óäàëÿåò ñèìâîëû, íà÷èíàÿ îò êîíöà ñòðîêè. Ðàññìîòðèì íåñêîëüêî ïðèìåðîâ:
SELECT LTRIM(' TeXt DATA') X1, LTRIM(' _ # TeXt DATA', ' #_') X2, LTRIM(' 1234567890 TeXt DATA', ' 1234567890') X3 FROM dual 106
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
X1 TeXt DATA
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
X2 TeXt DATA
X3 TeXt DATA
Ôóíêöèÿ REPLACE(str, search_str, [,replace_str])
Ôóíêöèÿ REPLACE îñóùåñòâëÿåò ïîèñê îáðàçöà search_str â ñòðîêå str è êàæäîå íàéäåííîå âõîæäåíèå çàìåíÿåò íà replace_str. Ïî óìîë÷àíèþ replace_str ðàâåí ïóñòîé ñòðîêå, ïîýòîìó âûçîâ ôóíêöèè REPLACE ñ äâóìÿ àðãóìåíòàìè ïðèâîäèò ê óäàëåíèþ âñåõ íàéäåííûõ âõîæäåíèé. Ïîèñê ïîäñòðîêè âåäåòñÿ ñ ó÷åòîì ðåãèñòðà. Ïðèìåð:
SELECT REPLACE('Ó ïîïà áûëà ñîáàêà', 'ñîáàêà', 'êîøêà') x1, REPLACE('Ó ïîïà áûëà çëàÿ ñîáàêà', 'çëàÿ') x2, REPLACE('Ó ïîïà áûëà ñîáàêà', 'Ñîáàêà', 'Êîøêà') x3 FROM dual X1 Ó ïîïà áûëà êîøêà
X2 Ó ïîïà áûëà ñîáàêà
X3 Ó ïîïà áûëà ñîáàêà
Ôóíêöèÿ TRANSLATE(str, from_mask, to_mask)
Ôóíêöèÿ TRANSLATE àíàëèçèðóåò ñòðîêó str è çàìåíÿåò â íåé âñå ñèìâîëû, âñòðå÷àþùèåñÿ â ñòðîêå from_mask, íà ñîîòâåòñòâóþùèå ñèìâîëû èç to_mask. Äëÿ êîððåêòíîé ðàáîòû ôóíêöèè ñòðîêè from_mask è to_mask äîëæíû èìåòü îäèíàêîâóþ äëèíó èëè ñòðîêà from_mask äîëæíà áûòü äëèííåå, ÷åì to_mask. Åñëè from_mask äëèíåå, ÷åì to_mask, è â ïðîöåññå îáðàáîòêè ñòðîêè str îáíàðóæàòñÿ ñèìâîëû, ñîîòâåòñòâóþùèå îäíîìó èç ñèìâîëîâ from_mask, è ïðè ýòîì èì íå íàéäåòñÿ ñîîòâåòñòâèÿ â to_mask, òî òàêèå ñèìâîëû áóäóò óäàëåíû èç ñòðîêè str. Åñëè ïåðåäàòü from_mask èëè to_mask, ðàâíîå NULL, òî ôóíêöèÿ âîçâðàòèò çíà÷åíèå NULL. Ñðàâíåíèå ïðîèçâîäèòñÿ ñ ó÷åòîì ðåãèñòðà. Ïðèìåðû:
SELECT TRANSLATE('Test 12345', 'e2', 'E!') x1, TRANSLATE('Test 12345', 'e234', 'E') x2 FROM dual 107
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
X1 TEst 1!345
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
X2 TEst 15
Äàííàÿ ôóíêöèÿ óäîáíà äëÿ ðåøåíèÿ ðÿäà ïðàêòè÷åñêèõ çàäà÷, ñâÿçàííûõ ñ ïåðåêîäèðîâêîé ñèìâîëîâ èëè ñ ïîèñêîì çàïðåùåííûõ ñèìâîëîâ. Íàïðèìåð, íåîáõîäèìî ïðîàíàëèçèðîâàòü ïàðîëü è âûÿñíèòü, ñîäåðæèò ëè îí õîòÿ áû îäíó öèôðó. Ðåàëèçàöèÿ äàííîé ïðîâåðêè ïðè ïîìîùè TRANSLATE èìååò âèä:
IF TRANSLATE(PassWd, '0123456789', '*') = PassWd THEN ADD_ERROR('Îøèáêà - Ïàðîëü äîëæåí ñîäåðæàòü õîòÿ áû îäíó öèôðó !'); RETURN 1; END IF; Äðóãîé ïðèìåð: èäåò ïîäãîòîâêà ÷èñëà ê åãî ïðåîáðàçîâàíèþ â NUMBER. Íåîáõîäèìî çàìåíèòü ðàçäåëèòåëè äåñÿòè÷íûõ çíàêîâ ¾,¿ è ¾.¿ íà ¾.¿ è óäàëèòü ïðîáåëû. Ðåàëèçàöèÿ äàííîé îïåðàöèè ïðè ïîìîùè TRANSLATE èìååò âèä:
SELECT TRANSLATE('123 455,23', '., ', '..') x1, TRANSLATE('-123 455.23', '., ', '..') x2 FROM dual X1 123455.23
X2 -123455.23
Ôóíêöèÿ SUBSTR(str, m [,n])
Ôóíêöèÿ SUBSTR âîçâðàùàåò ôðàãìåíò ñòðîêè str, íà÷èíàÿ ñ ñèìâîëà m äëèíîé n ñèìâîëîâ. Äëèíó ìîæíî íå óêàçûâàòü â ýòîì ñëó÷àå âîçâðàùàåòñÿ ñòðîêà îò ñèìâîëà m è äî êîíöà ñòðîêè str. Íóìåðàöèÿ ñèìâîëîâ èäåò ñ 1. Åñëè óêàçàòü m = 0, òî êîïèðîâàíèå âñå ðàâíî íà÷íåòñÿ ñ ïåðâîãî ñèìâîëà. Çàäàíèå îòðèöàòåëüíîãî çíà÷åíèÿ m ïðèâîäèò ê òîìó, ÷òî ñèìâîëû îòñ÷èòûâàþòñÿ îò êîíöà ñòðîêè, à íå îò íà÷àëà. Çàäàíèå çíà÷åíèé m, ïðåâûøàþùèõ ïî àáñîëþòíîìó çíà÷åíèþ äëèíó ñòðîêè, ïðèâîäèò ê òîìó, ÷òî ôóíêöèÿ âîçâðàùàåò NULL. Ïðèìåð: 108
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
SELECT SUBSTR('Ó ïîïà áûëà ñîáàêà', 13) x1, SUBSTR('Ó ïîïà áûëà ñîáàêà', -6) x2, SUBSTR('Ýòî òåñòîâûé òåêñò', 5, 8) x3, SUBSTR('Ó ïîïà áûëà ñîáàêà', 150) x4 FROM dual X1 ñîáàêà
X2 ñîáàêà
X3 òåêñòîâûé
X4 NULL
Ôóíêöèÿ INSTR(str, search_str [,n[,m]])
Ôóíêöèÿ INSTR âîçâðàùàåò ïîçèöèþ ïåðâîãî ñèìâîëà m-ãî ôðàãìåíòà ñòðîêè str, ñîâïàäàþùåãî ñî ñòðîêîé search_str. Ñðàâíåíèå âåäåòñÿ ñ n-ãî ñèìâîëà ñòðîêè str, ïðè ñðàâíåíèè ó÷èòûâàåòñÿ ðåãèñòð. Ïî óìîë÷àíèþ n = m = 1, òî åñòü ïîèñê âåäåòñÿ îò íà÷àëà ñòðîêè è âîçâðàùàåòñÿ ïîçèöèÿ ïåðâîãî íàéäåííîãî ôðàãìåíòà.  ñëó÷àå íåóñïåøíîãî ïîèñêà ôóíêöèÿ âîçâðàùàåò 0. Ïðèìåðû:
SELECT INSTR('Ó ïîïà áûëà ñîáàêà', 'ñîáàêà') x1, INSTR('Ó ïîïà áûëà ñîáàêà', 'êîøêà') x2, INSTR('Ýòî òåêñò äëÿ äåìîíñòðàöèè ïîèñêà òåêñòà', 'òåêñò', 1, 2) x3, INSTR('11111000000001', '1', 7) x4 FROM dual X1 13
X2 0
X3 35
X4 14
Ñ äàííîé ôóíêöèé, ðàâíî êàê è ñî âñåìè îñòàëüíûìè â Oracle, ÷àñòî äîïóñêàþòñÿ òèïîâûå îøèáêè, ñâÿçàííûå ñ îáðàáîòêîé çíà÷åíèÿ NULL. Åñëè str=NULL, òî ôóíêöèÿ âåðíåò NULL, à íå íîëü! Ýòî íåîáõîäèìî ó÷èòûâàòü ïðè ïîñòðîåíèè ðàçëè÷íûõ óñëîâèé. Íàïðèìåð, äàííûé ôðàãìåíò ïðîãðàììû íà PL/SQL êàê ðàç íå ó÷èòûâàåò ýòó îñîáåííîñòü:
IF INSTR(TXT_VAR, '*') = 0 THEN ... END IF; 109
5.7. Ñòðîêîâûå è ñèìâîëüíûå ôóíêöèè
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
 äàííîì ñëó÷àå ïðàâèëüíî áûëî áû íàïèñàòü òàê:
IF NVL(INSTR(TXT_VAR, '*'), 0) = 0 THEN ... END IF; Ôóíêöèè LENGTH(str) è LENGTHB(str)
Ôóíêöèÿ LENGTH(str) âîçâðàùàåò äëèíó ñòðîêè str â ñèìâîëàõ. Äëÿ ïóñòîé ñòðîêè è çíà÷åíèÿ NULL ôóíêöèÿ âîçâðàùàåò NULL, ïîýòîìó ñîâìåñòíî ñ äàííîé ôóíêöèåé ðåêîìåíäóåòñÿ èñïîëüçîâàòü NVL. Ïðèìåð:
SELECT LENGTH('Ó ïîïà áûëà ñîáàêà') x1, LENGTH('') x2, LENGTH(NULL) x3, NVL(LENGTH(''), 0) x4 FROM dual X1 18
X2 NULL
X3 NULL
X4 0
Ôóíêöèÿ LENGTHB àíàëîãè÷íà ôóíêöèè LENGTH, íî âîçâðàùàåò äëèíó ñòðîêè â áàéòàõ. Ôóíêöèÿ ASCII(str)
Âîçâðàùàåò ASCII-êîä ïåðâîãî ñèìâîëà ñòðîêè str â ñëó÷àå ïðèìåíåíèÿ êîäèðîâêè ASCII è çíà÷åíèå ïåðâîãî áàéòà ìíîãîáàéòíîãî ñèìâîëà ïðè èñïîëüçîâàíèè êîäèðîâêè íà îñíîâå ìíîãîáàéòíûõ ñèìâîëîâ. Ïðèìåð:
SELECT ASCII('Test') x1 FROM dual X1 84 110
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
Ôóíêöèÿ CHR(n)
Âîçâðàùàåò ñèìâîë ïî åãî êîäó. Ïðèìåð:
SELECT CHR(64) x1 FROM dual X1 @
5.8
Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
 äàííîì ðàçäåëå ðå÷ü ïîéäåò î ôóíêöèÿõ ðàáîòû ñ äàòîé/âðåìåíåì è ôóíêöèÿìè ïðåäîáðàçîâàíèÿ òèïîâ äëÿ äàòû. Äëÿ õðàíåíèÿ äàòû è âðåìåíè â Oracle ïðåäóñìîòðåí ñïåöèàëüíûé òèï DATE. Ñ ôèçè÷åñêîé òî÷êè çðåíèÿ ýòî äðîáíîå ÷èñëî, öåëàÿ ÷àñòü êîòîðîãî õðàíèò êîëè÷åñòâî äíåé ñ íåêîòîðîé áàçîâîé äàòû, à äðîáíàÿ âðåìÿ. Ýòî ïîçâîëÿåò ñîâåðøàòü íàä äàòàìè àðèôìåòè÷åñêèå îïåðàöèè ñëîæåíèå è âû÷èòàíèå. Ôóíêöèÿ SYSDATE
Ýòî îäíà èç ñàìûõ ÷àñòî óïîòðåáëÿåìûõ ôóíêöèé, îíà âîçâðàùàåò òåêóùóþ äàòó è âðåìÿ ïî ÷àñàì ñåðâåðà. Ïðèìåð:
SELECT SYSDATE FROM dual SYSDATE 26.12.2007 16:24:43 Ôóíêöèÿ ADD_MONTHS(d, x)
Âîçâðàùàåò äàòó, ïîëó÷åííóþ â ðåçóëüòàòå ïðèáàâëåíèÿ ê äàòå d îäíîãî èëè íåñêîëüêèõ ìåñÿöåâ. Êîëè÷åñòâî ìåñÿöåâ çàäàåòñÿ ïàðàìåòðîâ x, ïðè÷åì x ìîæåò áûòü îòðèöàòåëüíûì â ýòîì ñëó÷àå óêàçàííîå êîëè÷åñòâî ìåñÿöåâ âû÷èòàåòñÿ èç çàäàííîé äàòû. Ïðèìåð: 111
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
SELECT SYSDATE d, ADD_MONTHS(SYSDATE, 3) d1, ADD_MONTHS(SYSDATE, -3) d2 FROM dual D 26.12.2007 16:24:43
D1 26.03.2008 16:24:43
D2 26.09.2007 16:24:43
Ôóíêöèÿ LAST_DAY(d)
Âîçâðàùàåò ïîñëåäíåå ÷èñëî ìåñÿöà, óêàçàííîãî â äàòå d. Ïðèìåð:
SELECT SYSDATE d, LAST_DAY(SYSDATE) d1 FROM dual D 26.12.2007 16:24:43
D1 31.12.2008 16:24:43
Äàííàÿ ôóíêöèÿ î÷åíü óäîáíà äëÿ îïðåäåëåíèÿ êîëè÷åñòâà äíåé â çàäàííîì ìåñÿöå, íàïðèìåð:
SELECT SYSDATE d, TO_CHAR(LAST_DAY(SYSDATE), 'DD') d1 FROM dual D 26.12.2007 16:24:43
D1 31
Ôóíêöèÿ MONTHS_BETWEEN(d1, d2)
Ôóíêöèÿ MONTH_BETWEEN âîçâðàùàåò êîëè÷åñòâî ìåñÿöåâ ìåæäó äâóìÿ äàòàìè d1 è d2 ñ ó÷åòîì çíàêà êàê d1-d2, âîçâðàùàåìîå ÷èñëî ÿâëÿåòñÿ äðîáíûì.
SELECT MONTHS_BETWEEN('2.09.2006', '2.05.2006') d1, MONTHS_BETWEEN('12.09.2006', '2.05.2006') d2, MONTHS_BETWEEN('2.05.2006', '12.09.2006') d3 FROM dual 112
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
D1 4
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
D2 4,32258064516129
D3 -4,32258064516129
Ôóíêöèÿ TRUNC(d[,mask])
Ïðîèçâîäèò óñå÷åíèå óêàçàííîé äàòû â ñîîòâåòñòâèè ñ ìàñêîé. Åñëè ìàñêà íå óêàçàíà, òî óñå÷åíèå ïðîèçâîäèòñÿ äî äàòû (âðåìÿ îòáðàñûâàåòñÿ). Ïðèìåð:
SELECT SYSDATE d1, TRUNC(SYSDATE) d2 FROM dual D1 26.09.2006 16:45:26
D2 26.09.2006
Ðàññìîòðèì òèïîâûå ïðèìåðû óñå÷åíèå äàòû äî ÷àñîâ, äíåé, ìåñÿöà è ãîäà. Ôîðìàòíàÿ ìàñêà ïî óìîë÷àíèþ ðàâíà ¾DD¿
SELECT SYSDATE d1, TRUNC(SYSDATE, TRUNC(SYSDATE, TRUNC(SYSDATE, TRUNC(SYSDATE, FROM dual
'HH24') 'DD') 'MM') 'YYYY')
d2, d3, d4, d5
D1 D2 D3 D4 D5 26.09.2006 16:49:21 26.09.2006 16:00:00 26.09.2006 01.09.2006 01.01.2006 Ôóíêöèÿ ROUND(d[,mask])
Ôóíêöèÿ ROUND àíàëîãè÷íà TRUNC, íî âìåñòî óñå÷åíèÿ îíà ïðîèçâîäèò îêðóãëåíèå. Ôîðìàòíàÿ ìàñêà ïî óìîë÷àíèþ ðàâíà ¾DD¿. Ïðèìåð:
SELECT SYSDATE d1, ROUND(SYSDATE) d2, 113
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
ROUND(SYSDATE, 'HH24') d3, ROUND(SYSDATE, 'DD') d4, ROUND(SYSDATE, 'MM') d5 FROM dual D1 D2 D3 D4 D5 26.09.2006 16:50:50 27.09.2006 26.09.2006 17:00:00 27.09.2006 01.10.2006 Ôîðìàòíûå ìàñêè, äîïóñòèìûå äëÿ ôóíêöèé TRUNC è ROUND
Ðàññìîòðèì ïîäðîáíåå ôîðìàòíûå ìàñêè è îñîáåííîñòè èõ ïðèìåíåíèÿ: Ìàñêà
Íàçíà÷åíèå
ÑÑ YEAR, èëè YYYY, èëè YY, èëè Y Q MONTH, èëè MON, èëè MM WW
Ïåðâûé äåíü ñòîëåòèÿ Ïåðâûé äåíü ãîäà Ïåðâûé äåíü êâàðòàëà Ïåðâûé äåíü ìåñÿöà
Òîò æå äåíü íåäåëè, ÷òî è ïåðâûé äåíü òåêóùåãî ãîäà W Òîò æå äåíü íåäåëè, ÷òî è ïåðâûé äåíü òåêóùåãî ìåñÿöà DDD èëè DD Äåíü DAY, èëè DY, èëè D Ïåðâûé äåíü íåäåëè HH, èëè HH12, èëè ×àñ HH24 MI Ìèíóòà Ôóíêöèÿ TO_DATE(str[,mask [,nls_lang]])
Ôóíêöèÿ TO_DATE ïðåîáðàçóåò ñòðîêó str â äàòó. Ïðåîáðàçîâàíèå âåäåòñÿ ïî ìàñêå mask, åñëè îíà óêàçàíà. Åñëè ìàñêà íå óêàçàíà, òî áåðåòñÿ ìàñêà ïî óìîë÷àíèþ.  ñëó÷àå óêàçàíèÿ ìàñêè ìîæíî óêàçàòü åùå îäèí ïàðàìåòð ÿçûê, èñïîëüçóåìûé ïðè ôîðìàòèðîâàíèè íàçâàíèé ìåñÿöåâ è äíåé.  ñëó÷àå îøèáêè àíàëèçà ñòðîêè str â ñîîòâåòñòâèè ñ çàäàííîé 114
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
ìàñêîé âîçíèêàåò èñêëþ÷èòåëüíàÿ ñèòóàöèÿ. Íàèáîëåå ðàñïðîñòðàíåííàÿ îøèáêà ¾ORA-01830: øàáëîí ôîðìàòà äàòû çàâåðøàåòñÿ ïåðåä ïðåîáðàçîâàíèåì âñåé ñòðîêè ââîäà¿. Êðîìå òîãî, íåðåäêî âñòðå÷àåòñÿ îøèáêà ¾ORA-01821: ôîðìàò äàòû íå ðàñïîçíàí¿ îíà âîçíèêàåò ïðè óêàçàíèè íåäîïóñòèìîé ôîðìàòíîé ìàñêè. Ïðèìåð:
SELECT TO_DATE('12.09.2006') d FROM dual D 12.09.2006 Ôóíêöèÿ TO_CHAR(d[,mask])
Ïðåîáðàçóåò äàòó d â ñèìâîëüíóþ ñòðîêó â ñîîòâåòñòâèè ñ çàäàííîé ìàñêîé.  ñëó÷àå óêàçàíèÿ íåäîïóñòèìîé ìàñêè âîçíèêàåò èñêëþ÷èòåëüíàÿ ñèòóàöèÿ ¾ORA-01821: ôîðìàò äàòû íå ðàñïîçíàí¿. Ïðèìåð:
SELECT SYSDATE d1, TO_CHAR(SYSDATE, 'DD.MM.YY HH24:MI') d2 FROM dual D1 D2 26.09.2006 17:09:08 26.09.06 17:09
115
5.8. Ôóíêöèè ðàáîòû ñ äàòîé è âðåìåíåì
116
Ãëàâà 5. Äîïîëíèòåëüíûå âîçìîæíîñòè
Áèáëèîãðàôè÷åñêèé ñïèñîê 1. Êð¼íêå Ä. Òåîðèÿ è ïðàêòèêà ïîñòðîåíèÿ áàç äàííûõ. 9-å èçä. ÑÏá.: Ïèòåð, 2005 859 ñ. 2. Ãëóøàêîâ Ñ.Â., Òðåòüÿêîâ Þ.Â., Ãîëîâàø Î.À. Àäìèíèñòðèðîâàíèå Oracle 9i/Õóäîæ.-îôîðìèòåëü À.Ñ. Þõòìàí. Õàðüêîâ: Ôîëèî, 2003. 695 ñ. 3. Êàéò Òîì. Oracle äëÿ ïðîôåññèîíàëîâ. Ïåð. ñ àíãë./Òîì Êàéò- ÑÏá.: ÎÎÎ ¾ÄèàÑîôòÞÏ¿, 2003. 672 ñ. 4. Ñìèðíîâ Ñ.Í., Çàäâîðüåâ È.Ñ. Ðàáîòàåì ñ Oracle: Ó÷åáíîå ïîñîáèå/ 2-å èçä., èñïð. è äîï. Ì.: Ãåëèîñ ÀÐÂ, 2002. 496 ñ.
117
Ó÷åáíîå èçäàíèå Íàìåñòíèêîâ Àëåêñåé Ìèõàéëîâè÷
Ïîñòðîåíèå áàç äàííûõ â ñðåäå Oracle Ïðàêòè÷åñêèé êóðñ
Ðåäàêòîð Í. À. Åâäîêèìîâà Îðèãèíàë-ìàêåò èçãîòîâëåí â ñèñòåìå LATEX2ε . Èçä. ëèö. 020640 îò 22.10.97. Ïîäïèñàíî â ïå÷àòü Ôîðìàò 60×84/16. Áóìàãà ïèñ÷àÿ. Óñë. ïå÷. ë. 7,67. Ó÷.-èçä. ë. 6,85. Ãàðíèòóðà Computer Modern. Òèðàæ 200 ýêç. Çàêàç .
.
Óëüÿíîâñêèé ãîñóäàðñòâåííûé òåõíè÷åñêèé óíèâåðñèòåò 432027, Óëüÿíîâñê, Ñåâ. Âåíåö, 32. Òèïîãðàôèÿ ÓëÃÒÓ, 432027, Óëüÿíîâñê, Ñåâ. Âåíåö, 32.