fÖ 4 fÖ 4: dtb kdatabaskursen - högskolan...
TRANSCRIPT
FÖ 4 D t b kFÖ 4: Databaskursen
1. SQL DDL (Data Definition Language)2. Skapa tabell3 Lä till PK3. Lägga till PK4. Data Dictionary Views5. Namn på constraintsp6. Lägga till FK7. Lägga till en kolumn8 Obj k k8. Objektet sekvens9. Tabellen Dual10. Ta bort objektj11. Datatyper12. Inbyggda funktioner
Pär Douhan pdo@du se
1
Pär Douhan, [email protected]
SQL DDLSQL DDL
Förkortningen DDL står för Data Definition Language
A ä d ä i k k fö ä d ll t b t d t b bj kt Nå Används när vi ska skapa, förändra eller ta bort databasobjekt. Några exempel på databasobjekt är: tabell, procedur, funktion, trigger och sekvens.
1. Skapa objekt: create
Objekt
p j2. Förändra objekt: alter3. Ta bort objekt: drop
2
Sk t b llSkapa en tabell
STUDENT# studnr* fnamn
studnr fnamn enamn mobil
STUDENT
* fnamn* enamno mobil
create table student(studnr varchar2(10)studnr varchar2(10),fnamn varchar2(50) not null,enamn varchar2(50) not null,mobil varchar2(15));
table STUDENT created.
3
Lä till PKLägga till en PKN k i lä till p i ä k l (PK) till t b ll t d t
STUDENT# studnr* fnamn
Nu ska vi lägga till en primärnyckel (PK) till tabellen student. Vi ser i modellen att kolumnen studnr är markerad med #och ska alltså vara tabellens primärnyckel.
* fnamn* enamno mobil Vi kan göra detta direkt när vi skapar tabellen, men jag
föredrar att göra det efteråt. Vi använder alter för att göra detta:
alter table studentadd primary key(studnr);
table STUDENT alterd.
Undrar vilket namn vår PK fick?
Vi kan ta reda på det genom att söka i Data Dictionary.
4
D t Di tiData DictionaryE d t b i håll lltid En databas innehåller alltid en beskrivning av lagrad information. Denna brukar
Data
kallas för Data Dictionary. Ibland även för metadatabasen.
Dictionary I Oracle finns det flera olika data dictionary views. Dessa ligger i ett tablespace som ligger i ett tablespace som heter system.
5
D t Di ti ViData Dictionary ViewsD t di ti i ä kä d t l Data dictionary views, även kända som catalog views, låter oss övervaka databasens tillstånd irealtid:
Data Dictionary 1. Vyerna USER, ALL, och DBA, innehåller
information om schemaobjekt som är tillgängligainformation om schemaobjekt som är tillgängligapå olika behörighetsnivåer
2. De s.k. V$ vyerna innehåller information omdatabasens prestanda Vi kan t ex se hur mycketdatabasens prestanda. Vi kan t.ex. se hur mycketminne databasens olika sessioner konsumerar etc.
Via dessa vyer kan vi söka fram metadata om alla objekt och olika tillstånd i databasen. Vi hittar alla vyer och mycket mer på ss64:
http://ss64.com
6
Sök i D t Di tiSöka i Data Dictionarydesc user constraints;
STUDENT# studnr* fnamn
Name Null Type‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐‐‐
_
* fnamn* enamno mobil
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ ‐‐‐‐ ‐‐‐‐‐‐‐‐‐‐‐‐‐‐OWNER VARCHAR2(128) CONSTRAINT_NAME VARCHAR2(128)CONSTRAINT_TYPE VARCHAR2(1) TABLE_NAME VARCHAR2(128) SEARCH_CONDITION LONG() SEARCH_CONDITION_VC VARCHAR2(4000) R_OWNER VARCHAR2(128) R_CONSTRAINT_NAME VARCHAR2(128) DELETE RULE VARCHAR2(9)DELETE_RULE VARCHAR2(9) STATUS VARCHAR2(8) DEFERRABLE VARCHAR2(14) DEFERRED VARCHAR2(9) VALIDATED VARCHAR2(13) GENERATED VARCHAR2(14) BAD VARCHAR2(3) RELY VARCHAR2(4) LAST_CHANGE DATE INDEX OWNER VARCHAR2(128)INDEX_OWNER VARCHAR2(128) INDEX_NAME VARCHAR2(128) INVALID VARCHAR2(7) VIEW_RELATED VARCHAR2(14) ORIGIN_CON_ID NUMBER
7
Sök i D t Di tiSöka i Data Dictionary
STUDENT# studnr* fnamn
select constraint_name,constraint_typefrom user_constraintswhere table_name = 'STUDENT'; -- OBS! Stora bokstäver
* fnamn* enamno mobil CONSTRAINT_NAME CONSTRAINT_TYPE
------------------------------- ---------------SYS C0010189 PSYS_C0010189 P SYS_C0010187 C SYS_C0010188 C
CONSTRAINT_TYPE (from 12c docs)C ‐ Check constraint on a tableP ‐ Primary keyU Unique keyU ‐ Unique keyR ‐ Referential integrityV ‐ With check option, on a viewO ‐ With read only, on a view
Namnet på vår PK är alltså: SYS_C0010189
8
N å t i tNamn på constraintsSTUDENT
STUDENT# studnr* fnamn
studnr fnamn enamn mobil
1 ik d 0733359556
STUDENT
fnamn* enamno mobil
1 erik andersson 0733359556
SYS_C0010189 är inget bra namn på en constraint.
insert into student(studnr,fnamn,enamn,mobil)values('1','carina','eriksson','0733358559');
Error starting at line : 1 in command -insert into student(studnr,fnamn,enamn,mobil)values('1','carina','eriksson','0733358559')E Error report -SQL Error: ORA-00001: brott mot unik begränsning (TEST.SYS_C0010189)00001. 00000 - "unique constraint (%s.%s) violated"
Detta namn säger oss ingenting!
9
q ( )
B t å t i tByta namn på constraintsalter table student
STUDENT# studnr* fnamn
alter table studentrename constraint SYS_C0010189 to student_studnr_pk;
t bl STUDENT lt d* fnamn* enamno mobil
table STUDENT altered.
Det är alltid bra att ge sina constraints bra namn. Det finns olika i i k ti Hä ä j ä dnamngivningskonventioner. Här är en som jag använder:
tabell_kolumn_typ
Typ Förkortning
Primary Key pk
Foreign Key fk
Check ck
Unique uq
10
N å t i tNamn på constraintsSTUDENT
STUDENT# studnr* fnamn
studnr fnamn enamn mobil
1 ik d 0733359556
STUDENT
fnamn* enamno mobil
1 erik andersson 0733359556
Vi testar igen för att se skillnaden:
insert into student(studnr,fnamn,enamn,mobil)values('1','carina','eriksson','0733358559');
Error starting at line : 1 in command -insert into student(studnr,fnamn,enamn,mobil)values('1','carina','eriksson','0733358559')E Error report -SQL Error: ORA-00001: brott mot unik begränsning (TEST.STUDENT_STUDNR_PK)00001. 00000 - "unique constraint (%s.%s) violated"
11
q ( )
T b t t i tTa bort en constraint
STUDENT# studnr* fnamn
Om vi vill ta bort en constraint kan vi göra det med drop. Vi behöver bara känna till namnet:
fnamn* enamno mobil
alter table studentdrop constraint student_studnr_pk;
Nu är PK borttagen. Om vi vill kan vi lägga till fler constraintspå samma gång. Vi lägger till PK igen och en unique constraint på kolumnen mobil:
alter table studentadd constraint student_studnr_pk primary key(studnr)add constraint student_mobil_uq unique(mobil);
12
Lä till FKLägga till en FK
FORDON# regnr* färg
PERSON# persnr* fnamn
ÄGARBYTE
# id(#) * färg
* märke* modell
* fnamn* enamno mobil
(#) persnr(#) regnr* datum
create table ägarbyte(g y (id number(9),persnr varchar2(11),regnr varchar2(6),datum date default sysdate not null);datum date default sysdate not null);
alter table ägarbytealter table ägarbyteadd constraint ägarbyte_radnr_pk primary key(id)add constraint ägarbyte_persnr_fk foreign key(persnr) references person(persnr)add constraint ägarbyte_regnr_fk foreign key(regnr) references fordon(regnr);
13
Lä till k lLägga till en kolumnalter table student
STUDENT# studnr* persnr
alter table studentadd persnr number(10);
persnr* fnamn* enamno mobil
Oj, det blev visst fel datatyp på kolumnen. Vi vill ha varchar2(11) istället så att vi kan lagra personnummer som en teckensträng på formen 'YYMMDD-NNNN'.
Vi kan ändra datatyp på kolumnen med följande SQL-sats:
alter table studentmodify persnr varchar2(11);
sats:
y p
14
Obj kt t kObjektet sekvens
ÄGARBYTE
# id(#) persnr
112568, 112569...(#) persnr(#) regnr* datum
Det kan bli problem att generera nya unika id-värden för tabellen Ägarbyte om vi p g y g yöverlåter detta till människor.
Bättre att låta en sekvens fixa detta!Bättre att låta en sekvens fixa detta!
En sekvens är ett databasobjekt som vi kan se som en svart låda. Varje gång vi anropar funktionen nextval på sekvensobjektet så kommer vi att få ett nytt unikt anropar funktionen nextval på sekvensobjektet så kommer vi att få ett nytt unikt nummer. Jämför med en nummerlappsmaskin på t.ex. apoteket.
15
Obj kt t kObjektet sekvens
ÄGARBYTE
# id(#) persnr
112568, 112569...(#) persnr(#) regnr* datum
Vi k k lt k li t Vi k t t tt d fVi skapar enkelt en sekvens enligt följande kod:
Vi kan testa att den fungerar:
create sequence seq_ägarbytestart with 1increment by 1;
select seq_ägarbyte.nextvalfrom dual;
NEXTVAL‐‐‐‐‐‐‐‐‐‐
1
16
H ä d i kHur använder vi en sekvensÄGARBYTE
id persnr regnr datum
ÄGARBYTE
1 940610 7140 ABC567 1994 11 251 940610-7140 ABC567 1994-11-25
Vi anropar sekvensen när vi ska lägga till data i en tabell. Detta gör vi med SQL DML:
insert into ägarbyte(id,persnr,regnr,datum)values(seq_ägarbyte.nextval,'940610-7145','ABC567',sysdate);
OBS! Det går inte att koppla ihop sekvensen med tabellen vid skapandet av tabellen.
17
T b ll D lTabellen DualDet finns en tabell definierad i Oracle data dictionary med namnet DualDet finns en tabell definierad i Oracle data dictionary med namnet Dual.
Tabellen finns där så att utvecklare som vill köra frågor eller testafunktioner garanteras ett känt resultatfunktioner, garanteras ett känt resultat.
DUALselect * from dual; Det finns alltid bara en DUAL
* dummy DUMMY-----
X
Det finns alltid bara en rad i tabellen Dual.
X
O i ö l å k ' ä ' ll kOm vi gör select på en konstant, t. ex. en 'textsträng' eller ett uttryckfrån någon tabell, så kommer resultatet att returneras en gång för varjerad som tabellen innehåller. I fallet med tabellen Dual, så kommer vi alltidatt få ett resultat tillbaka.
18
T b ll D l lTabellen Dual - exempel'KALLEANDERSSON'
select 'Kalle Andersson'from dual;
KALLEANDERSSON----------------Kalle Andersson
select sysdateSYSDATE----------------y
from dual; 2019-05-10
select sysdate + 10SYSDATE + 10----------------2019 05 20from dual; 2019-05-20
select 1 + 2 + 3from dual;
1+2+3----------------6
19
T b t bj ktTa bort objektFör att ta bort skapade objekt använder vi oss av:För att ta bort skapade objekt använder vi oss av:drop objekt_name;
FORDON# regnr* färg
PERSON# persnr* fnamn
ÄGARBYTE# id(#) * färg
* märke* modell
* fnamn* enamn* telefono mobil
(#) persnr(#) regnr* datum
Om vi skall ta bort ovanstående tabeller, så måste detta ske i en viss ordning:g
1. drop table ägarbyte;2. drop table person; drop table fordon;
Vi kan inte ta bort person eller fordon först. Då detta medför brott mot referensintegriteten. Vi skulle ha FK-värden i ägarbyte som saknade referenser.
20
D t t kl d t tDatatyper - enkla datatyper"I have a very simple rule: Put dates in dates numbers in I have a very simple rule: Put dates in dates, numbers in numbers, and strings in strings. Never use a datatype to store something other than what it was designed for, and use the most specific type possible. " (Tom Kyte, Oracle)
Varchar2 när vi vill lagra text. Kom ihåg att sätta enkelfnuttar ' runt texten i 'en textsträng' Vi kan sätta maxlängd genom att lägga till stränglängden varchar2(25) har en textsträng . Vi kan sätta maxlängd genom att lägga till stränglängden, varchar2(25) har en maxlängd av 25 tecken.
N b ä ä i b hö l iff 345 3 67 3 3 14 Vi ätt i t k lf tt ' Number när är vi behöver lagra siffror: 345, 3, 67.3, 3.14. Vi sätter inte enkelfnuttar ' runt siffror. number(3) innebär max 3 siffror, t. ex. 999. number(5,2) innebär total längd av 5 siffror inklusive 2 decimaler, t. ex. 145.25
Date när vi skall lagra tidpunkter. Skilj på hur det lagras i databasen och hur det presenteras. Om vi lagrar sysdate, så har vi år, dag, timme, minut, sekund, ja ända ner på tusendels sekund. Om vi lagrar sysdate, så har vi år, dag, timme, minut, sekund, ja ända ner på tusendels sekund. Vi kan presentera det som '2024-01-25' eller '01-JAN-2024' genom att ange en viss formatmask. Vi sätter enkelfnuttar ' runt datum '2016-12-24'.
21
K t i f ktiKonverteringsfunktioner
Olika inbyggda funktioner som sköter konvertering av datatyper.
to char to date to number etcto_char, to_date, to_number etc.
Vi kan konvertera ett datum, t. ex. sysdate till en teckensträng på önskatformat 2027 10 01:14:15:58format 2027-10-01:14:15:58.
Vi testar med en bekant SQL-sats:Vi testar med en bekant SQL sats:
select to_char(sysdate,'YYYY-MM-DD:HH24:MI:SS') as nufrom dual;from dual;
NUNU-------------------2015-03-12:13:15:49
22
Jä fö i t ä l d äJämför inte äpplen med päronIbland kan vi behöva konvertera en 'teckensträng' till ett datum eller ett Ibland kan vi behöva konvertera en teckensträng till ett datum eller ett datum till en 'teckensträng'.
Vi vill kanske kontrollera om det finns några rader i kundtabellen med ettVi vill kanske kontrollera om det finns några rader i kundtabellen med ettregdatum som är lika med '2019-05-25'.
where regdatum = '2019-05-25';where regdatum = 2019-05-25 ;
datum sträng
Furthermore, only compare dates to dates, strings to strings, and numbers to numbers. When dates and numbers are stored in strings, or
d i i i l h ffstored using inappropriate lengths, your system suffers:
1. När man stoppar in data i databasen förlorar man möjligheten attk ll d t ä ikti d t iff ä ikti iffkontrollera att datum är riktiga datum, att siffror är riktiga siffror
2. Databasen förlorar prestanda3. Dataintegriteten och därmed datkvaliteten sjunker4. Hela systemet lider!
23
y
Jä fö ä l d ä lJämför äpplen med äpplenVi å ill d ä d å bä id likh
where to_char(regdatum,'YYYY-MM-DD') = '2019-05-25';
Vi måste se till att det är samma datatyp på bägge sidor om likhetsoperatorn =
sträng sträng
where to char(regdatum 'YYYY') = '2019';
Om vi vill kontrollera hur många som registrerade sig under 2019:
where to_char(regdatum, YYYY ) = 2019 ;
O i ill k ll h å i d i d A i 2019
where to_char(regdatum,'YYYY-MM') = '2019-08';
Om vi vill kontrollera hur många som registrerade sig under Augusti 2019:
24
K k f l kti d t tKonsekvenser av felaktiga datatyperO i l d ll ä å k d få å Om vi lagrar ett datum som nummer eller en sträng så kan detta få svåra konsekvenser!
Vad hindrar mig från att mata in 20170296?
Den 96:e Februari finns väl inte. Jo i vår databas finns det datumet. Detta är Jett exempel på låg dataintegritet.
V d hi d i f å i 2017 E2 A6? Vad hindrar mig från att mata in 2017-E2-A6?
2017-E2-A6, vilken dag är det? , g
Om vi hade satt datum som date hade detta inte varit möjligt. Systemet hade stoppat oss från att mata in vår skräpdata i databasenhade stoppat oss från att mata in vår skräpdata i databasen.
"Put dates in dates, numbers in numbers, and strings in strings."
25
O ti å d t t d tOperationer på datatypen date
date - number = datedate date = n mber t l t d ll t å d t
date + number = date
date - date = number antalet dagar mellan två datum
select to_date('JAN-01-2026','MON-DD-YYYY') + 10 as återdatumfrom dual;
ÅTERDATUM----------------2026-01-11
select sysdate - to_date('1993-02-23','YYYY-MM-DD')from dual;
sysdate - to_date('1993-02-23','YYYY-MM-DD')--------------------------------------------8052,74644
26
A d d i lAvrunda decimalerVi k ä d f k i d() fö d ill ö k ä l Vi kan använda funktionen round() för att avrunda till önskvärt antal decimaler:
select round(sysdate - to_date('1993-02-23','YYYY-MM-DD'),0) as antal_dagarfrom dual;
ANTAL DAGARANTAL_DAGAR------------8053
Här kan du läsa mer om Oracle built in functions:
http://www.techonthenet.com/oracle/functions/
27