第 4 章: sql
DESCRIPTION
第 4 章: SQL. 基本结构 集合运算 合计函数 空值 嵌套子查询 导出关系 视图 数据库更新 连接关系 DDL Embedded SQL, ODBC 及 JDBC. 例子中所用模式. 基本结构. SQL 基于集合与关系运算并作了某些修改和增强 典型的 SQL 查询形如 : select A 1 , A 2 , ..., A n from r 1 , r 2 , ..., r m where P A i 是属性 r i 是表 P 是谓词 等价于关系代数表达式 - PowerPoint PPT PresentationTRANSCRIPT
©Silberschatz, Korth and Sudarshan4.1Database System Concepts
第第 44 章章 : : SQLSQL
基本结构 集合运算 合计函数 空值 嵌套子查询 导出关系 视图 数据库更新 连接关系 DDL Embedded SQL, ODBC及 JDBC
©Silberschatz, Korth and Sudarshan4.2Database System Concepts
例子中所用模式例子中所用模式
©Silberschatz, Korth and Sudarshan4.3Database System Concepts
基本结构基本结构 SQL 基于集合与关系运算并作了某些修改和增强 典型的 SQL 查询形如 :
select A1, A2, ..., An
from r1, r2, ..., rm
where P Ai 是属性 ri 是表 P 是谓词
等价于关系代数表达式
A1, A2, ..., An(P (r1 x r2 x ... x rm))
SQL 查询的结果是一个关系 .
©Silberschatz, Korth and Sudarshan4.4Database System Concepts
select select 子句子句 select 子句对应于关系代数的投影运算 . 用于列出想要的查询结果
中的属性 .
从 loan 关系求所有分行的名称select branch-namefrom loan
在 “纯” 关系代数语法中 , 对应查询是 :
branch-name(loan)
select 子句中用 * 表示 “所有属性”
select *from loan
注意 : SQL 不允许在名字中用 ‘ -’ 字符 , 因此在实际系统中当用branch_name 而非 branch-name. 本书用 ‘ -’ 是因为它好看一点 !
注意 : SQL 是不分大小写的 .
©Silberschatz, Korth and Sudarshan4.5Database System Concepts
select select 子句子句 ((续续 ))
SQL 允许关系与查询结果中出现重复元组 .
可用关键字 distinct 强制删除重复元组 .从 loan 关系求所有分行名并删除重复元组
select distinct branch-namefrom loan
关键字 all 声明保留重复元组select all branch-namefrom loan
这是缺省情形 , 可省略
©Silberschatz, Korth and Sudarshan4.6Database System Concepts
select select 子句子句 ((续续 ))
select 子句可包含使用 +, –, , / 运算以及常量和属性的算术表达式 .
查询select loan-number, branch-name, amount 100from loan
将 loan 关系的 amount 属性乘以 100.
©Silberschatz, Korth and Sudarshan4.7Database System Concepts
where where 子句子句 where 子句对应于关系代数的选择谓词 . 其中的谓词涉及 from
子句中出现的关系的属性 .
求 Perryridge 分行发出的所有额度超过 $1200 的贷款的贷款号 .select loan-numberfrom loanwhere branch-name = ‘Perryridge’ and amount >
1200
比较结果可用逻辑连接词 and, or, not 组合在一起 .
可对算术表达式的结果进行比较 .
©Silberschatz, Korth and Sudarshan4.8Database System Concepts
where where 子句子句 ((续续 ))
SQL的 between 运算符可以简化介于两个值之间的比较 .
求额度介于 $90,000 与 $100,000 之间的贷款的贷款号select loan-numberfrom loanwhere amount between 90000 and 100000
©Silberschatz, Korth and Sudarshan4.9Database System Concepts
from from 子句子句 from 子句对应于关系代数的笛卡尔积运算 . 它列出了查询中要扫描的关系 .
求笛卡尔积 borrower x loan select
from borrower, loan
求所有在 Perryridge 分行有贷款的客户的姓名 , 贷款号和贷款数量 .select customer-name, borrower.loan-number, amountfrom borrower, loanwhere borrower.loan-number = loan.loan-number and
branch-name = ‘Perryridge’
©Silberschatz, Korth and Sudarshan4.10Database System Concepts
重命名操作重命名操作 SQL 允许对关系和属性用 as 子句重命名 :
old-name as new-name
求所有客户的姓名 , 贷款号和贷款数量 ; 将 loan-number 列改名为 loan-id.
select customer-name, borrower.loan-number as loan-id, amountfrom borrower, loanwhere borrower.loan-number = loan.loan-number
©Silberschatz, Korth and Sudarshan4.11Database System Concepts
元组变量元组变量 元组变量是在 from 子句中用 as 子句定义的 .
求所有有贷款的客户的姓名和贷款号 .
select customer-name, T.loan-number, S.amount from borrower as T, loan as S where T.loan-number = S.loan-number
求比位于 Brooklyn 的某分行资产多的分行的名字 .
select distinct T.branch-name from branch as T, branch as S where T.assets > S.assets and S.branch-city = ‘Brooklyn’
©Silberschatz, Korth and Sudarshan4.12Database System Concepts
串操作串操作 SQL 包含串匹配运算用于比较字符串 . 模式用两个特殊字符描述 : 百分号 (%). % 字符可与任何字符串匹配 .
下划线 (_). _ 字符与任一字符匹配 .
求所有街道名称包含子串 “ Main” 的客户的姓名 .select customer-namefrom customerwhere customer-street like ‘%Main%’
若要匹配串“ Main%” 则需用like ‘Main\%’ escape ‘\’
SQL 支持许多串操作 连接 ( “||”)
大小写转换 求串长度 , 取子串 , etc.
©Silberschatz, Korth and Sudarshan4.13Database System Concepts
元组的显示顺序元组的显示顺序 按字母顺序列出在 Perryridge 分行有贷款的客户的姓名
select distinct customer-namefrom borrower, loanwhere borrower loan-number - loan.loan-number and branch-name = ‘Perryridge’order by customer-name
可对每个排序属性使用 desc 指定降序 , asc 指定升序 ; 升序是缺省顺序 . E.g. order by customer-name desc
©Silberschatz, Korth and Sudarshan4.14Database System Concepts
重复元组重复元组 对于有重复元组的关系 , SQL 定义了运算结果中重复元组的拷贝
数如何确定 .
一些关系代数运算的多重集合版本 – 给定关系 r1 和 r2:
1. 若在 r1 中元组 t1 有 c1 份拷贝 , 且 t1 满足选择条件 ,, 则在 (r1)中 t1 有 c1 份拷贝 .
2. 对 r1 中元组 t1 的每一拷贝 , 在 A(r1) 中有元组 A(t1) 的一份拷贝 , 这里 A(t1) 表示元组 t1 的投影 .
3. 若在 r1 中元组 t1 有 c1 份拷贝 , 在 r2 中元组 t2 有 c2 份拷贝 , 则在r1 x r2 中元组 t1. t2 有 c1 x c2 份拷贝
©Silberschatz, Korth and Sudarshan4.15Database System Concepts
重复元组重复元组 ((续续 ))
例如 : 假设有多重集关系 r1 (A, B) 和 r2 (C) 如下 :
r1 = {(1, a) (2,a)} r2 = {(2), (3), (3)}
则 B(r1) 为 {(a), (a)}, B(r1) x r2 为
{(a,2), (a,2), (a,3), (a,3), (a,3), (a,3)}
SQL 重复元组的语义 :
select A1,, A2, ..., An
from r1, r2, ..., rm
where P
等价于下列表达式的多重集版本 :
A1,, A2, ..., An(P (r1 x r2 x ... x rm))
©Silberschatz, Korth and Sudarshan4.16Database System Concepts
集合运算集合运算 关系的集合操作 union, intersect, except 对应于关系代数运算
以上操作自动删除重复元组 ; 为了保留所有重复元组应使用对应
的多重集版本 union all, intersect all, except all.
假如一个元组在 r 中发生 m 次 , 在 s 中发生 n 次 , 则 :
在 r union all s 中发生 m + n 次 在 r intersect all s 中发生 min(m,n) 次 在 r except all s 中发生 max(0, m – n) 次
©Silberschatz, Korth and Sudarshan4.17Database System Concepts
集合操作集合操作 求有贷款或账户的客户
(select customer-name from depositor)union(select customer-name from borrower)
求既有贷款又有账户的客户(select customer-name from depositor)intersect(select customer-name from borrower)
求只有账户没有贷款的客户(select customer-name from depositor)except(select customer-name from borrower)
©Silberschatz, Korth and Sudarshan4.18Database System Concepts
合计函数合计函数 以下函数对关系中某一列值的多重集进行计算并返回单个值
avg: 平均值min: 最小值max: 最大值sum: 总和count: 值的个数
©Silberschatz, Korth and Sudarshan4.19Database System Concepts
合计函数合计函数 ((续续 ))
求 Perryridge 分行的平均账户余额 .
select avg (balance)from accountwhere branch-name = ‘Perryridge’
求 customer 关系中的元组个数select count (*)from customer
求银行存款人数 .
select count (distinct customer-name)from depositor
©Silberschatz, Korth and Sudarshan4.20Database System Concepts
合计函数合计函数 – – Group ByGroup By
求每个分行的存款人数 .
select branch-name, count (distinct customer-name)from depositor, accountwhere depositor.account-number = account.account-numbergroup by branch-name
注意 : select 子句中处于合计函数之外的属性必须在 group by 属性列表中出现!
©Silberschatz, Korth and Sudarshan4.21Database System Concepts
合计函数合计函数 – – Having Having 子句子句
求平均账户余额超过 $1,200 的所有分行名及平均余额 .select branch-name, avg (balance)from accountgroup by branch-namehaving avg (balance) > 1200
注意 : having 子句中的谓词是在分组形成之后起作用的 , 而 where 子句中的谓词是在分组形成之前起作用的
©Silberschatz, Korth and Sudarshan4.22Database System Concepts
空值空值 元组在某些属性上可以有空值 , 用 null 表示 null 表达未知的值或不存在的值 .
谓词 is null 可用来检查空值 . E.g. 求 loan 关系中 amount 为空值的贷款号 .
select loan-numberfrom loanwhere amount is null
任何涉及空值的算术表达式的结果也为 null E.g. 5 + null 返回 null
合计函数简单地忽略空值 稍候详述
©Silberschatz, Korth and Sudarshan4.23Database System Concepts
空值与三值逻辑空值与三值逻辑 与 null 的比较返回 unknown
E.g. 5 < null or null <> null or null = null
三值逻辑用到真值 unknown: OR: (unknown or true) = true,
(unknown or false) = unknown (unknown or unknown) = unknown
AND: (true and unknown) = unknown,
(false and unknown) = false, (unknown and unknown) = unknown
NOT: (not unknown) = unknown
如果谓词 P 为 unknown, 则 “ P is unknown” 为真 若 where 子句的谓词计算到 unknown 则视为 false
©Silberschatz, Korth and Sudarshan4.24Database System Concepts
空值与合计空值与合计 求贷款总额
select sum (amount)from loan
上述语句忽略空值 如果 loan 关系中没有非空 amount 则结果为 null
除 count(*) 之外的所有合计操作都忽略在合计属性上为空值的元组 .
©Silberschatz, Korth and Sudarshan4.25Database System Concepts
嵌套子查询嵌套子查询 SQL 提供嵌套子查询的机制 .
子查询是嵌在另一个查询内部的 select-from-where 表达式 .
子查询的通常用法是执行集合成员检测 , 集合比较 , 以及集合基数 .
©Silberschatz, Korth and Sudarshan4.26Database System Concepts
查询例查询例 求既有账户又有贷款的客户 .
select distinct customer-namefrom borrowerwhere customer-name in (select customer-name
from depositor)
求有贷款但没有账户的客户select distinct customer-namefrom borrowerwhere customer-name not in (select customer-name
from depositor)
©Silberschatz, Korth and Sudarshan4.27Database System Concepts
查询例查询例 求在 Perryridge 分行既有账户又有贷款的客户
select distinct customer-namefrom borrower, loanwhere borrower.loan-number = loan.loan-number and
branch-name = “Perryridge” and (branch-name, customer-name) in
(select branch-name, customer-namefrom depositor, accountwhere depositor.account-number =
account.account-number)
注意 : 以上查询可以写成更简单的形式 . 这里的写法是为了说明 SQL 特色 .
(Schema used in this example)
©Silberschatz, Korth and Sudarshan4.28Database System Concepts
集合比较集合比较 求比位于 Brooklyn 的某个分行资产多的所有分行 .
select distinct T.branch-namefrom branch as T, branch as Swhere T.assets > S.assets and S.branch-city = ‘Brooklyn’
使用 > some 子句的同一查询select branch-namefrom branchwhere assets > some (select assets from branch where branch-city = ‘Brooklyn’)
©Silberschatz, Korth and Sudarshan4.29Database System Concepts
Some Some 子句的定义子句的定义 F <comp> some r t r s.t. (F <comp> t)
其中 <comp> 可以是 :
056
(5< some ) = true
05
0
) = false
5
05(5 some ) = true (since 0 5)
(read: 5 < some tuple in the relation)
(5< some
) = true(5 = some
(= some) in然而 , ( some) not in
©Silberschatz, Korth and Sudarshan4.30Database System Concepts
all all 子句的定义子句的定义
F <comp> all r t r (F <comp> t)
056
(5< all ) = false
610
4
) = true
5
46(5 all ) = true ( 因为 5 4 and 5 6)
(5< all
) = false(5 = all
( all) not in然而 , (= all) in
©Silberschatz, Korth and Sudarshan4.31Database System Concepts
查询例查询例 求比位于 Brooklyn 的所有分行资产都多的分行名 .
select branch-namefrom branchwhere assets > all
(select assetsfrom branchwhere branch-city = ‘Brooklyn’)
©Silberschatz, Korth and Sudarshan4.32Database System Concepts
测试空关系测试空关系 如果子查询非空 , 则 exists 谓词返回 true.
exists r r Ø
not exists r r = Ø
©Silberschatz, Korth and Sudarshan4.33Database System Concepts
查询例查询例 求在位于 Brooklyn 的所有分行都开了账户的客户 .
select distinct S.customer-namefrom depositor as Swhere not exists (
(select branch-namefrom branchwhere branch-city = ‘Brooklyn’)
except(select R.branch-namefrom depositor as T, account as Rwhere T.account-number = R.account-number and
S.customer-name = T.customer-name))
(Schema used in this example) 注意 : X – Y = Ø X Y 注意 : 这个查询不能用 = all 及其变种
©Silberschatz, Korth and Sudarshan4.34Database System Concepts
测试重复元组测试重复元组
unique 谓词测试子查询的结果中是否有重复元组 .
求在 Perryridge 分行最多只开了一个账户的客户 . select T.customer-name from depositor as T where unique (
select R.customer-name from account, depositor as R where T.customer-name = R.customer-name and
R.account-number = account.account-number and
account.branch-name = ‘Perryridge’)
(Schema used in this example)
©Silberschatz, Korth and Sudarshan4.35Database System Concepts
查询例查询例 求在 Perryridge 分行至少开了两个账户的客户 .
select distinct T.customer-namefrom depositor Twhere not unique (
select R.customer-namefrom account, depositor as Rwhere T.customer-name = R.customer-name and
R.account-number = account.account-number andaccount.branch-name = ‘Perryridge’)
(Schema used in this example)
©Silberschatz, Korth and Sudarshan4.36Database System Concepts
视图视图 提供对某些用户隐藏某些数据的机制 . 创建视图命令 :
create view v as <query expression>
其中 : <query expression> 是任何合法查询表达式 v 是视图名
©Silberschatz, Korth and Sudarshan4.37Database System Concepts
查询例查询例 包含分行及其客户的视图create view all-customer as
(select branch-name, customer-name from depositor, account where depositor.account-number = account.account-number)
union (select branch-name, customer-name from borrower, loan where borrower.loan-number = loan.loan-number)
求 Perryridge 分行的所有客户select customer-namefrom all-customerwhere branch-name = ‘Perryridge’
©Silberschatz, Korth and Sudarshan4.38Database System Concepts
导出关系导出关系 求平均账户余额超过 $1200 的分行名及其平均账户余额 .
select branch-name, avg-balancefrom (select branch-name, avg (balance)
from account group by branch-name)
as result (branch-name, avg-balance)where avg-balance > 1200
注意 : 这里我们不必使用 having 子句 , 因为我们在 from 子句中计算了临时关系 result, result 的属性可直接用于 where 子句 .
©Silberschatz, Korth and Sudarshan4.39Database System Concepts
With With 子句子句 With 子句是我们可以定义局部于查询的视图 , 而非全局视图 求具有最大余额的账户
with max-balance(value) as select max (balance) from account select account-number from account, max-balance where account.balance = max-balance.value
©Silberschatz, Korth and Sudarshan4.40Database System Concepts
使用使用 With With 子句的复杂查询子句的复杂查询 求账户余额总和大于全体分行的平均账户余额总和的分行
with branch-total (branch-name, value) as select branch-name, sum (balance) from account group by branch-namewith branch-total-avg(value) as select avg (value) from branch-totalselect branch-namefrom branch-total, branch-total-avgwhere branch-total.value >= branch-total-avg.value
©Silberschatz, Korth and Sudarshan4.41Database System Concepts
数据库更新数据库更新 – – 删除删除 删除 Perryridge 分行的所有账户记录
delete from accountwhere branch-name = ‘Perryridge’
删除位于 Needham 的每个分行的所有账户 .
delete from accountwhere branch-name in (select branch-name
from branch where branch-city = ‘Needham’)
delete from depositorwhere account-number in (select account-number
from branch, account where branch-city = ‘Needham’ and branch.branch-name = account.branch-
name)
(Schema used in this example)
©Silberschatz, Korth and Sudarshan4.42Database System Concepts
查询例查询例 删除余额低于平均值的账户 .
delete from accountwhere balance < (select avg (balance)
from account) 问题 : 当我们从 account 删除元组时 , 平均余额也发生了变化 SQL 的解决方案 :1. 首先 , 计算平均余额并找出所有应删除元组2. 其次 , 将上述所有元组删除 ( 并不重新计算 avg 或重测试元组 )
©Silberschatz, Korth and Sudarshan4.43Database System Concepts
数据库更新数据库更新 – – 插入插入
向 account 增加一个新元组insert into account
values (‘A-9732’, ‘Perryridge’,1200)或等价地
insert into account (branch-name, balance, account-number)values (‘Perryridge’, 1200, ‘A-9732’)
向 account 增加一个新元组 , 余额置为 null
insert into accountvalues (‘A-777’,‘Perryridge’, null)
©Silberschatz, Korth and Sudarshan4.44Database System Concepts
数据库更新数据库更新 – – 插入插入
向所有 Perryridge 分行的贷款客户提供一个存有 $200 的储蓄账户作为礼物 . 用贷款号作为新储蓄账户的账号 insert into account
select loan-number, branch-name, 200from loanwhere branch-name = ‘Perryridge’
insert into depositorselect customer-name, loan-numberfrom loan, borrowerwhere branch-name = ‘Perryridge’ and
loan.account-number = borrower.account-number
在其结果插入关系之前 , select-from-where 语句应完全求出 . 否则类似下面的查询会导致问题 insert into table1 select * from table1
©Silberschatz, Korth and Sudarshan4.45Database System Concepts
数据库更新数据库更新 – – 修改修改 余额超过 $10,000 的账户增加 6%, 其他账户增加 5%.
用两条 update 语句 :
update accountset balance = balance 1.06where balance > 10000
update accountset balance = balance 1.05where balance 10000
次序很重要 更好的做法是用 case 语句
©Silberschatz, Korth and Sudarshan4.46Database System Concepts
Case Case 语句语句 余额超过 $10,000 的账户增加 6%, 其他账户增加 5%.
update account set balance = case when balance <= 10000 then balance *1.05 else balance * 1.06 end
©Silberschatz, Korth and Sudarshan4.47Database System Concepts
视图的更新视图的更新 创建隐藏了 amount 属性的贷款数据的视图
create view branch-loan asselect branch-name, loan-numberfrom loan
插入新元组insert into branch-loan
values (‘Perryridge’, ‘L-307’)
这个插入可以表示为向 loan 关系插入元组(‘L-307’, ‘Perryridge’, null)
对更复杂的视图作更新往往难以翻译 , 因而通常不允许 .
多数 SQL 实现只允许对定义在单个关系上的简单视图 ( 不含合计 ) 进行更新
©Silberschatz, Korth and Sudarshan4.48Database System Concepts
TransactionsTransactions
A transaction is a sequence of queries and update statements executed as a single unit Transactions are started implicitly and terminated by one of
commit work: makes all updates of the transaction permanent in the database
rollback work: undoes all updates performed by the transaction.
Motivating example Transfer of money from one account to another involves two steps:
deduct from one account and credit to another
If one steps succeeds and the other fails, database is in an inconsistent state
Therefore, either both steps should succeed or neither should
If any step of a transaction fails, all work done by the transaction can be undone by rollback work.
Rollback of incomplete transactions is done automatically, in case of system failures
©Silberschatz, Korth and Sudarshan4.49Database System Concepts
Transactions (Cont.)Transactions (Cont.)
In most database systems, each SQL statement that executes successfully is automatically committed. Each transaction would then consist of only a single statement
Automatic commit can usually be turned off, allowing multi-statement transactions, but how to do so depends on the database system
Another option in SQL:1999: enclose statements within begin atomic … end
©Silberschatz, Korth and Sudarshan4.50Database System Concepts
连接关系连接关系 附加的连接操作常用于 from 子句中作为子查询表达式 连接条件 – 定义两个关系的元组如何匹配 , 以及连接结果中有哪
些属性 .
连接类型 – 定义如何处理没有匹配的元组 .
连接类型inner joinleft outer joinright outer joinfull outer join
连接条件naturalon <predicate>using (A1, A2, ..., An)
©Silberschatz, Korth and Sudarshan4.51Database System Concepts
连接关系连接关系 – – 数据库例数据库例 关系 loan
amount
300040001700
关系 borrower
customer-name loan-number
Jones
Smith
Hayes
L-170
L-230
L-155
branch-name
Downtown
Redwood
Perryridge
loan-number
L-170
L-230
L-260
注意 : L-260 的 borrower 信息丢失 , L-155的 loan 信息丢失
©Silberschatz, Korth and Sudarshan4.52Database System Concepts
连接关系连接关系 – – 例例
loan inner join borrower onloan.loan-number = borrower.loan-number
branch-name amount
Downtown
Redwood
30004000
customer-name loan-number
Jones
Smith
L-170
L-230
branch-name amount
Downtown
Redwood
Perryridge
300040001700
customer-name loan-number
Jones
Smith
null
L-170
L-230
null
loan left inner join borrower onloan.loan-number = borrower.loan-number
loan-number
L-170
L-230
loan-number
L-170
L-230
L-260
©Silberschatz, Korth and Sudarshan4.53Database System Concepts
连接关系连接关系 – – 例例
loan natural inner join borrower
branch-name amount
Downtown
Redwood
30004000
customer-name
Jones
Smith
loan natural right outer join borrower
branch-name amount
Downtown
Redwood
null
30004000null
customer-name
Jones
Smith
Hayes
loan-number
L-170
L-230
loan-number
L-170
L-230
L-155
©Silberschatz, Korth and Sudarshan4.54Database System Concepts
连接关系连接关系 – – 例例 loan full outer join borrower using (loan-number)
branch-name amount
Downtown
Redwood
Perryridge
null
300040001700null
customer-name
Jones
Smith
null
Hayes
求开有账户或有贷款 ( 不能都有 ) 的客户 .select customer-namefrom (depositor natural full outer join borrower)where account-number is null or loan-number is null
loan-number
L-170
L-230
L-260
L-155
©Silberschatz, Korth and Sudarshan4.55Database System Concepts
数据定义语言数据定义语言 (DDL)(DDL)
关系模式 属性域 完整性约束 关系的索引 关系的安全性和授权信息 关系在磁盘上的物理存储结构
不仅可以声明关系 , 还可以声明关系的其他信息 , 包括 :
©Silberschatz, Korth and Sudarshan4.56Database System Concepts
SQLSQL 中的域类型中的域类型 char(n). 定长字符串 , 用户指定长度 n.
varchar(n). 变长字符串 , 用户指定最大长度 n.
int. 整数 ( 依赖于机器的有限整数集合 ).
smallint. 小整数 ( 依赖于机器的有限整数集合 ).
numeric(p,d). 定点数 , 用户指定精度为 p 位 , 小数点右边有 n 位 .
real, double precision. 浮点数和双精度浮点数 , 精度依赖于机器 .
float(n). 浮点数 , 用户指定精度为至少 n 位 .
域类型中允许空值 . 声明一个属性为 not null 将禁止该属性取空值 .
SQL-92 中的 create domain 语句可创建用户定义的域类型create domain person-name char(20) not null
©Silberschatz, Korth and Sudarshan4.57Database System Concepts
SQL SQL 中的中的 Date/Time Date/Time 类型类型 date. 日期 , 包含年 (4 位 ) , 月 , 日
E.g. date ‘2001-7-27’
time. 一天中的时间 , 包含小时 , 分钟 , 秒 E.g. time ’09:00:30’ time ’09:00:30.75’
timestamp: 日期加时间 E.g. timestamp ‘2001-7-27 09:00:30.75’
Interval: 时间段 E.g. Interval ‘1’ day
从一个 date/time/timestamp 值减去另一个可得 interval 值 Interval 值可以加到 date/time/timestamp 值上
可从 date/time/timestamp 抽取部分值 E.g. extract (year from r.starttime)
可将字符串转换成 date/time/timestamp E.g. cast <string-valued-expression> as date
©Silberschatz, Korth and Sudarshan4.58Database System Concepts
Create Table Create Table 语句语句
SQL 关系用 create table 命令定义 :
create table r (A1 D1, A2 D2, ..., An Dn,(integrity-constraint1),...,(integrity-constraintk))
r 是关系名 Ai 是属性名 Di 是属性 Ai 的域值的数据类型 例如 :
create table branch(branch-name char(15) not null,branch-city char(30),assets integer)
©Silberschatz, Korth and Sudarshan4.59Database System Concepts
Create TableCreate Table 中的完整性约束中的完整性约束 not null
primary key (A1, ..., An)
check (P), P 是谓词
例如 : 声明 branch-name 作为 branch 的主键并确保 assets 的值非负
create table branch(branch-namechar(15),branch-city char(30)assets integer,primary key (branch-name),check (assets >= 0))
primary key declaration on an attribute automatically ensures not null in SQL-92 onwards, needs to be explicitly stated in SQL-89
©Silberschatz, Korth and Sudarshan4.60Database System Concepts
Drop Table Drop Table 与 与 Alter TableAlter Table
drop table 命令从数据库删除关系的所有信息 .
alter table 命令可用于向已有关系增加属性 . 关系的所有元组在新属性上的值为 null. 命令形如
alter table r add A D
其中 A 是新增属性名 , D 是 A 的域 . alter table 命令还可用于删除关系的属性
alter table r drop A其中 A 是关系 r 的属性名 许多数据库系统不支持删除属性
©Silberschatz, Korth and Sudarshan4.61Database System Concepts
Embedded SQLEmbedded SQL
SQL 标准定义了将 SQL 嵌入到程序设计语言 (如 Pascal, PL/I, Fortran, C, and Cobol ) 的内容 .
SQL 查询所嵌入的语言称为宿主语言 , 而在宿主语言中可用的 SQL 结构即组成了 embedded SQL.
基本形式基于 System R的 SQL到 PL/I 的嵌入 . EXEC SQL 语句用于向预处理器标识 embedded SQL 请求
EXEC SQL <embedded SQL 语句 > END-EXEC
注意 : 依语言而变 . E.g. Java 嵌入使用 # SQL { …. } ;
©Silberschatz, Korth and Sudarshan4.62Database System Concepts
查询例查询例
用 SQL 写查询并为它声明一个游标EXEC SQL
declare c cursor for select customer-name, customer-cityfrom depositor, customer, accountwhere depositor.customer-name = customer.customer-name and depositor account-number = account.account-number
and account.balance > :amount
END-EXEC
从宿主语言内查询在某账户中余额大于给定变量 amount 的客户的姓名和城市 .
©Silberschatz, Korth and Sudarshan4.63Database System Concepts
Embedded SQL (Embedded SQL (续续 ))
open 语句导致查询被执行EXEC SQL open c END-EXEC
fetch 语句可使查询结果中的一条元组的值放入宿主语言变量 .
EXEC SQL fetch c into :cn, :cc END-EXEC循环调用 fetch 可逐条取得查询结果中的元组
SQL 通信区 (SQLCA) 中的变量 SQLSTATE 设置成 ‘ 02000’ 以指示不再有数据了
close 语句使数据库系统删除保存查询结果的临时关系 .
EXEC SQL close c END-EXEC
注意 : 上述细节随语言而变 . E.g. Java 嵌入定义了 Java iterators 来遍历结果中的元组 .
©Silberschatz, Korth and Sudarshan4.64Database System Concepts
通过游标更新通过游标更新
通过声明游标是 for update 即可更新通过游标取得的元组 declare c cursor for
select * from account where branch-name = ‘Perryridge’ for update
修改游标当前位置上的元组 update account
set balance = balance + 100 where current of c
©Silberschatz, Korth and Sudarshan4.65Database System Concepts
动态动态 SQLSQL
允许程序在运行时刻构造并提交 SQL 查询 .
例如char * sqlprog = “update account set balance = balance * 1.05
where account-number = ?”EXEC SQL prepare dynprog from :sqlprog;char account [10] = “A-101”;EXEC SQL execute dynprog using :account;
动态 SQL 程序包含一个 ?, 这是一个占位符 , 当 SQL 程序执行时提供相应的值 .
©Silberschatz, Korth and Sudarshan4.66Database System Concepts
ODBCODBC
Open DataBase Connectivity(ODBC) standard standard for application program to communicate with a database
server.
application program interface (API) to
open a connection with a database,
send queries and updates,
get back results.
Applications such as GUI, spreadsheets, etc. can use ODBC
©Silberschatz, Korth and Sudarshan4.67Database System Concepts
ODBC (Cont.)ODBC (Cont.)
Each database system supporting ODBC provides a "driver" library that must be linked with the client program.
When client program makes an ODBC API call, the code in the library communicates with the server to carry out the requested action, and fetch results.
ODBC program first allocates an SQL environment, then a database connection handle.
Opens database connection using SQLConnect(). Parameters for SQLConnect: connection handle,
the server to which to connect
the user identifier,
password
Must also specify types of arguments: SQL_NTS denotes previous argument is a null-terminated string.
©Silberschatz, Korth and Sudarshan4.68Database System Concepts
ODBC CodeODBC Code
int ODBCexample()
{
RETCODE error;
HENV env; /* environment */
HDBC conn; /* database connection */
SQLAllocEnv(&env);
SQLAllocConnect(env, &conn);
SQLConnect(conn, "aura.bell-labs.com", SQL_NTS, "avi", SQL_NTS, "avipasswd", SQL_NTS);
{ …. Do actual work … }
SQLDisconnect(conn);
SQLFreeConnect(conn);
SQLFreeEnv(env);
}
©Silberschatz, Korth and Sudarshan4.69Database System Concepts
ODBC Code (Cont.)ODBC Code (Cont.)
Program sends SQL commands to the database by using SQLExecDirect Result tuples are fetched using SQLFetch() SQLBindCol() binds C language variables to attributes of the query result
When a tuple is fetched, its attribute values are automatically stored in corresponding C variables.
Arguments to SQLBindCol()
– ODBC stmt variable, attribute position in query result
– The type conversion from SQL to C.
– The address of the variable.
– For variable-length types like character arrays,
» The maximum length of the variable
» Location to store actual length when a tuple is fetched.
» Note: A negative value returned for the length field indicates null value
Good programming requires checking results of every function call for errors; we have omitted most checks for brevity.
©Silberschatz, Korth and Sudarshan4.70Database System Concepts
ODBC Code (Cont.)ODBC Code (Cont.) Main body of program
char branchname[80];float balance;int lenOut1, lenOut2;HSTMT stmt;
SQLAllocStmt(conn, &stmt);char * sqlquery = "select branch_name, sum (balance) from account group by branch_name";
error = SQLExecDirect(stmt, sqlquery, SQL_NTS);
if (error == SQL_SUCCESS) { SQLBindCol(stmt, 1, SQL_C_CHAR, branchname , 80, &lenOut1); SQLBindCol(stmt, 2, SQL_C_FLOAT, &balance, 0 , &lenOut2);
while (SQLFetch(stmt) >= SQL_SUCCESS) { printf (" %s %g\n", branchname, balance); }}SQLFreeStmt(stmt, SQL_DROP);
©Silberschatz, Korth and Sudarshan4.71Database System Concepts
More ODBC FeaturesMore ODBC Features
Prepared Statement SQL statement prepared: compiled at the database
Can have placeholders: E.g. insert into account values(?,?,?)
Repeatedly executed with actual values for the placeholders
Metadata features finding all the relations in the database and
finding the names and types of columns of a query result or a relation in the database.
By default, each SQL statement is treated as a separate transaction that is committed automatically. Can turn off automatic commit on a connection
SQLSetConnectOption(conn, SQL_AUTOCOMMIT, 0)}
transactions must then be committed or rolled back explicitly by
SQLTransact(conn, SQL_COMMIT) or
SQLTransact(conn, SQL_ROLLBACK)
©Silberschatz, Korth and Sudarshan4.72Database System Concepts
ODBC Conformance LevelsODBC Conformance Levels
Conformance levels specify subsets of the functionality defined by the standard. Core
Level 1 requires support for metadata querying
Level 2 requires ability to send and retrieve arrays of parameter values and more detailed catalog information.
SQL Call Level Interface (CLI) standard similar to ODBC interface, but with some minor differences.
©Silberschatz, Korth and Sudarshan4.73Database System Concepts
JDBCJDBC
JDBC is a Java API for communicating with database systems supporting SQL
JDBC supports a variety of features for querying and updating data, and for retrieving query results
JDBC also supports metadata retrieval, such as querying about relations present in the database and the names and types of relation attributes
Model for communicating with the database: Open a connection
Create a “statement” object
Execute queries using the Statement object to send queries and fetch results
Exception mechanism to handle errors
©Silberschatz, Korth and Sudarshan4.74Database System Concepts
JDBC CodeJDBC Codepublic static void JDBCexample(String dbid, String userid, String passwd)
{ try {
Class.forName ("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@aura.bell-labs.com:2000:bankdb", userid, passwd);
Statement stmt = conn.createStatement();
… Do Actual Work ….
stmt.close();
conn.close();
}
catch (SQLException sqle) {
System.out.println("SQLException : " + sqle);
}
}
©Silberschatz, Korth and Sudarshan4.75Database System Concepts
JDBC Code (Cont.)JDBC Code (Cont.)
Update to databasetry {
stmt.executeUpdate( "insert into account values ('A-9732', 'Perryridge', 1200)");
} catch (SQLException sqle) {
System.out.println("Could not insert tuple. " + sqle);
}
Execute query and fetch and print results ResultSet rset = stmt.executeQuery( "select branch_name, avg(balance)
from account group by branch_name");
while (rset.next()) {
System.out.println( rset.getString("branch_name") + " " + rset.getFloat(2));
}
©Silberschatz, Korth and Sudarshan4.76Database System Concepts
JDBC Code Details JDBC Code Details
Getting result fields: rs.getString(“branchname”) and rs.getString(1) equivalent if
branchname is the first argument of select result.
Dealing with Null values
int a = rs.getInt(“a”);
if (rs.wasNull()) Systems.out.println(“Got null value”);
©Silberschatz, Korth and Sudarshan4.77Database System Concepts
Prepared StatementPrepared Statement
Prepared statement allows queries to be compiled and executed multiple times with different arguments
PreparedStatement pStmt = conn.prepareStatement(
“insert into account values(?,?,?)”); pStmt.setString(1, "A-9732");
pStmt.setString(2, "Perryridge");
pStmt.setInt(3, 1200);
pStmt.executeUpdate();
pStmt.setString(1, "A-9733");
pStmt.executeUpdate();
NOTE: If value to be stored in database contains a single quote or other special character, prepared statements work fine, but creating a string and executing it directly would result in a syntax error!
©Silberschatz, Korth and Sudarshan4.78Database System Concepts
其他其他 SQL SQL 特色特色 SQL 会话
客户端 连接到 SQL 服务器 , 建立一次会话 执行一系列语句 断开连接和会话 可 commit 或 rollback 会话内的工作
SQL 环境包含若干部分 , 如用户标识 , 指明会话正在使用那些模式的 schema.
©Silberschatz, Korth and Sudarshan4.79Database System Concepts
Schemas, Catalogs, and EnvironmentsSchemas, Catalogs, and Environments
Three-level hierarchy for naming relations. Database contains multiple catalogs
each catalog can contain multiple schemas
SQL objects such as relations and views are contained within a schema
e.g. catalog5.bank-schema.account
Each user has a default catalog and schema, and the combination is unique to the user.
Default catalog and schema are set up for a connection
Catalog and schema can be omitted, defaults are assumed
Multiple versions of an application (e.g. production and test) can run under separate schemas
©Silberschatz, Korth and Sudarshan4.80Database System Concepts
Procedural Extensions and Stored Procedural Extensions and Stored ProceduresProcedures
SQL provides a module language permits definition of procedures in SQL, with if-then-else statements,
for and while loops, etc.
more in Chapter 9
Stored Procedures Can store procedures in the database
then execute them using the call statement
permit external applications to operate on the database without knowing about internal details
These features are covered in Chapter 9 (Object Relational Databases)
Extra Material on JDBC and Extra Material on JDBC and Application ArchitecturesApplication Architectures
©Silberschatz, Korth and Sudarshan4.82Database System Concepts
Transactions in JDBCTransactions in JDBC
As with ODBC, each statement gets committed automatically in JDBC
To turn off auto commit use conn.setAutoCommit(false);
To commit or abort transactions use conn.commit() or conn.rollback()
To turn auto commit on again, use conn.setAutoCommit(false);
©Silberschatz, Korth and Sudarshan4.83Database System Concepts
Procedure and Function Calls in JDBCProcedure and Function Calls in JDBC
JDBC provides a class CallableStatement which allows SQL stored procedures/functions to be invoked.
CallableStatement cs1 = conn.prepareCall( “{call proc (?,?)}” ) ;
CallableStatement cs2 = conn.prepareCall( “{? = call func (?,?)}” );
©Silberschatz, Korth and Sudarshan4.84Database System Concepts
Result Set MetaDataResult Set MetaData
The class ResultSetMetaData provides information about all the columns of the ResultSet.
Instance of this class is obtained by getMetaData( ) function of ResultSet.
Provides Functions for getting number of columns, column name, type, precision, scale, table from which the column is derived etc.
ResultSetMetaData rsmd = rs.getMetaData ( );
for ( int i = 1; i <= rsmd.getColumnCount( ); i++ ) {
String name = rsmd.getColumnName(i);
String typeName = rsmd.getColumnTypeName(i); }
©Silberschatz, Korth and Sudarshan4.85Database System Concepts
Database Meta DataDatabase Meta Data
The class DatabaseMetaData provides information about database relations
Has functions for getting all tables, all columns of the table, primary keys etc.
E.g. to print column names and types of a relation
DatabaseMetaData dbmd = conn.getMetaData( );
ResultSet rs = dbmd.getColumns( null, “BANK-DB”, “account”, “%” ); //Arguments: catalog, schema-pattern, table-pattern, column-pattern // Returns: 1 row for each column, with several attributes such as // COLUMN_NAME, TYPE_NAME, etc.
while ( rs.next( ) ) { System.out.println( rs.getString(“COLUMN_NAME”) ,
rs.getString(“TYPE_NAME”); }
There are also functions for getting information such as Foreign key references in the schema
Database limits like maximum row size, maximum no. of connections, etc
©Silberschatz, Korth and Sudarshan4.86Database System Concepts
Application ArchitecturesApplication Architectures
Applications can be built using one of two architectures Two tier model
Application program running at user site directly uses JDBC/ODBC to communicate with the database
Three tier model
Users/programs running at user sites communicate with an application server. The application server in turn communicates with the database
©Silberschatz, Korth and Sudarshan4.87Database System Concepts
Two-tier ModelTwo-tier Model
E.g. Java code runs at client site and uses JDBC to communicate with the backend server
Benefits: flexible, need not be restricted to predefined queries
Problems: Security: passwords available at client site, all database operation
possible
More code shipped to client
Not appropriate across organizations, or in large ones like universities
©Silberschatz, Korth and Sudarshan4.88Database System Concepts
Three Tier ModelThree Tier Model
CGI Program
DatabaseServer
Application/HTTPServer
ServletsJDBC
Network
Client Client Client
HTTP/Application Specific Protocol
©Silberschatz, Korth and Sudarshan4.89Database System Concepts
Three-tier Model (Cont.)Three-tier Model (Cont.)
E.g. Web client + Java Servlet using JDBC to talk with database server
Client sends request over http or application-specific protocol
Application or Web server receives request
Request handled by CGI program or servlets
Security handled by application at server Better security
Fine granularity security
Simple client, but only packaged transactions