mseda/dbs05_eng.pdf · © miloš Šeda: database systems. brno university of technology, fme,...
TRANSCRIPT
BRNO UNIVERSITY OF TECHNOLOGY FACULTY OF MECHANICAL ENGINEERING
Institute of Automation and Computer Science
DATABASE SYSTEMS
Doc. RNDr. Ing. Miloš Šeda, Ph.D.
BRNO 2005
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
2
Contents 1. Theoretical Aspects of Data Processing ......................................................................... 3 1.1 Introduction .....................................................................................................................3 1.2 Database Systems ........................................................................................................... 3 1.2.1 Data Independence .......................................................................................................4 1.3. Data Models .................................................................................................................. 5 1.3.1. Integrity Constraints for Relationships ........................................................................ 7 1.3.2 Relational Data Model ................................................................................................. 8 1.3.3 Relational Algebra ....................................................................................................... 9 1.3.4 Relational Algebra as a Query Language .................................................................. 14 1.4 Database Design ........................................................................................................... 16 1.4.1 Functional Dependencies, Normal Forms .................................................................. 17 1.4.2 Functional Analysis ................................................................................................... 24
2. Structured Query Language (SQL) ............................................................................. 28 2.1 SELECT Query ............................................................................................................ 28 2.1.1 Aggregate Functions .................................................................................................. 30 2.1.2 SELECT with Subqueries ........................................................................................... 32 2.2 Union Query ................................................................................................................. 36 2.3 Crosstab Query ............................................................................................................. 36 2.4 Update (Action) Queries ............................................................................................... 37 2.5 Definition Queries ........................................................................................................ 38 2.6 Computing with NULL Values, NULL in SQL .............................................................. 40
3. Visual Basic for Applications (VBA) ............................................................................ 41 3.1 Definitions and Declarations.......................................................................................... 41 3.2 Control Structures.......................................................................................................... 43 3.2.1 Assignment Statements ............................................................................................... 43 3.2.2 Conditional Statements .............................................................................................. 43 3.2.3 Loop Statements ........................................................................................................ 44 3.2.4 Jump Statements ........................................................................................................ 45 3.2.5 With Statement ........................................................................................................... 45 3.2.6 Procedures and Functions ......................................................................................... 46 3.2.6.1 Parameters of Procedures and Functions ................................................................. 46 3.2.6.2 Call of Procedures and Functions ............................................................................ 47 3.3 Forms ........................................................................................................................... 48 3.3.1 Event Procedures in Forms......................................................................................... 48 3.3.2 References to Collection Elements in Visual Basic ...................................................... 49 3.4 Hierarchy of MS Access Objects .................................................................................. 53 3.5 Object RecordSet .......................................................................................................... 56 3.6 Calling SQL from VBA ................................................................................................ 64
4. Database Application ................................................................................................... 66 References ......................................................................................................................... 79 Terminology ...................................................................................................................... 81
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
3
1. Theoretical Aspects of Data Processing 1.1 Introduction Information system functions:
• Selection of information, • prognoses of development, • planning, • decision making, • application in automation of engineering tasks, • application in economic data processing (wages, invoices, stock records, etc.).
Information system interface:
• Batch processing, • conversation with system.
Implementation of IS 60s-80s ... Cobol, PL/1 - file processing Drawbacks of file processing:
• Programmes and data are interdependent. • Data redundancy. • Data inconsistency. • Data incompatibility. • Difficult data accessibility. • Data isolation. • Problem of data sharing. • Problem of information security. • Problem of data integrity.
1.2 Database Systems
• Data structures are separated from application (user) programs. • Data access is possible only through DBS programs. • Multiuser access is enabled and data security is provided.
DB + DBMS = DBS
• Data are not organised in separated files, but in a centrally processed data structure, called database (DB)
• Central database management, i.e. all programs are implemented by means of special software, called Database Management System (DBMS).
DBMS 1. Tools for data definition
Data Definition Language (DDL) CREATE, INDEX, …
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
4
2. Tools for algorithm description
Data Manipulation Language (DML) INSERT, UPDATE, DELETE, SELECT, …
Fig. 1. Architecture of DBS
1.2.1 Data Independence - modifications of data definitions on lower level have no impact on data definitions on
higher level 1. Physical independence - changes of the physical scheme without changes of logical
scheme and application programs. 2. Logical independence - changes of conceptual level of data description without changes in
application programs. Forms of file organisation − Heap − Linked organisation − Sequential − Transforming − Index-sequential − B-trees ad ) Index-sequential organisation - data file & index file (index)
view of user 1
view of user n
view of user 2 …
external level
conceptual level
logical scheme
internal level
physical scheme
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
5
data file index No. ID name surname place street no … key No. 1 75… Jan Kos Brno Orlí 4 … 59… 4 2 66… Jiří Černý … … … … 66… 2 3 80… … … … … … … 75… 1 4 59… … … … … … … 80… 3 1.3 Data Models a) Relational data model (entities and relationships among them are described by relational
schemes and relations). b) Hierarchical data model (relationships among entities are represented by tree-structures,
vertices represent entities, edges represent relationships between pairs of entities). c) Network data model ((relationships are modelled by general graph structures; hierarchical
model is a special case of the network model) E-R (Entity-Relational) conceptual model E (Entity) – object of the real world Example: “teacher Kos Petr, ID 650512/…”
Entity type - abstraction describing the type of objects, given by a name and set of attributes Example: TEACHER(surname, name, ID,...), SUBJECT(code, name, …) [noun, substantive]
Attribute - property of entities (and relationships), function assigning a value to entities and relationships R (Relationship) - relationship of 2 or more entities Example: “teacher Kos Petr, ID 650512/…” “teaches” “the subject xyz …”
Relationship type
Example: TEACHES, SUPPLIES, … [(mostly) verb] MS Access
• Entity type, relationship type, table name
• Attributes, headers of the table in table Data list, field names in table Design view
• Entities (instances of objects of entity type), relationships (instances of objects of relationship type), table rows E-R diagram and its graphical symbols
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
6
graphical symbol shape interpretation
rectangle
entity type
diamond
relationship type
oval
attribute
line connection of symbols
1 number 1 single occurrence in relationship
M, N, … letters M, N, …
multiple occurrence in relationship
Type E-R diagrams
Fig. 2. E-R model with 1 : N relationship
Fig. 3. E-R model with M : N relationship
TEACHER TEACHES SUBJECT
DUTIES UNDER CONTRACT NAME
SURNAME
ID
…
NAME
YEAR
SEMESTER
… M N
CODE
READER LENT BOOK
DATE NAME
SURNAME
ID
…
AUTHOR
NAME
ISBN
… 1 N
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
7
1.3.1 Integrity Constraints for Relationships 1. Cardinality – 1:1 (one-to-one relationship), ), 1:N (one-to-many), M:N (many-to-many) 2. Membership 3. Min-max integrity constraint 4. Weak entity types, foreign key Cardinality
Fig. 4. Relational cardinality, occurrence E-R diagram Membership in relationship - obligatory (complete) - optional (partial)
Examples:
(Optional subjects need not be opened)
TEACHER TEACHES SUBJECT M N
1:1 1:N M:N
SPORTSMAN WON COMPETITION M N
DOCTOR WORKS WARD N 1
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
8
Min-max integrity constraint
Let the denotation R(E1, E2) represent the following diagram
and E:(min,max) denote minimal/maximal number of occurences of the entity E in the relationship R. Then
R ( E1: (1,1), E2 : (1,1) ) corresponds to 1:1 R ( E1: (1,1), E2 : (0,n) ) 1: N R ( E1: (0,1), E2 : (0,n) ) (0 or 1) : N R ( E1: (0,m), E2 : (0,n) ) M :N Example: Library system BOOK-LOAN (READER : (0,5), COPY : (0,1) ) BOOK-RESERVATION (READER : (0,4), BOOK : (0,n) ) REGISTRATION (BOOK : (1,n), COPY : (1,1) ) n - more pieces, REGISTRATION (BOOK : (0,n), COPY : (1,1) )
0 - book is not in the fund, e.g. lost book or loan from a foreign library
1.3.2 Relational Data Model Definition 1. Let Di, 1≤ i ≤ n be a system of nonempty sets, so called domains. Then each subset of Cartesian product R ⊆ D1 × D2 × … × Dn is called a relation of degree n over domains D1, D2, … ,Dn. Elements of R are ordered tuples (d1, d2, … ,dn), where di∈ Di, 1 ≤ i ≤ n. A relational scheme is the expression of the form R(A1:D1, A2 :D2, … , An :Dn), where Ai are attribute names. [shortened version: R(A1, A2, … , An).] [The pair (Ai :Di) is called an attribute of the relation R.] Note: Databases contain finite number of data ⇒ only finite relation are considered; domains – data types (STRING, INTEGER, … )
E1 R E2
READER LENT BOOK 1 N
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
9
Database relation can be represented as: a) matrix with m rows and n columns, columns have additional denotations by names (attributes). b) table, each element of the relation corresponds with one row of the table, there are no equal rows (relation = set), ith column contains values only from the domain Di , column headers represent attributes. Note: mathematics – relation elements = ordered tuples table representation – the order of columns can be changed Example: WORKERS number surname name salary W1 Starý Jan 17000 W2 Novák Petr 14000 W3 Kříž Jiří 21000 D1 set of strings Wn , n - natural number D2 set of surnames (STRING) D3 set of names (STRING) D4 set of nonnegative integers (LONG INTEGER) 1.3.3 Relational Algebra Besides the definition of relations as a tool for modelling databases, the relational model must also contain a set of operations with databases. There are two basic tools for manipulations with relations:
n relational algebra and n relational calculus.
Operations of the relational algebra
(1) The union of relations R and S of the same degree (and defined on the same domains) is denoted by R ∪ S and defined as follows:
R ∪ S = { t | t ∈ R ∨ t ∈ S }
(2) The difference of relations R and S is denoted by R − S and defined as follows:
R − S = { t | t ∈ R ∧ t ∉ S }
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
10
Example: R S
A B A B a 1 b 3 ⇒ d 2 c 1 c 1
R ∪ S R − S
A B A B a 1 a 1 d 2 d 2 c 1 b 3
Tab. 1. Union and difference
(3) The Cartesian product of a relation R of degree n and a relation S of degree m is denoted by R × S and defined as follows:
R × S = { rs | r ∈ R ∧ s ∈ S }, where rs = (r1, r2 , … , rn, s1, s2, … , sm)
Example: R S
A B C D E a 1 x 2 a ⇒ b 1 y 2 b
R × S
A B C D E a 1 x 2 a a 1 x 2 b b 1 y 2 a b 1 y 2 b
Tab. 2. Cartesian product (4) The projection of a relation R of degree n on attributes A = (i1, i2, … im), where 1 ≤ ij ≤ n,
ij ≠ ik for j ≠ k, is a list of indices of different components of the relation R (columns of the corresponding table or names of attributes, respectively), it is denoted by R[A] and defined as follows:
R[A] = { r[A] | r∈R }, where r[A] = (ri1, ri2, … , rim for r∈R (The projection serves to a selection of table columns.)
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
11
Example: R
A B C a 1 x ⇒ b 2 x
R[A] R[C] R[A,C]
A C A C a x a x b b x
Tab. 3. Projection
(5) Selection (or restriction): Let R be a relation, ϕ be a logical formula (it can contain logical operators ∧ ∨ ¬). The
selection (restriction) from the relation R by ϕ is denoted by R[ϕ] and defined as follows:
R[ϕ] = {r | r∈R ∧ ϕ (r)} (The selection operation serves to a selection of table rows.)
Example: R
A B C 1 a 2 3 b 2 ⇒ 2 a 2 1 c 1
R[A>2] R[A≤C] R[(A>C)∨ (B=”c”)]
A B C A B C A B C 3 b 2 1 a 2 3 b 2 2 a 2 1 c 1 1 c 1
Tab. 4. Selection
Note: (1)-(5) represent basic relational algebra operations, the further operations can be expressed by (1)-(5). (6) The intersection of relations R and S is denoted by R ∩ S and defined as follows:
R ∩ S = { t | t ∈ R ∧ t ∈ S }
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
12
Example: R S
A B A B a 1 b 3 ⇒ d 2 c 1 c 1
R ∩ S
A B c 1
Tab. 5. Intersection (7) Θ-join Let R be a relation of degree m, i∈{1,2, … ,m}, S be a relation of degree n, j∈{1,2, … ,n}, Θ∈{<, ≤, = ≥, >, ≠} The Θ-join of relations R and S by Θ over the ith attribute of the relation R and jth
attribute of the relation S is denoted R[i Θ j]S and defined as follows:
R[i Θ j]S = {rs | r ∈ R ∧ s ∈ S ∧ r[i] Θ s[j]}
(The Θ-join is the Cartesian product restricted by a condition Θ, i.e. the result contains only the rows that satisfy Θ.)
Example: R S
A B C D E a 1 1 1 x ⇒ b 1 2 2 y b 2 2 3 z
R [B = D] S
A B C D E a 1 1 1 x a 1 2 1 x b 2 2 2 y
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
13
R [C > D] S
A B C D E a 1 2 1 x b 2 2 1 x
R [C < D] S
A B C D E a 1 1 2 y a 1 1 3 z a 1 2 3 z b 2 2 3 z
Tab. 6. Θ-join Note: If Θ is the equality condition, then the resulting join will contain two same columns. Therefore the following modification of the join operation is defined:
R[i∗j]S = (R[i = j]S) [1,2, … ,m+j-1, m+j+1, …, m+n] - one of the same columns is omitted. (8) Natural join of relations R and S is denoted by R[∗]S. This join operation selects from the Cartesian product R × S those records, that have on
the common columns the same values; redundant columns are from the resulting join omitted.
(9) Division. Let R be a relation of degree m and S be a relation of degree n. Let A = (i1, i2, … ,ik), ij ∈{1,2, … ,m}, j = 1, … ,k, ij ≠ ik pro j ≠ k, B = (g1, g2, … ,gt), gj ∈{1,2, … ,n}, j = 1, … ,t, gj ≠ gk pro j ≠ k, be lists of selected attributes of R and S, respectively (for simplicity, the attributes are
denoted by natural numbers). Let us denote Ā = (j1, j2, … , jm−k), where jp ∈ {1,2, … , m}−A for p =1,2, … , m−k, jp< jk for p< k (i.e. Ā are attributes of R, that were not selected into the list A). Let us define for r∈R a set imR (r[Ā]), (image set), that contains all complements of r[Ā], which in product with r[Ā] create an element of the relation R, thus
imR (r[Ā]) = {y | r[Ā] y ∈ R[Ā, A] }. The division of a relation R over A by a relation S over B is denoted by R[A : B]S and defined as follows:
R[A : B]S = {r[Ā] | r∈R ∧ (S[B] ⊆ imR (r[Ā])}. It can be proved that the following equation is satisfied
R[A : B]S = R[Ā] − ((R[Ā] × S[B]) − R[Ā, A] ) [1,2, … ,m−k]
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
14
Example: Image set R
D1 D2 D3 D4 D5 1 a x f 2 2 a y g 3 1 b x f 2 2 c y h 3 3 a x f 1 1 b y f 2 2 a x h 3
Nechť A ={D3, D2, D4}, pak Ā = {D1, D5}. If r = (1, a, x, f, 2), then r[A] = (x, a, f), r[Ā] = (1,2), and thus imR(r[Ā]) = imR(1,2) = {(x, a, f), (x, b, f), (y, b, f)}. Note: Minimal set of operations of the relational algebra: { union, Cartesian product, difference, selection, projection }
i) Θ-join can be defined by means of the Cartesian product and selection, ii) natural join by means of the Cartesian product, selection and projection, iii) intersection can be defined as follows:
* R ∩ S = R ∪ S − (R − S) − (S − R), * R ∩ S = R − (R − S), * R ∩ S = S − (S − R).
1.3.4 Relational Algebra as a Query Language Example: Let us consider the following relations: CANDIDATES(ID, name, surname, town, street, No, ZIP-code) LANGUAGUES(code, language-name) KNOWLEDGE(ID, code, knowledge-degree).
R − S S − R
R
S
R ∩ S
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
15
where knowledge-degree ∈ {“beginner”, “advanced”, “excellent”} Define queries for solving the following tasks: (Q1) All data about all candidates
Q : = CANDIDATES (Q2) IDs, names and surnames of candidates from Brno.
Q : = (CANDIDATES[town="Brno"] ) [ID, name, surname]
(Q3) Names and surnames of candidates with excellent knowledge of English. Q : = {CANDIDATES [∗] (KNOWLEDGE[code="Eng" AND knowledge-degree= "excellent"])} [name,surname] (Q4) Languages, in which the candidate specified by his ID, is at least advanced.
Q : = { (KNOWLEDGE [ID=given-ID AND (knowledge-degree = "advanced" OR knowledge-degree = "excellent")] ) [∗] LANGUAGES} [language-name]
(Q5) Candidates, who are excellent at least in one language and its name. Q : = {CANDIDATES [∗] (KNOWLEDGE [knowledge-degree ="excellent"] ) } [name,surname,code]
(Q6) Candidates, who speak only English.
those, who speak only English = those, who speak English − those, who speak another language
Q : ={ (KNOWLEDGE [code="Eng"] ) [ID] − (KNOWLEDGE [code<>"Eng"]) [ID] } [∗] (CANDIDATES[ID, name, surname] )
(Q7) Candidates, who speak no foreign language
those, who speak no foreign language = all − those, who speak at least 1 foreign language
Q : = (CANDIDATES [ID] − KNOWLEDGE [ID]) [∗] (CANDIDATES[ID, name, surname] ) (Q8) Candidates, who have al least basic knowledge of all world languages.
Q1: all candidates speak all world languages = Cartesian product CANDIDATES [ID] × LANGUAGES[code] Q2: non-existing knowledge = all speak all − registered knowledge Q3: those, who speak all = those, who speak at least one language − − those, who do not speak at least one language
Q1 : = CANDIDATES [rodné-č] × LANGUAGES[code]
Q2 : = Q1 − KNOWLEDGE [ID, code] Q3 : = KNOWLEDGE [ID] − Q2 [ID] Q : = Q3 [∗] (CANDIDATES [ID, name, surname] ) It can also be solved by means of the division operation Q1 : = KNOWLEDGE [{A1, A2, … } − { ID } : kód] LANGUAGES
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
16
Q : = Q1 [∗] ( CANDIDATES [ID, name, surname] ) 1.4 Database Design Motivation examples: PERSONS ID name surname address 1 Jan Kos Brno, Orlí 4, 602 00 2 Petr Růžička Praha, Pod vodárenskou věží 2, 182 07 3 Jiří Sova Ústí nad Labem, Masarykovo nám. 4, … 4 Milan Konečný Brno, Lerchova 22, 602 00 Instead of the “set” attribute address is better to define atomic attributes town, street, No, ZIP_code. Then we get the following relational scheme PERSONS(ID, name, surname, town, street, No, ZIP_code). Definition: A relational scheme R(A1, … , An) is in the first normal form (1NF) if attributes A1, … , An are atomic, i.e. their domains are sets of simple values, e.g. sets of numbers (INTEGER, REAL, ...), characters (CHAR), words in an alphabet (≈ STRING), etc. Example: PERSONS IDdept department head workers 1 design_office Novák Novotný, Navrátil, Sedláček, Janíček 2 drawing _office Růžička Karas, Kos, Sova 3 accounting_dept Konečná Nová, Stará, Jarošová, … 4 … … … This relational scheme can be transformed into the 1NF, e.g., in this way: PERSONS IDdept department head workers 1 design_office Novák Novotný 1 design_office Novák Navrátil 1 design_office Novák Sedláček 1 design_office Novák Janíček 2 drawing _office Růžička Karas 2 drawing _office Růžička Kos 2 drawing _office Růžička Sova 3 accounting_dept Konečná Nová 3 accounting_dept Konečná Stará 3 accounting_dept Konečná Jarošová … … … … However, this transformation is unsuitable, because it contains these drawbacks:
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
17
1. Redundancy. Information about each department is repeated so many times as the number of its workers is.
2. Risk of inconsistency when modifications are performed. From the redundancy more complicated updates result. If a new head is installed, the head of the accounting department changes her name, or one of the departments changes its number, then this datum must be changed for all workers of the corresponding department. If this correction is not done completely, then the data will become inconsistent (one department has two heads or two different numbers, respectively).
3. Insertion anomaly. No information about an established department can be inserted if it is has no workers.
4. Deletion anomaly. If all workers of a department leave it, then their deletion in the table causes the loss of connecting information about the department, that is not desirable.
⇒ usually it is not suitable to use only one table and it is necessary to decompose the original table into several tables in 1NF, however, they must contain some connecting data to preserve all information. In our example, we can decompose the original relational scheme EMPLOYEES into 3 relational schemes WORKER(IDw, name, surname, IDdep) DEPARTMENT(IDdep, dept_name) HEAD(ID, IDdep) 1.4.1 Functional Dependencies, Normal Forms Definition: Let X, Y be subsets of a set of attributes A. Then we say that Y functionally depends on X (or X functionally determines Y) and denote X → Y if for each possible current relation R is satisfied that if two elements of R have equal values of attributes (or sets of attributes) X, then they also have the same values of attributes (or sets of attributes) Y. More formally: X → Y on R(A) ⇔ ∀ r1, r2 ∈ R, (r1.X = r2.X) ⇒ (r1.Y = r2.Y) n Note: A functional dependency is defined for all possible instances of the relation, and thus it is not possible to decide on a functional dependency from one instance. On the other hand, from the only one relation it is possible to show the functional independence between some attributes or sets of attributes, respectively. Logical implications Definition: Let F be a set of functional dependencies, then we say that F logically implies a dependency X → Y (or X → Y is functional dependency (logically) derivable from F), if this dependency is satisfied in all relations, in which the dependencies from F are satisfied. The set of all functional dependencies derivable from F is called a closure of F and denote it F+. n Note:
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
18
With respect to the infinity number of such relations, F+ cannot be calculated from this definition. Therefore we need another mechanism for checking whether the given dependency X → Y is in F+ or not. Inference rules - equivalent tool for a calculation of F+, or for a determination if a given dependency X → Y
is in F+ or not. Rules must satisfy the following properties (i) soundness, by means of these rules from F can be derived only dependencies from F+; (ii) completeness, rules allow to derive all functional dependencies from F+ and (iii) independence, if a rule is removed, then the completeness property will be lost. Armstrong’s axioms - inference rules of functional dependencies in the classical relational database theory. Let X, Y, Z are subsets of a set of attributes A. Then it holds: A1: Inclusion rule. If Y ⊆ X, then X → Y . A2: Augmentation rule. If X → Y, then XZ → YZ (XZ stands for X ∪ Z). A3: Transitivity rule. If X → Y and Y → Z, then X → Z. From Armstrong’s axioms further useful rules for inference of functional dependencies can be derived (W in the last of them denotes a subset of A): P1: Union rule. If X → Y and X → Z , then X → YZ. P2: Decomposition rule. If X → YZ , then X → Y and X → Z. P3: Pseudo-transitivity rule. If X → Y and YW → Z, then XW → Z. Proof. [P1] From the first assumption X → Y of Rule P1, we get by A2 that XZ → YZ. Similarly
from the second assumption X → Z of Rule P1 we get by A2 that XX → XZ, and thus X → XZ. Finally from X → XZ and XZ → YZ we get by A3 that X → YZ. [P2] From Rule A1 implies YZ → Y and YZ → Z. From these facts and from the assumption
X → YZ of Rule P2, applying Rule A3, we get X → Y a X → Z. [P3] From the first assumption X → Y of Rule P3 we get, applying Rule A2, the dependency
XW → YW, which with further assumption YW → Z of Rule P3 implies by Rule A3 the functional dependence XW → Z, what we wanted to prove.
Algorithm for computing transitive closure F + Input: F … set of fuzzy functional dependencies for the set of attributes A of a relational scheme R(A), where |F|=m and |A|=n,
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
19
f = X → Y … X⊆A, Y∈A.
Outputs: X+ … transitive closure of X with respect to F, membership … True, if f ∈F+ ; False, otherwise.
Data structures: LS[1: m], RS[1: m] … arrays of attributes from left/right sides of dependencies from F, Done … Boolean variable.
begin X+ : = X; repeat Done : = True; for i : = 1 to m do begin if (LS[i] → RS[i]) and (LS[i]⊆ X+) and (not (RS[i]⊆X+)) then begin X+ : = X+ ∪ RS[i]; Done : = False end end until Done; membership : = (Y∈X+) end Relational scheme keys Definition K1: (using functional dependency) Given a relational scheme R(A) and K ⊆ A, then K is the key of R, if it satisfies the following properties: (V1) K→ A (Uniqueness) (V2) There is no K' ⊂ K so that K' → A. (Nonredundancy) Definition K2: (using closure) Given a relational scheme R(A) and K ⊆ A, then K is the key of R, if it satisfies the following properties: (V1') K→ A ∈ F+. (Uniqueness) (V2') For each K' ⊂ K it is satisfied K' → A ∉ F+. (Nonredundancy) Remarks: (1) Each relation has a key (in the worst case it can be given by A) (2) A relation can contain more keys, e.g. in the table PERSONS(ID, name, surname, passportNo, …). the key can be ID or passportNo. One of the keys is determined as a primary key. (As a primary key is usually selected the key which is minimal in some sense (one
segment)) (3) An attribute which occurs at least in one of the keys, is called a key attribute. Attributes
that are not included in keys, are called nonkey attributes.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
20
Special types of functional dependencies Definition: Given a relational scheme R(A), where R is a relation and A is a set of attributes and X, Y are subsets of A, then we say that: (i) Y fully functionally depends on X, X→Y, if there is no X', X' ⊆ X, X'≠∅ so that X' → Y. (ii) Y partially functionally depends on X, X → Y, if there is X', X'⊂ X, X'≠∅ so that X'→ Y. n Note: Using (i), the property of nonredundancy in the definition of key can be expressed as follows: (V2'') A fully functionally depends on XK. Definition: Let X, Y be subsets of a set of attributes A, C be a single attribute, which is neither in X nor in Y. If X→Y, Y→ C are functional dependencies, and Y→X is not a functional dependency, then we say that C transitively functionally depends on X. n Normal forms of relations (2NF, 3NF, BCNF) Definition: A relational scheme is in: (2) the 2nd normal form (2NF), if it is in the 1NF and contains no partial functional
dependencies of nonkey attributes on a key; (3) the 3rd normal form (3NF), if it is in the 2NF and each nonkey attribute is not
transitively dependent on keys; (3½) Boyce-Codd normal form (BCNF), if it is in the 3NF and contains no transitive
dependency of key attributes (of one key) on (the other) key. Note: There is also the 4th normal form (4NF), that refers to a multivalued functional dependency. Multivalued functional dependency Definition: Denote C(b) a set of C-values (i.e. a set of values of the attribute C) assigned in a certain moment to B-value b. Let X, Y, Z be subsets of a set of attributes A such that Z = A − X − Y. Then Y multidepends on X, if for each XZ-value xz, it is satisfied Y(xz) = Y(x). This fact is called multidependency of Y on X and is denoted by X→→Y. If Z is the empty set (i.e. XY includes all attributes), then the multidependency X→→Y is trivial. Note: Therefore the attribute Y in R(A) multidepends on the attribute X, if it is satisfied that each value of attribute X determines the set of values of the attribute Y and this set is independent on the values of the other attributes in R(A).
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
21
Definition: A relational scheme R(A) is in the 4th normal form (4NF), if in the case when it contains a multivalued dependency X →→ Y, where not(Y⊆X) and XY does not contain all attributes A, then X also contains a key of the relation R. Note: R(A) is in the 4NF if for each multivalued dependency X→→Y is satisfied at least one of the two conditions: (1) Multidependency is not trivial (2) X includes a key of R(A)
Fig. 5. Hierarchy of normal forms
Partial functional dependencies (FDs), transitive FDs a multivalued FDs cause all problems mentioned above (the risk of inconsistency when modifications are performed, insertion and deletion anomalies. Example: [ 1NF ⇒ 2 NF ] THEATRE-PROGRAM(theatre, drama, director, address, date) It is not in the 2NF, because it contains partial functional dependencies: theatre → address, {drama, theatre} → director Decomposition THEATRE (theatre, address) SCHEDULE(theatre, drama, date) DIRECTOR(drama, theatre, director) Example: [ 1NF ⇒ 3 NF ] HOSPITALIZATION(patient-ID, patient-name, patient-surname, ID_health-insurance-company, health-insurance-company, date, time, doctor, department, diagnosis)
4NF BCNF 3NF 2NF 1NF
0NF
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
22
key = {patient-ID, hospitalization-date, hospitalization-time}
functional dependencies: key → doctor, key → department, key → diagnosis. (full FD) patient-ID → patient-name, patient-ID → patient-surname, (partial FD) patient-ID → ID_health-insurance-company → → health-insurance-company, (transitive FD) Deccmposition: PACIENT(patient-ID, patient-name, patient-surname) DOCTOR(doctor-ID, doctor-name, doctor-surname) DEPARTMENT(department-ID, department-name) DIAGNOSIS(diagnosis-ID, description) HEALTH-INSURANCE(ID_health-insurance-company, health-insurance-company) HOSPITALIZATION(patient-ID, hospitalization-date, hospitalization-time, doctor-ID, department-ID, diagnosis-ID) INSURANCE(patient-ID, ID_health-insurance-company) Note: If we allow that patients can change their health insurance companies, then the functional dependency patient-ID → ID_health-insurance-company is not satisfied and therefore it is necessary during each hospitalization to register patient’s current health insurance company.
⇓ Decomposition: PACIENT(patient-ID, patient-name, patient-surname) DOCTOR(doctor-ID, doctor-name, doctor-surname) DEPARTMENT(department-ID, department-name) DIAGNOSIS(diagnosis-ID, description) HEALTH-INSURANCE(ID_health-insurance-company, health-insurance-company) HOSPITALIZATION(patient-ID, hospitalization-date, hospitalization-time, doctor-ID, department-ID, diagnosis-ID, ID_health-insurance-company) Example: [ 3NF ⇒ BCNF ] DIRECTORY(town, street, ZIP-code) key 1: {town, street} key 2: {street, ZIP-code} This relational scheme has no nonkey attribute, it is (trivially) in 3NF, but it is not in BCNF, because it contains transitive dependency of key attribute town on the key {town,street} {town, street} → ZIP-code → town
• Redundancy - town is repeated with its each street. • Risk of inconsistency – e.g. when name is changed (Gottwaldov/Zlín etc.) • Insertion anomaly – it is not possible to register a town with its ZIP-code if we do not
know at least one from its streets Decomposition into 2 schemes: STREET-LIST(street, ZIP-code), TOWN-LIST(ZIP-code, town)
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
23
Example: [ … ⇒ 4NF ] EMPLOYEE(name, school, language)
name school language Kos basic Czech Kos basic English Kos high Czech Kos high English Kos university Czech Kos university English Kos university German
It contains two multivalued functional dependencies name →→ school and name →→ language,
⇓ decomposition into 2 schemes: S1(name, school), S2(name, language), now in each scheme only one multivalued functional dependency is contained (1:N). Note: Decompositions must be lossless and preserve functional dependencies. Definition: Let R(A) be a relational scheme and ρ ={R1(A1), R2(A2)} be its decomposition and F be a set of functional dependencies. We say that the decomposition is lossless with respect to F, if for each relation R(A) satisfying F is:
R = R1(A1) [∗] R2(A2). Theorem (decomposition theorem): If in R(A1, A2, A3) a functional dependency A1 → A2 is satisfied, then R can be decomposed without loss of information into projections R1(A1, A2) and R2(A1, A3). Theorem: Let ρ ={R(A1), R2(A2)} be a decomposition of a relational scheme R(A) and F be a set of functional dependencies. Then the decomposition ρ is lossless with respect to F if and only if:
(A1 ∩ A2) → A1 − A2 or (A1 ∩ A2) → A2 − A1. Example: TEACHERS(name, institute, subject, contract)
F = {name → institute, {name, subject} → contract} Decomposition: ρ = { TEACH(name, institute), TE-SUB(name, subject, contract) } {name, institute} ∩ {name, subject, contract} = {name}
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
24
{name, institute} − {name, subject, contract} = {institute} From the previous theorem we get that this decomposition is lossless. Example: BOOK-ORDERS (orderNo, date, total-price, customer-name, customer-surname, …, shopNo, shop-place, … , book-title1, author1-1, author1-2, … , author1-5, publisher1, price1, … , book-title2, author2-1, author2-2, … , author2-5, publisher2, price2, … , … book-title20, author20-1, author20-2, … , author20-5, publisher20, price20, … , ) Among entity types customer, order, shop, book, author there are the following relationships: customer - order 1 : N order - book M : N ⇒ 1 : N, intersection table, N : 1 book - author M : N ⇒ 1 : N, intersection table, N : 1 shop - order 1 : N
Note: 1:N is in MS Access denoted by 1:∞; primary key = blue background; foreign key = grey background. Reference integrity ≈ relationship between the primary key of the first relation and the foreign key of the second relation. 1.4.2 Functional Analysis - modelling of activities that concern with given application
CUSTOMER ORDER DETAIL BOOK
SHOP BOOK-AUTHOR AUTHOR
1
1
1 1
1 ∞
∞
∞
∞
∞
∞
1
IDcust surname name …
ordNo IDcust date shopNo …
ordNo ISBN count tax
ISBN title year publisher price …
shopNo town street …
ISBN IDauthor index
IDauthor surname name e-mail …
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
25
function - verb in imperative mood
WHAT must be done, not WHO, WHERE, WHEN and HOW
• on organisation level = working function, • on conceptual level = process, • on programme level = programme, procedure, transaction.
• Hierarchy of functions • Event modelling • Data flow diagrams (Yourdon, DeMarco, …)
Hierarchy of functions - functional structure diagrams (FSD) Event in hierarchy of functions works as a trigger
Data Flow Diagrams (DFDs) consist of 4 components:
1. processes - represent activities, one process can cover more functions 2. data flows - represent a data exchange among processes 3. data stores - locations, where data are saved (e.g. database, file, card file, paper sheet) 4. interface - represents external users that use data flows or data stores
Customer enters the booking office
book a ticket by requirements
summarise requirements for booking
find free tickets by requirements
make a reservation
F1.1.1 F1.1.2
F1.1
F1.2.1
F1.2
F1.3.1 F1.3.2 F1.3.3
F1.3
F1
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
26
Symbols in data flow diagrams Rules for DFD design
• DFD must not contain: o “black holes”, i.e. processes, into which data only enter o “selfgenerating processes”, i.e. processes, which have only outputs o data flows and processes with no description
• Name of a date flow have to o enable to understand the meaning of DFD and simplify communication
between user and solver o represent the flow structure
Example: DFD for withdrawal of money from account (DeMarco).
Yourdon DeMarco Gane & Sarson Processes
Data flows
Data stores (memories)
Interface (terminators)
processname
process name
1 process name
store name
store name
store name
D1
kind and number of memory
inerface name
inerface name
inerface name
flow name
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
27
Software engineering
• Methodology – summary of processes and methods that define WHAT, WHO and WHEN should be done during design, implementation and control of information system. Yourdon Structured Method, CASE Method fy Oracle, SSADM (Structured System Analysis and Design Method), ...
• Method - procedure or technique that defines WHAT is necessary to do in a given project phase (date model, functional model, modules, definition of requirements, testing, …). Yourdon Structured Analysis/Structured Design, Jackson System Development, …
• Technique - way, HOW to create this what a method recommends, e.g. for the date model to use Chen’s ERA model, functional analysis should be done by TopDown strategy, ...
• Tool - BY WHAT we realize the technique, by what we express results, e.g. data flow diagram (DFD), CASE (Computer Aided System/ Software Engineering), ...
client
withdrawal requirement
update account
accounts archive of account operations
confirmed paper
state of account
updated account
solvency checking
checked statements
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
28
2. Structured Query Language (SQL) 2.1 SELECT Query SELECT [ALL | DISTINCT | DISTINCTROW | [TOP n [PERCENT]]]
{* | table.* | [table.] field1 [AS alias1] [,table.] field2 [AS alias2] [,...] }
FROM {1table1 [AS alias1t] | 2select-query1 [AS alias1d] | 3=1|2} [LEFT | RIGHT | INNER] JOIN
table2 [AS alias2t] ON join-condition [IN external-database] }
[,{...}] [WHERE search-condition] [GROUP BY aggregate-key]
[HAVING search-condition-of-groups] [ORDER BY { column-name | column-number [ASC | DESC] }
[,{...}] [WITH OWNERACCESS OPTION]
join-condition
• table1.field1{= |<> | < | <= | > | >= } table2.field2 search-condition
• expression1 {= |<> | < | <= | > | >= } expression2 • expression [NOT] BETWEEN bottom AND top • expression [NOT] IN set-of-values • expression [NOT] LIKE pattern-string • expression {= |<> | < | <= | > | >= } ALL (subquery) • expression {= |<> | < | <= | > | >= } ANY | SOME (subquery) • expression [NOT] IN (subquery) • [NOT] EXISTS (subquery)
Examples: name LIKE "K*" name LIKE "J?rka" name LIKE "P[A-F]###" name IN ("Jan","Jiří","Pavel") name IN ([ersons].[name]) Note:
The expression ... EXISTS (SELECT ∗ ... ) is evaluated as true if the set of values in brackets is nonempty.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
29
Note:
In lists of output information not only the table fields but also more complex expressions can be used. Example: PERSONS(birth-certificate-number, name, surname, ...) PRACTICE(birth-certificate-number, organisation, date-of-accession, date-of-termination, ...) Find a list of persons, their practice in registered organisations with the length of practice and display them in the alphabetic order. SELECT DISTINCTROW persons.surname, person.name, practice.organisation, Val(Format(Iif(IsNull(practice.date-of-termination), Date() − practice.date-of-accession, practice.date-of-termination − practice.date-of-accession), "yy")) AS „total number of years" FROM persons LEFT JOIN practice ON persons.birthNo = practice.birthNo ORDER BY persons.surname, persons.name Note: If in the clause FROM more tables without join and search conditions (in clauses JOIN and WHERE, respectively) are mentioned then the query result is given by the Cartesian product of these tables. This is possible to use in special situations, see the following example. Example: CHESS(playerID, name, surname) The task is to generate the play list (all pairs). SELECT chess.name, chess.surname, ch2.name, ch2.surname
FROM chess, chess AS ch2 The Cartesian product inside one table – the table is opened twice, second time with an alias. This solution contains an error, it generates also pairs where both members are the same. CHESS(playerID, name, surname)
• one round play system SELECT chess.name, chess.surname, ch2.name, ch2.surname FROM chess, chess AS ch2 WHERE chess.playerID < ch2.playerID
• two round play system SELECT chess.name, chess.surname, ch2.name, ch2.surname FROM chess, chess AS ch2 WHERE chess.playerID <> ch2.playerID
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
30
Note: SELECT ∗ FROM Tab1,Tab2 WHERE Tab1.ID = Tab2.ID by MS Access is processed in the same way as SELECT ∗ FROM Tab1 INNER JOIN Tab2 ON Tab1.ID = Tab2.ID Example: DEPARTMENTS(deptID, dept-name) WORKERS(birth-certificate-number, name, surname, deptNo) 1. INNER JOIN – combines only those records from given tables that satisfy the join
condition 2. LEFT JOIN – selects all records from the table DEPARTMENTS and only those records
from the table WORKERS in which joined fields are equal (e.g. it also includes a new department without workers) 3. RIGHT JOIN – selects all records from the table WORKERS and only those records
from the table DEPARTMENTS in which joined fields are equal (e.g. it also includes external workers that are not assigned to any department). 2.1.1 Aggregate Functions aggregate function meaning COUNT(*) number of records including those containing
Null values COUNT(field) number of records, records with Null values
of the field are not counted AVG(expression) arithmetic average SUM(expression) sum MIN(expression) minimal value MAX(expression) maximal value STDEV(expression) standard deviation of the basic file of
numerical expressions STDEVP(expression) estimate of the standard deviation from
selected values VAR(expression) variance of the basic file of numerical
expressions VARP(expression) estimate of the variance from selected values
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
31
Example: OPTIONAL-SUBJECTS(student, subject-name, year, semester, ...) The goal is to list the subjects that were selected by 10 or more students and display them in the descending order by the number of students. SELECT subject-name, COUNT(subject-name) FROM optional-subjects GROUP BY subject-name HAVING COUNT(subject-name) >=10 ORDER BY 2 DESC Example (Multisegment aggregate key): Consider a relation scheme SCHOOL(teacherID, name, surname, institute, function, ...).
Determine a list of institutes and number of professors, associate professors and senior lecturers of these institutes. SELECT institute, function, COUNT() AS number FROM school GROUP BY institute, function It results in: institute function number Mathematics professor 2 associate professor 6 senior lecturer 17 Physics professor 3 associate professor 4 senior lecturer 11 … Note: The aggregation order is substantial.
SCHOOL(teacherID, name, surname, institute, function, ...). The following query SELECT function, institute COUNT() AS number FROM school GROUP BY function, institute returns the different result than the previous query as follows:
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
32
function funkce, počet professor Mathematics 2 Physics 3 … … associate professor Mathematics 6 Physics 4 … … senior lecturer Mathematics 17 Physics 11 … … 2.1.2 SELECT with Subqueries Example FIRM1(birth-certificate-number, name, surname, salary, function, ... ) FIRM2(birth-certificate-number, name, surname, salary, function, ... )
All workers from FIRM1 who have higher salaries than all workers from FIRM2. SELECT name, surname, salary FROM firm1 WHERE salary > ALL (SELECT salary FROM firm2) FIRMA1(rodné-č, jméno, příjmení, plat, funkce, ... ) FIRMA2(rodné-č, jméno, příjmení, plat, funkce, ... ) Example FIRM1(birth-certificate-number, name, surname, salary, function, ... ) FIRM2(birth-certificate-number, name, surname, salary, function, ... )
All workers from FIRM1 who have higher salaries than at least one worker from FIRM2. SELECT name, surname, salary FROM firm1 WHERE salary > ANY (SELECT salary FROM firm2) Example CUSTOMERS(customerID, customer-name, town, street, No, ZIP-code) INVOICES(invoiceNo, customerID, date, ... )
List of customers who have paid no invoice in this year. SELECT customer-name FROM customers WHERE customerID NOT IN
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
33
(SELECT customerID FROM invoices WHERE date >= #01.01.2005#) More generally … WHERE Year(date) = Year(Date())) Example: (as in the previous example using EXISTS) CUSTOMERS(customerID, customer-name, town, street, No, ZIP-code) INVOICES(invoiceNo, customerID, date, ... )
List of customers who have paid no invoice in this year using the EXISTS clause. SELECT customer-name FROM customers WHERE NOT EXISTS (SELECT ∗ FROM invoices WHERE customers.customerID=invoices.customerID AND Year(date) = Year(Date())) Example COMPETITION(team, points, scored, obtained, ... )
a) Create a table of a sport competition by gained points. If the number of points is equal for more teams then order them by difference between scored and obtained goals.
b) From the table Q, given by the previous query, find the team with the highest number of points. If more than one teams have the highest number of points then display all of them.
ad a) SELECT team, SUM(points) AS Spoints, SUM(scored) AS Sscored, SUM(obtained) AS Sobtained FROM competition GROUP BY team ORDER BY 2 DESC, SUM(scored−obtained) DESC ad b) ‘ Q ≡ table given by the previous query
SELECT Q.team, Q.Spoints, (Q.Sscored−Q.Sobtained) AS score FROM Q WHERE Q.Sbody = (SELECT MAX(Q.Sbody) FROM Q) ORDER BY score DESC Note: The aggregate function MAX in the subquery relates to the whole table because the clause GROUP BY is omitted.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
34
Example: READERS(IDreader, name, surname, ... ) BOOKS(ISBN, title, author, publisher ...) RESERVATIONS(IDreader, ISBN) Reader names who have reserved the book „On the road". SELECT readers.name, readers.surname FROM readers WHERE readers.IDreader IN (SELECT reservations.IDreader FROM reservations WHERE reservations.ISBN = (SELECT books.ISBN FROM books WHERE books.title = „On the road")) Existential and universal quantifier in SQL (∃,∀) The proposition „for each x p(x) is satisfied " is logically equivalent to the proposition „there is no x such that p(x) is not satisfied". Formally: (∀x) p(x) ≡ ¬ (∃ x)( ¬ p(x)) Example: (∀x) (∃ y): y>x is equivalent to ¬ (∃ x)( ¬ (∃ y): y>x) Note: It is simpler „to think" in universal quantifiers than in negations of existential quantifiers. In SQL the universal quantifier is not defined. Note:
The expression ... EXISTS (SELECT ∗ ... ) is evaluated as true if the set of values in brackets is nonempty. Example: Names of the readers who have reserved at least one book. SELECT readers.name, readers.surname FROM readers WHERE readers.IDreader IN (SELECT reservations.IDreader FROM reservations)
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
35
Example: Determine names of the readers who have reserved at least one book using the EXISTS clause.That means we want to determine such readers that there is a book reserved by them.
SELECT readers.name, readers.surname FROM readers WHERE EXISTS (SELECT ∗ FROM reservations WHERE readers.IDreader = reservations.IDreader) Example: Numbers of readers that have reserved at least one book, but no book published by UNIS.
(i) SELECT DISTINCT reservations.IDreader FROM reservations WHERE reservations.ISBN NOT IN (SELECT books.ISBN FROM books WHERE books.publisher = "UNIS") (ii) SELECT DISTINCT reservations.IDreader FROM reservations, books WHERE reservations.ISBN = books.ISBN AND books.publisher <> "UNIS" The following solution is correct. (iii) SELECT reservations.IDreader FROM reservations, reservations AS R2 WHERE NOT EXISTS (SELECT ∗ FROM reservations WHERE reservations.IDreader = R2.IDreader AND ISBN IN (SELECT ISBN FROM books WHERE books.publisher = "UNIS")) Example: Readers who have reserved all books. (i) SELECT readers.IDreader, readers.name, readers.surname FROM readers WHERE (SELECT DISTINCT ISBN FROM reservations
wrong
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
36
WHERE reservations. IDreader = readers.IDreader) = (SELECT ISBN FROM books) (ii) With respect to used data, the sets are identical if they have the same number of elements
and thus it can also be solved as follows: SELECT readers.IDreader, readers.name, readers.surname FROM readers WHERE (SELECT COUNT(DISTINCT ISBN) FROM reservations WHERE reservations.IDreader = readers.IDreader) = (SELECT COUNT(ISBN) FROM books) (iii) The following solution at the beginning finds numbers of reservations of each reader,
then stores them into an existing empty table with 2 columns, and finally selects among them these whose number of reservations is equal to the number of books.
(a) INSERT INTO AuxTab(ID, number) SELECT reservations.IDreader, COUNT(reservations.IDreader) FROM reservations GROUP BY reservations.IDreader (b) SELECT readers.IDreader, readers.name, readers.surname FROM readers, AuxTab WHERE readers.IDreader = AuxTab.ID AND AuxTab.number = (SELECT COUNT(ISBN) FROM books) 2.2 Union Query [TABLE] query1 UNION [ALL] [TABLE] query2 [UNION [ALL] [TABLE] query3 […] ] [ORDER BY ordering_specification] 2.3 Crosstab Query TRANSFORM aggregate-function (expression1) select-query PIVOT expression2
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
37
Example: TRANSFORM SUM(qPerson.time) As total-time SELECT qPerson.birth-certificate-number, qPerson.surname, qPerson.name FROM qPerson GROUP BY qPerson.birth-certificate-number, qPerson.surname, qPerson.name PIVOT qPerson.firm birth-certificate-number
surname name <> ABB KPS …
Hora Jan 0 … Kos Petr 10 4 … Novotný Pavel 5 … … … … … … … Example: TRANSFORM COUNT(Student.year) SELECT Student.year FROM Student GROUP BY Student.year PIVOT Partition(average-results,1,3,0.50)
year 1 : 1.50 1.51 : 2 2.01 : 2.50 2.51 : 3 1 40 150 250 60 2 … … … … 3 … … … … 4 … … … … 5 … … … …
2.4 Update (Action) Queries Creation of a new table. (copying data from the other table). SELECT [ALL | DISTINCT | ... ] list-of-fields INTO new-table [IN external-database] FROM source-table Insertion of one record into an existing table or query. INSERT INTO { table | query } [(list of fields into which data are inserted)]
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
38
VALUES (list of values) Selection of records from one table and their insertion into new records of the other table. INSERT INTO { table | query } [(list of fields into which data are inserted)] SELECT ... FROM ... WHERE ... Updating fields in a table (in tables) (in 1∝: relationship, a referential integrity for update can be used) UPDATE { table | query | table_joined_by_a_relationship } [IN external-database] SET column-name = { expression | NULL } [, ...] WHERE search-condition Deletion of records in a table (in tables) (in 1∝: relationship, a referential integrity for deletion can be used)
DELETE [∗ | table.∗] FROM { table | list-of-tables | query | table_joined_by_a_relationship } [IN external-database] WHERE search-condition 2.5 Definition Queries Creation of a new table, definition of fields (name, data type, size) and indices. CREATE TABLE table (field1 data-type[(size)] [NOT NULL] [CONSTRAINT name-of-index1...] [, field2 data-type[(size)] [NOT NULL] [CONSTRAINT name-of-index2...] [, ...]] [,CONSTRAINT name-of-multisegment-index… [, ...]]) Note: For complete definition of indices see the clause CONSTRAINT in the following paragraph.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
39
CONSTRAINT clause - definition of indices (and creation of a relationship with the other table) in commands CREATE TABLE a ALTER TABLE Klauzule CONSTRAINT - definice indexů (a vytvoření relace s jinou tabulkou) v příkazech CREATE TABLE a ALTER TABLE
• Single index CONSTRAINT index-name
{ PRIMARY KEY | UNIQUE | NOT NULL | REFERENCES foreign-table [(for-field1, for-field2)]}
• Multisegment index CONSTRAINT index-name
{ PRIMARY KEY (prim-segm1[,prim-segm2 [, ...]]) | UNIQUE (uniq-segm1[, uniq-segm2 [, ...]]) | NOT NULL (not_null-segm1[, not_null -segm2 [, ...]]) | FOREIGN KEY (ref1[,ref2 [, ...]]) REFERENCES foreign-table [(foreign-field1 [, foreign-field2 [, ...]])]} Modification of an existing table structure (adding a new field/index into an existing table or deletion of a field/index from an existing table, respectively) ALTER TABLE table { ADD {COLUMN field data-type [(size)] [NOT NULL] [CONSTRAINT index ...] | CONSTRAINT multisegment-index ... } | DROP {COLUMN field | CONSTRAINT multisegment-index ...}} Note: For complete definition of indices see the clause CONSTRAINT in the previous paragraph. Deletion of an existing table from a database, or deletion of an existing index from a table. DROP {TABLE table | INDEX index ON table} Creation of a new index from an existing field (fields) in a table. CREATE [UNIQUE] INDEX index
ON table (field [ASC | DESC] [, field [ASC | DESC], ...]) [WITH { PRIMARY | DISALLOW NULL | IGNORE NULL}]
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
40
2.6 Computing with NULL Values, NULL in SQL 1) Arithmetic operations with NULL value - if one of operands has NULL value, then the operation result is NULL
2) Compare operations =, <> , < , <=, > , >= - the same as for arithmetic operations 3) Logical operations AND, OR, NOT - in general 0 AND x = 0, 1 OR x = 1, where x is a logical expression ⇒ 0 AND NULL = 0 , NULL AND 0 = 0, 1 OR NULL = 1 , NULL OR 1 = 1 - negation NOT (NULL) = NULL
4) In MS Access, the NULL value can be tested by means of the logical function IsNull() 5) Aggregate functions in SQL - NULL values are included only in the aggregation COUNT(∗),
in all other aggregations: COUNT(field), AVG(expression), SUM(expression), … they are omitted !!! (Rule 1 is not applied here)
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
41
3. Visual Basic for Applications (VBA) 3.1 Definitions and Declarations Definition of constants [Public | Private] Const name [As data_type] = constant_expression Private (default) – constant is reachable only in the module where was defined, Public in declaration section of module, form or report – global usage, data_type: Byte, Integer, Long, Single, Double, Currency, Date, Boolean, String, Variant Note: Data type Variant is more flexible (it is the data type of all controls in forms and reports), but it has the lowest efficiency (Access must determine the current data type by the variable value). Declaration of variables a) default declaration (variable name is ended by a letter expressing the variable data type) Byte none Integer % Long & Single ! Double # Currency @ Date none Boolean none String $ Variant none Object none user defined none b) explicit declaration more suitable approach,
if it is not predefined in Tools of Module card, then MS Access at the beginning of new module includes the statement Option Explicit
Dim array-name[(array-size...)] [As [New] data_type]] … array-size is specified by:
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
42
[bottom To] top New – it enables implicit creation of an object; a new instance of the object is created on first reference to it, so it is so necessary to use the Set statement to assign the object reference (it can’t be used for non-object variables) Default value for bottom is 0, it can be changed as follows: Option Base 1 Example:
Dim X As Integer, Y As Integer, S As String∗30 Dim A(10) As Single, B(1 To 100, 0 To 3) As Integer ReDim statement ReDim [Preserve] array-name(array-size...) As data_type … 1) Dynamic array declaration - at first the array is defined by means of Dim without its size - then the number of its elements is allocated by means of ReDim Dim A() As Integer … ReDim A(100) As Integer 2) Dynamic change of the array size during the execution Dim A(50) As Integer … static declaration … ReDim Preserve A(55) As Integer … dynamic change Note: Preserve provides loss less change of size (values of the array elements are saved; if Preserve is not used then ReDim initializes the array elements values to Empty. Static statement Static name[(size...)] [As [New] data_type]] … size is specified by: [bottom To] top It declares within a procedure a variable, that will be used only in this procedure (by its nature, it is local), however, it exists also after finishing of the procedure, if the module containing it is open (loaded into the operational memory).
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
43
User defined data types [Public | Private] Type name_of_user_defined_data_type variable-name As data_type … End Type Example: Type person name As String∗20 surname As String∗20 End Type 3.2 Control Structures 3.2.1 Assignment Statements variable = expression Set object-variable = {[New] object-expression | Nothing } 3.2.2 Conditional Statements If condition Then command1 [Else command2] If condition Then commands1 Else commands2 End If If condition Then commands1 [[Else If condition2 Then commands2 [Else If condition3 Then commands3] … [Else commands_n]] End If
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
44
Select Case tested-expression Case list-of-values-1 commands1 Case list-of-values-2 commands2 ... [Case Else commands-n] End Select 3.2.3 Loop Statements For control-variable = first To last [Step step-size] commands1 [Exit For] [commands2] Next control-variable If the main part of the loop is executed for all elements of a collection, then it is more suitable to use the following version of the For loop. For Each element In collection commands1 [Exit For] [commands2] Next element Do {While | Until} podmínka příkazy1 [Exit Do] příkazy2 Loop Do příkazy1 [Exit Do] příkazy2 Loop {While | Until} podmínka While podmínka příkazy Wend
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
45
3.2.4 Jump Statements
• Unconditional jump on the other command in procedure or function GoTo {label | row_number} Example: GoTo nav ... nav:
• Conditional jump when an error is evaluated On Error {GoTo row_identifier | Resume [Next] | GoTo 0}
If only Resume is used, the programme jumps on the command that caused an error and Access tries to do it again. Resume Next catches errors, but the programme continues by the next command. If GoTo 0 is used, then catching errors is cut off in the current procedure and each error is sent to an error routine in the calling procedure. If there is no error routine, then a window with the corresponding warning message is opened.
Note: In error routine, we may test: 1. The value of built-in variable Err(error number). If Err = 0, then no error happened. 2. Error description by means of the function Error. 3. It can be used the object Err and its properties, too: Err.Description, text information about the current error Err.Number, number of the current error. 3.2.5 With Statement With object commands End With Example: With my_object .Height = 2000 .Width = 2000 .Caption = "This is my denotation" End With
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
46
3.2.6 Procedures and Functions [Public | Private] [Static] Sub procedure-name ([parameter-list]) [commands1] [Exit Sub] [commands2] End Sub [Public | Private] [Static] Function function-name ([parameter-list]) As data-type [commands1] [function-name = expression] [Exit Function] [commands2] [function-name = expression] End Function Range of validity of procedures/functions Public In all procedures/functions of all modules. Private In all procedures/functions of the current
modules. Static All variables declared (default or explicitly)
in the procedure will be kept during opening the module containing this procedure. Example: A counter inside of a procedure, its value is incremented by 1 in each execution of the procedure.
3.2.6.1 Parameters of Procedures and Functions [Optional] [ByVal | ByRef] [ParamArray] parameter-name [As data-type]
• Optional optional parameter.
It enables to declare a parameter of the Variant data type. All parameters after the optional parameter must be optional, too. If optional parameter is present or not can be checked by means of the function IsMissing()
• ByVal call by value. If the real parameter is an expression, then Visual Basic operates with it as it was declared by means of ByVal.
• ByRef call by reference. Arrays are always made accessible by reference
• ParamArray must be last in the list of parameters.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
47
• Optional označuje nepovinný parametr. Umožňuje deklarovat parametr typu Variant. Za nepovinným parametrem musí být všechny další parametry rovněž nepovinné. Test nepřítomnosti nepovinných parametrů lze provést pomocí funkce IsMissing().
• ByVal - volání hodnotou. Jestliže je skutečným parametrem výraz, Visual Basic s ním zachází jako by byl deklarován pomocí ByVal.
• ByRef - volání odkazem. Pole se vždy předávají odkazem. • ParamArray musí být v seznamu parametrů poslední.
3.2.6.2 Call of Procedures and Functions
• Procedure can be called by two different ways:
Call procedure-name(list-of-real-parameters) or
procedure-name list-of-real-parameters
• The result of the function is a value, and therefore it can be used in all statements where an expression is feasible, e.g. in the right side of an assignment statement:
variable = function-name (list-of-real-parameters)
Array, flexible and optional number of parameters Note: Arrays are not managed directly but using the general data type Variant. Sub Tests() Dim x As Variant, arr(2) As Variant x = Function1(175,60) arr(0) = 175 arr(1) = 60 x = Function2(arr) x = Function3(Array(175,60)) End Sub Function Function1(ParamArray arr() As Variant) As Variant arr(0) = … arr(1) = ... Function1 = arr ‘ structured return value End Function Function Function2(arr() As Variant) As Variant ... End Function Function Function3(arr As Variant) As Variant
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
48
... End Function Example: Testing of “empty” value (from modUtility module) Note: Initial values of MS Access: number 0 string ”” (empty string) Variant Empty object type Nothing Function IsNothing(varToTest As Variant) As Integer ’ it tests "logical nothing" by data types ’ Nothing:: Empty, Null, number with value of 0, empty string ’ Date/Time is never equal to Nothing IsNothing = True Select Case VarType(varToTest) Case vbEmpty Exit Function Case vbNull Exit Function Case vbBoolean If varToTest Then IsNothing = False Case vbByte, vbInteger, vbLong, vbSingle, vbDouble, vbCurrency If varToTest < > 0 Then IsNothing = False Case vbDate IsNothing = False Case vbString If Len(varToTest) < > 0 And varToTest < > " " Then IsNothing = False End Select End Function 3.3 Forms 3.3.1 Event Procedures in Forms Example Search a record on click of command button by the field where the cursor was before the click. Private Sub Command7_Click() On Error GoTo Err_Command7_Click Screen.PreviousControl.SetFocus
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
49
DoCmd.DoMenuItem acFormBar, acEditMenu, 10, , acMenuVer70 Exit-Command7_Click: Exit Sub Err-Command7_Click: MsgBox Err.Description Resume Exit_Command7_Click End Sub 3.3.2 References to Collection Elements in Visual Basic Forms … collection of opened forms Forms(i) … (i+1)th opened form Forms[orders] … form orders Forms(”orders”) … form orders Note: If the name of an element of a collection is stored in a variable, e.g. it is by a parameter of a procedure or function, then we must use the last case with round brackets but without quotation marks Dim form-name As String form-name = ”orders” ... Forms(form-name) … form orders Example: Additional pages in the Card control in the forms The card control reachable from form tools has only two pages; there are two possible approaches how to add extra pages:
1) in local menu of the card control, selected in Design view 2) in VBA programme code,
(e.g. we insert two edit fields (name of form containing the card control and card control name) and a command button in an auxiliary form.) In the OnClick event procedure of the command button the corresponding form will be opened in the Design view and in the card control a new page will be added and finally the form will be closed. A skeleton of the procedure is showed as follows:
Sub AddPageInCard(form-name As String, card-name As String) ... DoCmd.OpenForm form-name, acDesign ... Forms(form-name).Controls(card-name).Pages.Add DoCmd.Close End Sub
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
50
Example: Find names of all open forms and their controls Sub List-of-names1() Dim nf As Integer, nc As Integer, i As Integer, j As Integer, s As String Dim frm As Form s = "" nf = Forms.Count If nf > 0 Then For i = 0 To nf−1 Set frm = Forms(i) s = s & frm.Name & Chr$(13) & Chr$(10) nc = frm.Count If nc > 0 Then For j = 0 To nc−1 s = s & " " & frm(j).Name & Chr$(13) & Chr$(10) Next j Else s = s & " no controls in this form" & Chr$(13) & Chr$(10) End If Next i Else s = s & "no opened forms" & Chr$(13) & Chr$(10) & Chr$(13) _ & Chr$(10) End If MsgBox s End Sub Find names of all open forms and their controls using For Each
Sub List-of-names2() ‘ vbCrLf = Chr$(13) & Chr$(10), vbTab = tab Dim s As String, frm As Form, ctl As Control s = "" If Forms.Count > 0 Then For Each frm In Forms s = s & frm.Name & vbCrLf If frm.Count > 0 Then For Each ctl In frm.Controls s = s & vbTab & ctl.Name & vbCrLf Next ctl Else s = s & vbTab & " no controls in this form " & vbCrLf End If Next frm Else s = s & "no opened forms" & vbCrLf End If MsgBox s End Sub
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
51
Example: A form with no connected table containing specified criteria for a selection of data from a table connected with another and viewing them after pressing command button in the first form. (A)
Option Compare Database Option Explicit Private Sub FindPartners_Click() On Error GoTo Err_Command12_Click Dim stDocName As String, stLinkCriteria As String stDocName = "persons" stLinkCriteria ="[sex] =" & "'" & IIf(Me![Frame0] = 1, "male", "female") & "'" _ & " AND [age] <=" & Me![f-max_age] _ & " AND [education] =" & "'" & Me![Combo11] & "'" _ & " AND [number-of-children] <=" & Me![f-max_number-of-children] _ & " AND [town] LIKE " & "'" & Me![f-town] & "∗'" _ & " AND [salary] >=" & Me![f-min_salary] DoCmd.OpenForm stDocName, , , stLinkCriteria Exit-Command12_Click: Exit Sub Err-Command12_Click: MsgBox Err.Description Resume Exit_Command12_Click End Sub (B)
Simplification of the search condition
stLinkCriteria = "[sex] ='" & IIf(Me![Frame0] = 1, "male", " female") & "'" _ & " AND [age] <=" & Me![f-max_age] _ & " AND [education] ='" & Me![Combo11] & "'" _ & " AND [number-of-children] <=" & Me![f-max_number-of-children] _ & " AND [town] LIKE '" & Me![f-town] & "∗'" _ & " AND [salary] >=" & Me![f-min_salary]
IIf(IsNull(Me![f-min_salary]),0, Me![f-min_salary]]
general solution defining default value when no data are entered
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
52
Example: Multilevel selection
PERSONS(birth-certificate-number, name, surname, sex, state, ...) STATES(sex, state) In the first table the fields sex and state have text date type, in the second table sex has the date type number. The second table is so called code list and it contains all possible states, that persons can have. No key is defined here. sex stav 1 ženatý (married) 1 svobodný (single) 1 rozvedený (divorced) 1 vdovec (widower) 2 vdaná (married) 2 svobodná (single) 2 rozvedená (divorced) 2 vdova (widow) Tab.: Code list of states
Frame2_After_Update() Form_Current() SQL SELECT
In the form based on the table PERSONS the state is selected in two level (i) sex in Option Group control (ii) this provides the corresponding 4 states are included in ListBox control and here we select the real state. Selected state is then directly stored in the bounded field state of the table PERSONS, i.e. this field is contained in the property Control Source of the ListBox. If the Option Group is set to the 1st position then the value "male“ is stored into the field PERSONS.sex; Option Group in the 2nd position generates the value “female“ into the field PERSONS.sex.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
53
Let us consider that Option Group control returns 1 in the 1st position and 2 in the 2nd position. Let the ListBox name be List9 and Option Group name be Frame2. Under these assumptions the Row Source property of the ListBox is defined by the following SQL query: SELECT DISTINCTROW state FROM states WHERE sex=Frame2.Value; Whenever we change the position in the Option Group control, the contents of the ListBox must be updated. Therefore we must define the event procedure After_Update of the ListBox. If a state of the person has been already defined then we must delete it, because it corresponds to the previous information about sex which was mistaken. The sex must be then defined again. Private Sub Frame2_AfterUpdate() sex = IIf(Frame2.Value=1,"male","female") List9.Visible = True List9. Requery state = " " End Sub The last thing we must check when passing records of the table is to reconstruct the position of Option Group, contents of the ListBox including pointing up the selected state. All these action we will include into the form event procedure Form_Current(). The Else branch corresponds to the case, when no information about sex of person is included, e.g. the end of table was reached and we insert data into the new record. In this case we must provide that no position is selected in Option Group control and the ListBox is not visible. Private Sub Form_Current() If Not IsNull(sex) Then Frame2.Value = IIf (sex ="male",1,2) List9.Visible = True List9.Requery ‘ List9.Value = state Else Frame2.Value = 0 List9.Visible = False End If End Sub 3.4 Hierarchy of MS Access Objects
• Application engine Microsoft Jet (interface, opened forms, reports, modules, references)
• Database engine Microsoft Jet (DAO (Data Access Objects) - objects for direct access to data)
• Workspace ODBCDirect (it enables direct access to data in ODBC sources (Open Database Connectivity) without the database engine Microsoft Jet)
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
54
Hierarchy of the application engine Microsoft Jet
Hierarchy of the database engine Microsoft Jet Error
Errors
Containers
QueryDefs
Recordsets
Relations
TableDefs
Database
Databases
User
Users
Group
Groups
Group
Groups
User
Users
Workspace
Workspaces
DBEngine
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
55
Hierarchy of the workspace ODBCDirect
Document
Documents
Container
Containers
Field
Fields
Parameter
Parameters
QueryDef
QueryDefs
Field
Fields
Recordset
Recordsets
Field
Fields
Relation
Relations
Field
Fields
Field
Fields
Index
Indexes
TableDef
TableDefs
Database
Error
Errors
Parameter
Parameters
QueryDef
QueryDefs
Field
Fields
Recordset
Recordsets
Connection
Connections
Field
Fields
Recordset
Recordsets
Database
Databases
Workspace
Workspaces
DBEngine
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
56
3.5 Object RecordSet - object determined to manipulations with data in record level; there are 5 types of these
objects 1. Table [Set rst = db.OpenRecordset("table-name",dbOpenTable)] records of one table, it is possible to update, i.e. to add, modify and delete records.
2. Dynaset [Set rst = db.OpenRecordset("query-name",dbOpenDynaset)] (dynamic set of records) table of query results (from one or more tables) in which is
possible to add, modify and delete records.
3. Snapshot [Set rst = db.OpenRecordset("query-name",dbOpenSnapshot)] (snapshot - static copy of a set of records) table of query results, which cannot be
updated, it is used for searching and generating reports.
4. Forward-only [Set rst =db.OpenRecordset("query",dbOpenForwardOnly)] the same case as Snapshot, however it does not contain cursor, records can be passed only
in forward direction.
5. Dynamic [Set rst = db.OpenRecordset("query-name",dbOpenDynamic)] table of query results from one or more tables in which is possible to add, modify and
delete records (only in the workspace ODBCDirect). Note:
If the recordset type is not included, then MS Access tries in the workspace Microsoft Jet to assign this type by the maximal functionality in order 1, 2, 3, 4; and in the workspace Microsoft Jet ODBCDirect by the fastest answer to given query 4, 3, 2, 5.
Opening a table as a recordset in MS Access 97 Dim ws As Workspace, db As Database, rst As RecordSet ’1. Set ws = DBEngine.Workspaces(0) Set db = ws.OpenDatabase("file-name.mdb") Set rst = db.OpenRecordset("table-name") ’2. Set ws = DBEngine.Workspaces(0) Set db = ws.Databases(0) Set rst = db.OpenRecordset("table-name") ’3 Set db = DBEngine(0)(0) Set rst = db.OpenRecordset("table-name") '4. Set db = CurrentDb() Set rst = db.OpenRecordset("table-name")
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
57
Note: (Unexpected) Problems in MS Access 2000/2003 (1) Dim db As Database, rst As RecordSet open any module in Design view and set Tools → References... → (2) Dim db As Database, rst As RecordSet ... Set db = CurrentDb() Set rst = db.OpenRecordset("table-name") To avoid generating errors, we must declare Database and Recordset as follows: Dim db As DAO.Database, rst As DAO.RecordSet
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
58
Opening the SELECT query as a recordset.
Example: Determine the highest current value of a field of the automatic number data type Function MaxValue(table-name As String, column-name As String) As Byte Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("SELECT COUNT(∗) As mxf0 FROM ” _ & table-name) If rst!mxf0 = 0 Then MaxValue = 0 Else Set rst = db.OpenRecordset("SELECT MAX(" & column-name _ & ") As mxf0" & " FROM " & table-name) rst.MoveFirst MaxValue = rst!mxf0 End If rst.Close End Function Record updates Example: Increasing the electricity rate by 10 percent for all customers Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset(”customers") rst.MoveFirst While Not(rst.EOF) ' Do Until rst.EOF rst.Edit ' rst.Edit ' record → buffer rst![rate] = rst![rate] ∗1.1 ' rst![rate] = rst![rate] ∗1.1 rst.Update ' rst.Update ' buffer → record rst.MoveNext ' rst.MoveNext Wend ' Loop rst.Close The same example using the SQL command UPDATE Dim sqlcommand As String, db As DAO.Database Set db = CurrentDb() sqlcommand = “UPDATE [customers] SET rate = rate ∗1.1” (i) DoCmd.RunSQL sqlcommand (ii) db.Execute sqlcommand
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
59
Insertion of a new record
Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("table-name") ... rst.AddNew rst![field1] = … rst![field2] = … … rst.Update Deletion of the current record
Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("table-name") ... rst.Delete Note: After Delete the Update method must not be used (it leads to an error). Record sorting in recordsets of the table type (Index) (default given by the Primary Key) Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("table-name") ... rst.Index = "by-surname" … rst.Index = "Primary Key" Record sorting in a recordset of the dynaset or snapshot type (Sort) Dim db As DAO.Database, rst1 As DAO.RecordSet, rst2 As DAO.RecordSet Set db = CurrentDb() Set rst1 = db.OpenRecordset("table-name", dbOpenDynaset) rst1.Sort = “[surname], [name], [age] DESC” Set rst2 = rst1.OpenRecordset() Note:
The change of the Sort object property does not provide the change of ordering, it can be seen in a new object which is created from it.
In most cases is faster to use a recordset based on a query with ORDER BY.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
60
Record filtering in recordsets
Dim db As DAO.Database, rst1 As DAO.RecordSet, rst2 As DAO.RecordSet Set db = CurrentDb() Set rst1 = db.OpenRecordset("table-name", dbOpenDynaset) rst1.Filter = "[town] ='Brno'" Set rst2 = rst1.OpenRecordset() Note: Filtering without the use of recordsets
(1) DoCmd.OpenForm stDocName, , , stLinkCriteria (2) DoCmd.ApplyFilter stFilter … DoCmd.ShowAllRecords ‘ filtering off Search in recordsets of the table type by an index (Seek)
(i) Before the use of Seek, the current index must be set in the property Index (ii) Seek finds the first record, whose key value satisfies the comparison criterion recordset.Seek comparing-operator, key1[,key2]... Example: Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("students") rst.Index = "by surname and name" ‘ multisegment index rst.Seek "=", "Malý", "Miroslav" If rst.NoMatch Then MsgBox "required record is not found" End If ... Search in recordsets of the dynaset or snapshot type (Find...) Example: Update records with missing telephone numbers
… Dim db As DAO.Database, rst As DAO.RecordSet Dim strFind, strMsg, strTab As String Set db = CurrentDb() strTab = "Customers" Set rst = db.OpenRecordset(strTab,dbOpenDynaset) strFind = "IsNull([telephone])" rst.FindFirst strFind ‘ index is not required
it must not be omitted, otherwise
an error is evaluated
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
61
Do Until rst.NoMatch rst.Edit strMsg = "Enter the telephone number of the customer: " _ & rst![surname] & " " & rst![name] rst![telephone] = InputBox(strMsg) rst.Update rst.FindNext strFind Loop rst.Close Example: General solution – insertion of data into the arbitrary table and its arbitrary column with displaying the defined data.
Sub Enter_the_value_of(table-name As String, column-name As String) Dim db As Database, rst As Recordset, f As Field, sTab As String Dim strFind As String, s-record As String, s As String, i As Integer Set db = CurrentDb() Set rst = db.OpenRecordset(table-name, dbOpenDynaset) strFind = "IsNull([" & column-name & ”])" rst.FindFirst strFind Do Until rst.NoMatch rst.Edit s-record = "" For Each f In rst.Fields ‘ copy of values of all record fields Select Case VarType(rst.Fields(f.Name)) Case vbString s = rst.Fields(f.Name) Case vbByte, vbInteger, vbLong, vbSingle, _ vbDouble, vbCurrency s = Str(rst.Fields(f.Name)) Case vbBoolean
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
62
s = IIf(rst.Fields(f.Name), "True", "False") Case vbDate s = Format(rst.Fields(f.Name), "dd.mm.yy") Case Else s = "" End Select sTab = IIf(InStr(rst.Fields(f.Name), " "), vbTab, vbTab & vbTab) s-record = s-record & f.Name & sTab & ": " & s & vbCrLf Next f rst.Fields(column-name) = InputBox(s-record & vbCrLf & _ "Enter the value of " & column-name & ": ") rst.Update rst.FindNext strFind Loop rst.Close End Sub Alternative expression of the For loop in the previous solution For i = 0 To rst.Fields.Count − 1 Select Case VarType(rst.Fields(rst.Fields(i).Name)) Case vbString s = rst.Fields(rst.Fields(i).Name) Case vbByte, vbInteger, vbLong, vbSingle, _ vbDouble, vbCurrency s = Str(rst.Fields(rst.Fields(i).Name)) Case vbBoolean s = IIf(rst.Fields(rst.Fields(i).Name), "True", "False") Case vbDate s = Format(rst.Fields(rst.Fields(i).Name), "dd.mm.yy") Case Else s = "" End Select sTab = IIf(InStr(rst.Fields(i).Name, " "), vbTab, vbTab & vbTab) s-record = s-record & rst.Fields(i).Name & sTab & ": " & s & vbCrLf Next f Recordset clone 1) copy of the form Record Source (i.e. the table or query on which the form is based), 2) RecordsetClone form property and the object Recordset can be used for synchronization
of the Recordset record with the current form record.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
63
Example: Search in the clone with a setting of the current form record Sub Reader-list_AfterUpdate() ‘ it generates after a selection in list of readers Dim rst As DAO.Recordset, strFind As String Set rst = Me.RecordsetClone strFind = Str(Me! Reader-list) rst.FindFirst " IDreader = " & strFind If rst.NoMatch Then MsgBox "Reader with given ID is not found" Else Me.Bookmark = rst.Bookmark ‘ found record is displayed End If rst.Close End Sub Example: Search in the clone with a setting of the current form record (the 2nd version – searching by the beginning of the reader surname defined after
click on a command button by means of InputBox) Sub FindReader_Click() ‘ generated after the command button click Dim rst As DAO.Recordset, strFind As String Set rst = Me.RecordsetClone strFind = "[surname] LIKE '" & InputBox("Enter the first letters " _ & "of the searched reader name ") & "∗'" rst.FindFirst strFind If rst.NoMatch Then MsgBox ”Reader of this surname is not found" Else Me.Bookmark = rst.Bookmark ‘ found record is displayed End If rst.Close End Sub Example: Multiply the field amount in all records of the subform table by the factor defined in the other form opened after the click on a command button. Sub Multiplying_by_Factor_Click() Dim rst As Recordset, dblFactor As Double DoCmd.OpenForm “form-factor”,,,,,acDialog If IsNull(Forms![form-factor]![factor]) _ Or Forms![form-factor]![factor]=0 Then DoCmd.Close acForm, “form-factor” Exit Sub End If DoCmd.Hourglass True
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
64
dblFactor = CDbl(Forms![form-factor]![factor]) Set rst = Me! [subform-name].Form.RecordsetClone rst.MoveFirst While (Not(rst.EOF)) rst.Edit rst![amount] = rst![amount]∗ dblFaktor rst.Update rst.MoveNext Wend rst.Close Me.SetFocus DoCmd.Hourglass False End Sub 3.6 Calling SQL from VBA Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() 1. Saved query (SELECT, crosstab, … )
DoCmd.OpenQuery query-name [, view][, data-mode] view: acViewDesign, acViewNormal (default, query result), acViewPreview (page preview) data-mode: acAdd, acEdit (default), acReadOnly 2. SELECT query
Set rst = db.OpenRecordset(select_query,dbOpenDynaset) 3. Action a definition queries True (default), False
DoCmd.RunSQL query [, use-transaction] ‘ with confirmation or db.Execute query [, options] ‘ without confirmation Action: INSERT INTO, DELETE, UPDATE, SELECT INTO, definition: CREATE TABLE, DROP TABLE, ALTER TABLE, CREATE INDEX, DROP INDEX. The execution of DoCmd.RunSQL query is slower than db.Execute query. If we want to execute an action or definition SQL command by means of the Execute method and require a confirmation of this action, then we place before this command an InputBox or MsgBox command MsgBox(prompt [,buttons][,title])
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
65
Example: ... Dim strQ As String, strTable As String strQ = “DELETE ∗ FROM “ & strTabulka If MsgBox(“Are you sure in deleting all records in the table “ & _ strTable, & “?”, vbYesNo) = vbYes Then CurrentDb.Execute strQ End If ... Example: Find the maximal value assigned to a given field. Function MaxValue(given-table As String, given-field As String) As Byte Dim db As DAO.Database, rst As DAO.RecordSet Set db = CurrentDb() Set rst = db.OpenRecordset("SELECT COUNT(∗) As mxf0 FROM " & given-table) If rst!mxf0 = 0 Then MaxValue = 0 Else Set rst = db.OpenRecordset("SELECT MAX(" & given-field & ") As mxf0 " & _ "FROM " & given-table) rst.MoveFirst MaxValue = rst!mxf0 End If rst.Close End Function Transactions in MS Access Example: "Thermometer", hour-glass, loop, transaction. … Dim ws As Workspace, rst As DAO.Recorset, thermometer As Variant, ... Set ws = DBEngine.Workspaces(0) Set rst = CurrentDb.OpenRecordset("table-name") thermometer = SysCmd(acSysCmdInitMeter,“info-text", number) DoCmd.Hourglass True ws.BeginTrans ... For i = 1 To number … rst.AddNew ... rst.Update ...
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
66
thermometer = SysCmd(acSysCmdUpdateMeter, i) Next i ws.CommitTrans rst.Close DoCmd.Hourglass False thermometer = SysCmd(acSysCmdClearStatus)
4. Database Application
This application will be explained in more detail in exercises. Here we present only selected procedures.
Fig. 1. Application menu
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
67
Fig. 4.2 Option Compare Database Option Explicit Dim ppp As Integer, ccc As Integer, kkk As Single Dim sss As String Private Sub Form_Load() TabCtl33.Value = 0 ' první stránka na kartě ListTypStudia.Value = "MS" ' typ studia ListRocnik.Value = 1 ' ročník ListPredmety.Requery ' vybraný seznam předmětů ListUcitele.Value = 1 ' učitel ComboFunkce.Value = 201 ' funkce Label_pom0.Visible = False Label_pom1.Visible = False Label_pom2.Visible = False Label_pom3.Visible = False Label_pom4.Visible = False Label_pom5.Visible = False Label_pom6.Visible = False Label_pom7.Visible = False Label_pom8.Visible = False Label_pom9.Visible = False LabelCv.Caption = " " ComboZk.Value = " " ListUcFun.Value = Null ' ListUcFun.Requery ListUcOst.Value = Null ListUcOst.Requery TextPocetOstatni.Value = 0 ' TextPocetOstatni.Enabled = False CommandSaveChange.Enabled = False CheckTydny.Value = False TextTydny.Enabled = False
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
68
TextSkupiny.Enabled = False TextStudenti.Enabled = False CheckTydny.Enabled = False ComboTyp_prcv.Enabled = False TextPredmet.Enabled = False End Sub Private Sub InicializaceDetailů(enab As Integer) TextTydny.Enabled = False CheckTydny.Value = False TextSkupiny.Value = 0 TextStudenti.Value = 0 ComboTyp_prcv.Value = 0 LabelCv.Caption = " " ComboZk.Value = " " If enab = 1 Then TextSkupiny.Enabled = False TextStudenti.Enabled = False CheckTydny.Enabled = False ComboTyp_prcv.Enabled = False TextPredmet.Enabled = False End If End Sub Private Sub ListUcitele_AfterUpdate() TextPocetOstatni.Value = 0 ListUcOst.Requery End Sub Private Sub ComboOstatni_AfterUpdate() ' TextPocetOstatni.Enabled = True TextPocetOstatni.Value = 0 End Sub Private Sub ListTypStudia_AfterUpdate() ' typ studia ListRocnik.Value = 1 Select Case ListTypStudia.Value Case "DS" ListRocnik.RowSource = "1" Case "BS" ListRocnik.RowSource = "1;2;3" Case "MS" ListRocnik.RowSource = "1;2;3;4;5" Case "DIS" ListRocnik.RowSource = "1;2;3;4;5;6" End Select ListRocnik.Requery ListPredmety.Requery TextPredmet.Value = " " TextTydny.Value = 0 InicializaceDetailů (1) If ListTypStudia.Value = "DIS" Then ComboTyp_prcv.Value = 2 Else ComboTyp_prcv.Value = 0 End If End Sub Private Sub ListRocnik_AfterUpdate() ' ročník
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
69
ListPredmety.Requery ListPredmety.Value = 0 TextPredmet.Value = " " TextTydny.Value = 0 InicializaceDetailů (1) End Sub Private Sub ListPredmety_AfterUpdate() ' předměty Dim db As Database, rst As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset("predmety") rst.Index = "PrimaryKey" rst.Seek "=", ListPredmety.Value TextSkupiny.Enabled = True TextStudenti.Enabled = True CheckTydny.Enabled = True ComboTyp_prcv.Enabled = True ' TextPredmet.Enabled = True TextPredmet.Value = rst!nazev TextTydny.Value = rst!tydnu ppp = rst!predn ccc = rst!cvic sss = rst!semestr rst.Close If sss = "zim" Then Label_pom5.Caption = 0 ' t_LS Label_pom7.Caption = 0 ' h_LS Else Label_pom4.Caption = 0 ' t_ZS Label_pom6.Caption = 0 ' h_ZS End If ' další složky z recordsetu InicializaceDetailů (0) End Sub Private Sub CheckTydny_AfterUpdate() TextTydny.Enabled = CheckTydny.Value End Sub Private Sub CommandPridatFunkci_Click() On Error GoTo Err_CommandPridatFunkci_Click Dim db As Database, rst As Recordset Dim strQ As String, mx As Integer Set db = CurrentDb() '(1) Set rst = db.OpenRecordset("uc_fun") ' mx = 0 ' rst.MoveFirst ' While Not rst.EOF ' If rst!IDautom > mx Then mx = rst!IDautom ' rst.MoveNext ' Wend ' mx = mx + 1 ' MsgBox "mx1=" + Str(mx) ' rst.Close '(2) Set rst = db.OpenRecordset("MXuc_fun", dbOpenDynaset) ' rst.MoveFirst ' mx = rst!mxf + 1
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
70
' MsgBox "mx2=" + Str(mx) ' rst.Close '(3) Set rst = db.OpenRecordset("SELECT MAX(IDautom) As mxf0 FROM uc_fun") ' rst.MoveFirst ' mx = rst!mxf0 + 1 ' MsgBox "mx3=" + Str(mx) ' rst.Close '(4) mx = MaxHodnota("uc_fun", "IDautom") + 1 ' MsgBox "MaxHodnota=" + Str(mx) Label_pom0.Caption = mx If Not IsNull(ListUcitele.Value) And Not IsNull(ComboFunkce.Value) Then strQ = "INSERT INTO uc_fun" _ & "(IDuc,IDfu,IDautom)" _ & "VALUES (ListUcitele.Value,ComboFunkce.Value,Label_pom0.Caption)" ' & "VALUES (ListUcitele.Value,ComboFunkce.Value,MaxHodnota('uc_fun', 'IDautom') + 1)" DoCmd.RunSQL strQ ListUcFun.Requery Else MsgBox "Nový záznam o funkci nelze zapsat," & vbCrLf & _ "protože údaje jsou neúplné" End If '(5) If Not IsNull(ListUcitele.Value) And Not IsNull(ComboFunkce.Value) Then ' strQ = "INSERT INTO uc_fun" _ ' & "(IDuc,IDfu" _ ' & "VALUES (ListUcitele.Value,ComboFunkce.Value)" ' DoCmd.RunSQL strQ ' ListUcFun.Requery ' Else ' MsgBox "Nový záznam o funkci nelze zapsat," & vbCrLf & _ ' "protože údaje jsou neúplné" ' End If Exit_CommandPridatFunkci_Click: Exit Sub Err_CommandPridatFunkci_Click: MsgBox Err.Description Resume Exit_CommandPridatFunkci_Click End Sub Private Sub CommandZrusitFunkci_Click() On Error GoTo Err_CommandZrusitFunkci_Click Dim strQ As String If Not IsNull(ListUcFun.Value) Then strQ = "DELETE * FROM uc_fun WHERE IDautom=ListUcFun.Value" DoCmd.RunSQL strQ ListUcFun.Value = Null ListUcFun.Requery Else MsgBox "Nelze nic zrušit, protože žádný záznam" & vbCrLf & _ "o zastávané funkci nebyl vybrán" End If Exit_CommandZrusitFunkci_Click: Exit Sub Err_CommandZrusitFunkci_Click: MsgBox Err.Description Resume Exit_CommandZrusitFunkci_Click
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
71
End Sub Private Sub CommandPridatOstatni_Click() On Error GoTo Err_CommandPridatOstatni_Click Dim db As Database, rst As Recordset Dim strQ As String, mx As Integer Set db = CurrentDb() mx = MaxHodnota("uc_ost", "IDautom") + 1 Label_pom1.Caption = mx If Not IsNull(ListUcitele.Value) And Not IsNull(ComboOstatni.Value) _ And TextPocetOstatni.Value > 0 Then strQ = "INSERT INTO uc_ost" _ & "(IDuc,IDost,pocet,IDautom)" _ & "VALUES (ListUcitele.Value,ComboOstatni.Value,TextPocetOstatni.Value,Label_pom1.Caption)" DoCmd.RunSQL strQ ListUcOst.Requery Else MsgBox "Nový záznam o činnosti nelze zapsat," & vbCrLf & _ "protože údaje jsou neúplné" End If Exit_CommandPridatOstatni_Click: Exit Sub Err_CommandPridatOstatni_Click: MsgBox Err.Description Resume Exit_CommandPridatOstatni_Click End Sub Private Sub CommandZrusitOst_Click() On Error GoTo Err_CommandZrusitOst_Click Dim strQ As String If Not IsNull(ListUcOst.Value) Then strQ = "DELETE * FROM uc_ost WHERE IDautom=ListUcOst.Value" DoCmd.RunSQL strQ ListUcOst.Value = Null ListUcOst.Requery Else MsgBox "Nelze nic zrušit, protože žádný záznam" & vbCrLf & _ "o ostatní činnosti učitele nebyl vybrán" End If Exit_CommandZrusitOst_Click: Exit Sub Err_CommandZrusitOst_Click: MsgBox Err.Description Resume Exit_CommandZrusitOst_Click End Sub Private Sub CommandOpravitOst_Click() On Error GoTo Err_CommandOpravitOst_Click Dim db As Database, rst As Recordset Dim strQ As String If Not IsNull(ListUcOst.Value) Then Set db = CurrentDb() Set rst = db.OpenRecordset("uc_ost") rst.Index = "PrimaryKey" rst.Seek "=", ListUcOst.Value ' TextPocetOstatni.Enabled = True Label_pom1.Caption = rst!IDautom ComboOstatni.Value = rst!IDost TextPocetOstatni.Value = rst!pocet rst.Close
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
72
ListUcitele.Enabled = False TextPocetOstatni.SetFocus ' změna fokusu, aby se tlačítko opět mohlo znepřístupnit CommandSaveChange.Enabled = True Else MsgBox "Nelze nic opravovat, protože žádný záznam" & vbCrLf & _ "o ostatní činnosti učitele nebyl vybrán" End If Exit_CommandOpravitOst_Click: Exit Sub Err_CommandOpravitOst_Click: MsgBox Err.Description Resume Exit_CommandOpravitOst_Click End Sub Private Sub CommandSaveChange_Click() On Error GoTo Err_CommandSaveChange_Click Dim strQ As String strQ = "UPDATE uc_ost SET IDost=ComboOstatni.Value, pocet=TextPocetOstatni.Value " & _ "WHERE IDautom=Label_pom1.Caption" DoCmd.RunSQL strQ ListUcOst.Requery ListUcitele.Enabled = True ComboOstatni.SetFocus CommandSaveChange.Enabled = False Exit_CommandSaveChange_Click: Exit Sub Err_CommandSaveChange_Click: MsgBox Err.Description Resume Exit_CommandSaveChange_Click End Sub Private Sub ComboTyp_prcv_AfterUpdate() Dim db As Database, rst As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset("pred_cv") rst.Index = "PrimaryKey" rst.Seek "=", ComboTyp_prcv.Value kkk = rst!koef rst.Close Select Case ComboTyp_prcv.Value Case 1, 7, 11, 15 LabelCv.Caption = "P" Select Case ListPredmety.Value Case "1in", "1in-", "ai", "bzi", "0in", "dtx", "fza", "rdb", "rmt", "rps", "scn", _ "vci", "vir", "vjc", "vm2", "v2a", "vzp", "vb0", "vd", "vdp", "vr0", "vu0" ComboZk.Value = " " Case Else ComboZk.Value = "zk" End Select Case 2 LabelCv.Caption = "Konz" ComboZk.Value = "zk" Case 3, 8, 12, 16 LabelCv.Caption = "C1" Select Case ListPredmety.Value Case "dtx", "fza", "rdb", "rmt", "rps", "scn", _ "vci", "vir", "vjc", "vm2", "v2a", "vzp", "vb0" ComboZk.Value = "kz" Case "bzi", "0in", "vd", "vdp", "vr0", "vu0" ComboZk.Value = "z"
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
73
Case Else ComboZk.Value = " " End Select Case 4, 9, 13, 17 LabelCv.Caption = "C2a" Select Case ListPredmety.Value Case "1in", "1in-", "ai", "dtx", "fza", "rdb", "rmt", "rps", "scn", _ "vci", "vir", "vjc", "vm2", "v2a", "vzp", "vb0" ComboZk.Value = "kz" Case "bzi", "0in", "vd", "vdp", "vr0", "vu0" ComboZk.Value = "z" Case Else ComboZk.Value = " " End Select Case 5, 10, 14, 18 LabelCv.Caption = "C2b" Select Case ListPredmety.Value Case "1in", "1in-", "ai", "dtx", "fza", "rdb", "rmt", "rps", "scn", _ "vci", "vir", "vjc", "vm2", "v2a", "vzp", "vb0" ComboZk.Value = "kz" Case "bzi", "0in", "vd", "vdp", "vr0", "vu0" ComboZk.Value = "z" Case Else ComboZk.Value = " " End Select Case 6 LabelCv.Caption = "sem." ComboZk.Value = " " End Select End Sub Private Sub CommandSaveUV_Click() On Error GoTo Err_CommandSaveUV_Click Dim strQ As String, mx As Integer, koef_zk As Single mx = MaxHodnota("uc_uv", "IDuv") + 1 Label_pom2.Caption = mx Select Case ListTypStudia.Value Case "DS" Label_pom3.Caption = "51" Case "BS" Label_pom3.Caption = "81" Case "MS" Label_pom3.Caption = "11" Case "DIS" Label_pom3.Caption = "??" End Select If sss = "zim" Then Label_pom4.Caption = TextTydny.Value ' t_ZS Label_pom6.Caption = IIf(Left(LabelCv.Caption, 1) = "C", ccc, ppp) ' h_ZS Else Label_pom5.Caption = TextTydny.Value ' t_LS Label_pom7.Caption = IIf(Left(LabelCv.Caption, 1) = "C", ccc, ppp) ' h_LS End If Label_pom8.Caption = kkk Select Case ComboZk.Value Case "zk" koef_zk = 0.7 Case "kz" koef_zk = 0.5 Case Else
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
74
koef_zk = 0 End Select If IsNull(ComboTyp_prcv.Value) Or (TextSkupiny.Value = 0) Or _ (TextStudenti.Value = 0) Then MsgBox "Nový záznam o výuce nelze zapsat," & vbCrLf & _ "protože údaje jsou neúplné" Else Label_pom9.Caption = (Label_pom4.Caption * Label_pom6.Caption + _ Label_pom5.Caption * Label_pom7.Caption) * TextSkupiny.Value * kkk _ + TextStudenti.Value * koef_zk strQ = "INSERT INTO uc_uv" _ & "(IDuv,IDuc,IDpred,rocnik,forma_st,t_ZS,t_LS,h_ZS,h_LS," & _ "IDprcv,typ_prcv,forma_zk,n_skupin,n_stud,koef,sum_radek)" & _ "VALUES (Label_pom2.Caption,ListUcitele.Value,ListPredmety.Value," & _ "ListRocnik.Value,Label_pom3.Caption," & _ "Label_pom4.Caption,Label_pom5.Caption,Label_pom6.Caption,Label_pom7.Caption," & _ "ComboTyp_prcv.Value,LabelCv.Caption,ComboZk.Value," & _ "TextSkupiny.Value,TextStudenti.Value,Label_pom8.Caption,Label_pom9.Caption)" DoCmd.RunSQL strQ ListUcOst.Requery End If Exit_CommandSaveUV_Click: Exit Sub Err_CommandSaveUV_Click: MsgBox Err.Description Resume Exit_CommandSaveUV_Click End Sub Private Sub CommandKonec_Click() On Error GoTo Err_CommandKonec_Click DoCmd.Close Exit_CommandKonec_Click: Exit Sub Err_CommandKonec_Click: MsgBox Err.Description Resume Exit_CommandKonec_Click End Sub
Source row of subject list is represented by the following query:
SELECT DISTINCTROW [predmety].[kod], [predmety].[rocnik], [predmety].[semestr], [predmety].[nazev], [predmety].[studium], [predmety].[obor], [predmety].[tydnu], [predmety].[predn], [predmety].[cvic], [predmety].[typcvic], [predmety].[kredit], [predmety].[zk] FROM [predmety] WHERE studium=ListTypStudia.Value AND rocnik=ListRocnik.Value;
Teaching + zk, kz:
SELECT DISTINCTROW [Uc_UV].[IDuv], [Uc_UV].[rocnik], [Uc_UV].[forma_st], [Uc_UV].[IDpred], [Uc_UV].[typ_prcv], [Uc_UV].[koef], [predmety].[nazev], [Uc_UV].[t_ZS], [Uc_UV].[t_LS], [Uc_UV].[h_ZS], [Uc_UV].[h_LS], [Uc_UV].[forma_zk], [predmety].[obor], [Uc_UV].[n_skupin], [Uc_UV].[n_stud], [Uc_UV].[sum_radek] FROM Uc_UV,predmety WHERE Uc_UV.IDuc=ComboV_uc.Value AND Uc_UV.IDpred=predmety.kod;
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
75
Fig. 4.3. Calculations of ZH
Option Compare Database Option Explicit Private Sub Form_Load() Me!ComboV_uc = 0 ListV_ostatni.Requery ListV_funkce.Requery ListV_vyuka.Requery End Sub Private Sub ComboV_uc_AfterUpdate() Dim db As Database, rst As Recordset Dim a As Single, celkem As Single Set db = CurrentDb() celkem = 0 Me!Textsum_cin = 0 Me!Textsum_fun = 0 Me!Textsum_vyuka = 0 Set rst = db.OpenRecordset("SELECT SUM(extra_cin.koef * uc_ost.pocet) " _ & "AS sum_cin " _ & "FROM uc_ost,extra_cin " _ & "WHERE uc_ost.IDuc=" & Me!ComboV_uc & " AND " _ & "uc_ost.IDost=extra_cin.IDextra", dbOpenSnapshot) If IsNull(rst!sum_cin) Then a = 0 Else rst.MoveFirst a = rst!sum_cin
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
76
Me!Textsum_cin = Format(a, "###0.0") End If ListV_ostatni.Requery rst.Close celkem = celkem + a Set rst = db.OpenRecordset("SELECT SUM(funkce.ZH) AS sum_fun " _ & "FROM uc_fun,funkce " _ & "WHERE uc_fun.IDuc=" & Me!ComboV_uc & " AND " _ & "uc_fun.IDfu=funkce.IDfun", dbOpenSnapshot) If IsNull(rst!sum_fun) Then a = 0 Else rst.MoveFirst a = rst!sum_fun Me!Textsum_fun = Format(a, "###0.0") End If ListV_funkce.Requery rst.Close celkem = celkem + a Set rst = db.OpenRecordset("SELECT SUM(uc_UV.sum_radek) AS sum_vyuka " _ & "FROM uc_UV " _ & "WHERE uc_UV.IDuc=" & Me!ComboV_uc, dbOpenSnapshot) If IsNull(rst!sum_vyuka) Then a = 0 Else rst.MoveFirst a = rst!sum_vyuka Me!Textsum_vyuka = Format(a, "###0.0") End If ListV_vyuka.Requery rst.Close celkem = celkem + a Me!TextSum_ZH = Format(celkem, "###0.0") End Sub Private Sub CommandCelkemOdbory_Click() On Error GoTo Err_CommandCelkemOdbory_Click Dim db As Database Dim rstOdb As Recordset, rstUc As Recordset, rst As Recordset Dim ZH As Single, ost As Single, fun As Single, vyuka As Single Dim celkemUc As Single, celkem As Single Dim strQ As String strQ = "DELETE * FROM VyslOdbory" DoCmd.RunSQL strQ Set db = CurrentDb() Set rstOdb = db.OpenRecordset("VyslOdbory") Set rstUc = db.OpenRecordset("Ucitele") rstUc.MoveFirst celkem = 0 Do While Not rstUc.EOF celkemUc = 0 Set rst = db.OpenRecordset("SELECT SUM(uc_UV.sum_radek) AS sum_vyuka " _
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
77
& "FROM uc_UV " _ & "WHERE uc_UV.IDuc=" & rstUc!IDped, dbOpenSnapshot) If IsNull(rst!sum_vyuka) Then vyuka = 0 Else rst.MoveFirst vyuka = rst!sum_vyuka End If rst.Close celkemUc = celkemUc + vyuka Set rst = db.OpenRecordset("SELECT SUM(extra_cin.koef * uc_ost.pocet) " _ & "AS sum_cin " _ & "FROM uc_ost,extra_cin " _ & "WHERE uc_ost.IDuc=" & rstUc!IDped & " AND " _ & "uc_ost.IDost=extra_cin.IDextra", dbOpenSnapshot) If IsNull(rst!sum_cin) Then ost = 0 Else rst.MoveFirst ost = rst!sum_cin End If rst.Close celkemUc = celkemUc + ost Set rst = db.OpenRecordset("SELECT SUM(funkce.ZH) AS sum_fun " _ & "FROM uc_fun,funkce " _ & "WHERE uc_fun.IDuc=" & rstUc!IDped & " AND " _ & "uc_fun.IDfu=funkce.IDfun", dbOpenSnapshot) If IsNull(rst!sum_fun) Then fun = 0 Else rst.MoveFirst fun = rst!sum_fun End If rst.Close celkemUc = celkemUc + fun rstOdb.AddNew rstOdb!Iduc = rstUc!IDped rstOdb!odbor = rstUc!odbor rstOdb!jmeno = rstUc!jmeno rstOdb!ZH = vyuka rstOdb!ost = ost rstOdb!fun = fun rstOdb!Uc_celkem = celkemUc rstOdb.Update rstUc.MoveNext celkem = celkem + celkemUc Loop rstOdb.Close rstUc.Close ListUAI.Requery ListOdbory.Requery ListSumyUc.Requery
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
78
Exit_CommandCelkemOdbory_Click: Exit Sub Err_CommandCelkemOdbory_Click: MsgBox Err.Description Resume Exit_CommandCelkemOdbory_Click End Sub Private Sub CommandZrusitVyuku_Click() On Error GoTo Err_CommandZrusitVyuku_Click Dim strQ As String If Not IsNull(ListV_vyuka) Then strQ = "DELETE * FROM uc_uv WHERE IDuv=ListV_vyuka.Value" DoCmd.RunSQL strQ ListV_vyuka.Value = Null ListV_vyuka.Requery Call ComboV_uc_AfterUpdate Else MsgBox "Nelze nic zrušit, protože žádný záznam" & vbCrLf & _ "o výuce předmětu nebyl vybrán" End If Exit_CommandZrusitVyuku_Click: Exit Sub Err_CommandZrusitVyuku_Click: MsgBox Err.Description Resume Exit_CommandZrusitVyuku_Click End Sub Private Sub CommandOpravitVyuku_Click() On Error GoTo Err_CommandOpravitVyuku_Click Dim stDocName As String Dim stLinkCriteria As String If Not IsNull(ListV_vyuka) Then stDocName = "OpravaVyuky" DoCmd.OpenForm stDocName, , , stLinkCriteria, , , ListV_vyuka Else MsgBox "Nelze nic opravovat, protože žádný záznam" & vbCrLf & _ "o výuce předmětu nebyl vybrán" End If Exit_CommandOpravitVyuku_Click: Exit Sub Err_CommandOpravitVyuku_Click: MsgBox Err.Description Resume Exit_CommandOpravitVyuku_Click End Sub Private Sub CommandKonecVypoctu_Click() On Error GoTo Err_CommandKonecVypoctu_Click DoCmd.Close Exit_CommandKonecVypoctu_Click: Exit Sub Err_CommandKonecVypoctu_Click: MsgBox Err.Description Resume Exit_CommandKonecVypoctu_Click End Sub
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
79
References [1] Benyon-Davies, P.: Database Systems. Macmillan Press, London, 1996. ISBN 0-333-
63667-8. [2] Bíla, J., Král, F.: Databázové a znalostní systémy. Skriptum ČVUT FS, Praha, 1999. [3] Connolly, T. and Begg, C.: Database Systems: A Practical Approach to Design,
Implementation, and Management. Addison Wesley, 2001. ISBN 0201708574. [4] Date, C.J.: An Introduction to Database Systems. Addison Wesley, 2003. ISBN
0321197844. [5] Duží, M.: Konceptuální modelování – datový model HIT. Slezská univerzita, Ostrava,
2000. [6] Elmasri, R. and Navathe, S.B.: Fundamentals of Database Systems. Addison Wesley,
2003. ISBN 0321122267. [7] Farana, R.: Tvorba relačních databázových systémů. VŠB TU, Ostrava, 1999. [8] Farana, R.: Aplikace počítačů v řízení. Relační databáze. VŠB TU, Ostrava, 1995. [9] Fortier, P.J.: Database Systems Handbook. McGraw-Hill, 1997, ISBN 0-07-021626-6. [10] Garcia-Molina, H., Ullman, J.D. and Widom, J.D.: Database Systems: The Complete
Book. Prentice Hall, 2001. ISBN 0130319953. [11] Halaška, I., Pokorný, J., Valenta, M.: Databázové systémy. Cvičení. Skriptum ČVUT
FEL, Praha, 2004. [12] Havlát, T., Benešovský, M.: Úvod do databázových systémů. Skriptum UJEP PřF, Brno,
1984. [13] Hellerstein, J.M. and Stonebraker, M. (eds.): Readings in Database Systems. The MIT
Press, 2005. ISBN 0262693143. [14] Lacko, L.: PHP a MySQL. CP Books, Brno, 2005. [15] Lacko, L.: SQL. Computer Press, Brno, 2003. [16] McCullough-Dieter, C.: Mistrovství v Oracle 8. Computer Press, Praha, 1999. [17] Pokorný, J.: Visual Basic pro aplikace Accessu 2000. Kopp, České Budějovice, 2000. [18] Pokorný, J.: Office 97 a Internet. Kopp, České Budějovice, 1997. [19] Pokorný J.: Učíme se SQL. PLUS, Praha, 1993. [20] Pokorný, J.: Konstrukce databázových systémů. Skriptum ČVUT FEL, Praha, 2004. [21] Pokorný, J., Halaška, I.: Databázové systémy. Skriptum ČVUT FEL, Praha, 2004. [22] Pokorný, J., Halaška, I.: Databázové systémy. Vybrané kapitoly a cvičení. Karolinum,
Praha, 1993. [23] Pokorný, J., Halaška, I.: Databázové systémy. Vybrané kapitoly a cvičení. Karolinum –
nakladatelství Univerzity Karlovy, Praha, 1998. [24] Richta, K., Sochor, J.: Projektování programových systémů. ČVUT FEL, Praha, 1994. [25] Riordan, R.: Designing Effective Database Systems. Addison-Wesley Professional,
2005. ISBN 0321290933. [26] Rob, P. and Coronel, C.M.: Database Systems: Design, Implementation and
Management. Course Technology, 2004. ISBN 061921323X. [27] Shah, N.: Database Systems Using Oracle. Prentice Hall, 2004. ISBN 0131018574. [28] Straka, M.: Vývoj databázových aplikací. Grada, Praha, 1992.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
80
[29] Šimůnek, M.: SQL - kompletní kapesní průvodce. Grada, Praha, 1999. [30] Ullman, L.: PHP a MySQL. Computer Press, Brno, 2004. [31] Viescas, J.: Mistrovství v Microsoft Access 2000. Computer Press, Praha, 2000. [32] Williams, H.E., Lane, D.: PHP a MySQL. Vytváříme webové databázové aplikace.
Computer Press, Praha, 2002.
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
81
Terminology A aggregation function agregační funkce argument argument, parametr (procedury/funkce) Armstrong’s axioms Armstrongovy axiomy assignment statement přiřazovací příkaz attribute atribut augmentation rule pravidlo zvětšení B batch processing zpracování v dávkách Boyce-Codd normal form Boyce-Coddova normální forma (BCNF) C Cartesian product kartézský součin check box zaškrtávací pole (= ano/ne) closure uzávěr collection kolekce combo box control pole se seznamem command button příkazové tlačítko completeness úplnost conditional statement podmíněný příkaz consistency konzistence controls řídící prvky (např. ve formulářích) crosstab query křížový dotaz D DAO Data Access Objects data mining dolování dat data model datový model database databáze database design návrh datových struktur DBMS Database Management System DDL Data Definition Language DFD Data Flow Diagram DML Data Manipulation Language decision making rozhodování decomposition theorem dekompoziční teorém, věta o rozkladu degree řád, stupeň deletion anomaly anomálie zrušení division dělení domain doména, obor hodnot
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
82
E entity entita, objekt (reálného světa) E-R diagram Entity-Relationship diagram event procedure událostní procedura expression výraz F field pole, položka filtering filtrování first normal form 1. normální forma (1NF) foreign key cizí klíč fourth normal form 4. normální forma (4NF) form formulář function funkce functional dependency funkční závislost G H heap halda, hromada hierarchical data model hierarchický datový model I inclusion rule pravidlo inkluze inconsistency nekonzistence independence nezávislost index (file) index(ový soubor) inference rules odvozovací pravidla insertion anomaly anomálie vložení integrity constraints integritní omezení intersection průnik J join operation operace spojení jump statement příkaz skoku K key attribute klíčový atribut, klíč L list box control seznam
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
83
loop statement příkaz cyklu lossless decomposition bezeztrátový rozklad M many-to-many relationship relace M:N multivalued functional dependency multizávislost N natural join operation operace přirozeného spojení normal form normální forma O object object ODBC Open Database Connectivity one-to-many relationship relace 1:N one-to-one relationship relace 1:1 P partial functional dependency částečná funkční závislost primary key primární klíč procedure procedura projection projekce Q query dotaz R radio button (option group control) přepínač recordset recordset, množina záznamů redundancy redundance, nadbytečnost reference integrity referenční integrita relation relace relational algebra relační algebra relational calculus relační kalkul relational data model relační datový model relational scheme relační schéma relationship vztah report sestava S subquery poddotaz subroutine podprogram
© Miloš Šeda: Database Systems. Brno University of Technology, FME, November 2005
84
sharing sdílení searching hledání, vyhledávání second normal form 2. normální forma (2NF) selection výběr snapshot snímek soundness bezespornost sorting řazení, uspořádávání (podle velikosti, abecedy) SQL Structured Query Language T table tabulka textbox control textové pole third normal form 3. normální forma (3NF) transaction transakce transitivity rule pravidlo tranzitivity transitive closure tranzitivní uzávěr transitive functional dependency tranzitivní funkční závislost tuple n-tice U union sjednocení update aktualizovat user-defined data type uživatelem definovaný datový typ V validation rule ověřovací pravidlo VBA Visual Basic for Applications W workspace pracovní oblast