第18课.使用视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
创建视图后,可以用与表基本相同的方式使用他们。
视图仅仅是用来查看储存在别处的数据的一种设施,其返回的数据是从其他表中检索出来的,添加或更改这些这些表中的数据时,视图将返回改变过的数据。
视图必须唯一命名。
18.1.创建视图
视图用CREATE VIEW语句来创建。
CREATE VIEW viewname AS <SELECT语句>
--删除视图,用DROP语句
DROP VIEW [IF EXISTS] viewname;
SELECT 字段1,字段2,..., FROM viewname;
18.2.1.隐藏复杂的SQL
--创建一个名为ProductCustomers的视图
CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
--此处比使用子查询多了prod_id,在后面使用视图时使用
FROM Customeres, Orders, OrderItems
WHERE Customers.cust_id= Ordes.cust_id
AND OrderItems.order_num=Orders.order_num;
--订购了任意产品的顾客
SELECT *
FROM ProductCustomers
--检索订购了RGAN01的顾客
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id='RGAN01';
利用视图,可一次性编写基础的SQL,然后根据需要多次使用。
18.2.2.重新格式化检索出的数据
CREATE VIEW VendorLocation AS
SELECT RTRIM(vend_name)+ ' ('+ RTRIM(vend_country)+')'
AS vend_title
FROM Vendors;
--检索数据,创建所有的邮件标签
SELECT *
FROM VendorLocation;
18.2.3.过滤不想要的数据
--过滤没有电子邮件地址的顾客
CREATE VIEW CustomerEMaiList AS
SELECT cust_id, cust_name, cust_email
FROM Customers
WHERE cust_email IS NOT NULL;
SELECT *
FROM CustomerEMailList;
18.2.4. 简化字段
CREATE VIEW OrderItemsExpanded AS
SELECT order_num,
prod_id,
quantity,
item_price,
quantity * item_price AS expanded_price
FROM OrderItems;
SELECT *
FROM OrderItemsExpanded
WHERE order_num =20008;
第19课.使用储存过程
储存过程:为以后使用而保存的一条或多条SQL语句。
储存过程通常以编译过的形式储存。
好处:简单、安全、高性能。
19.1.执行
EXECUTE语句来执行储存过程,EXECUTE接受储存过程名和需要传递给它的任何参数。
--执行名为AddNewProduct的储存过程
--将新行添加到Products表,并将传入的属性赋给相应的列。
EXECUTE AddNewProduct ('JTS01', 'Stuffed Eiffel Tower',
6.49, 'Plush stuffed toy with the text La Tour Eiffel in red white and blue');
最好自动生成作为主键的值。
19.2.创建
--Oracle 对邮件发送清单中具有邮件地址的顾客进行计数
CREATE PROCEDURE MailingListCount(
ListCount OUT INTEGER --名为ListCount的参数,从储存过程返回一个值
)
IS
v_rows INTEGER;
BEGIN
--检索具有邮件地址的顾客,用检索**加粗样式**出的行数设置ListCount要传递出的参数。
SELECT COUNT(*) INTO v_rows
FROM Customers
WHERE NOT cust_email IS NULL;
ListCount :=v_rows;
END;
Oracle支持IN(传递至给储存过程),OUT(从储存过程返回值),INOUT(传递值给储存过程也从储存过程传回值)类型的参数。
储存过程的代码括在BEGIN和END语句中。
var ReturnValue NUMBER --声明变量来保存储存过程返回的任何值
EXEC MailingListCount (:ReturnValue);
SELECT ReturnValue;
SQL Server版本
--对邮件发送清单中具有邮件地址的顾客进行计数
CREATE PROCEDURE MailingListCount
AS
DECLARE @cnt INTEGER --声明名为@cnt的局部变量
SELECT @cnt=COUNT(*)
FROM Customers
WHERE NOT cust_email IS NULL;
RETURN @cnt;
--调用SQL Server例子
DECLARE @ReturnValue INT
EXECUTE @ReturnValue= MailingListCount;
SELECT @ReturnValue;
SQL Server 在Orders表中插入一个新订单
CREATE PROCEDURE NewOrder @cust_id CHAR(10)
AS
--Declare variable for order number
DECLARE @order_num INTEGER
--Get Current highest order number
SELECT @order_num =MAX(order_num)
FROM Orders
--Determine next order number
SELECT @order_num=@order_num+1
--Insert new order
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES (@order_num, GETDATE(), @cust_id) --订单号和订单日期自动生成
--Return order number
RETURN @order_num;
SQL Server
还需要理解????????page174
CREATE PROCEDURE NewOrder @cust_id CHAR(10)
AS
--Insert new order
INSERT INTO Orders(cust_id)
VALUES(@cust_id)
--Return order number
SELECT order_num= @@IDENTITY;--全局变量@@IDENTITY
标识字段/自动编号/序列:自动增量的列
第20课.管理事务处理
事务处理是一种机制,通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。(个人觉得类似C++中异常处理)
- 事务:一组SQL语句
- 回退(rollback):撤销指定SQL语句的过程
- 提交(commit):将未储存的SQL语句结果写入数据表
- 保留点:事务处理中设置的临时占位符,可以对它发布回退(与回退整个事务处理不同)。
事务处理用来管理INSERT、UPDATE和DELETE语句,不能回退SELECT语句,也不能回退CREATE或DROP操作。
管理事务的关键在于将SQL语句分解为逻辑块,并明确规定数据何时应该回退,合适不应该回退。
--MySQL 下面的语句完全执行或完全不执行
START TRANSACTION
...
通常,COMMIT用于保存更改,ROLLBACK用于撤销。
DELETE FROM Orders
ROLLBACK;
--SQL Server 从系统中完全删除订单12345
BEGIN TRANSACTION
DELETE OrderItems WHERE order_num =12345
DELETE Orders WHERE order_num =12345
COMMIT TRANSACTION
保留点
支持回退部分事务,必须在事务处理块中的合适位置放置占位符。如果回退,可以回退到某个占位符(也称保留点)。
--MySQL 创建占位符
SAVEPOINT delete1;
每个保留点都要取能够标识它的唯一名字。
--MySQL
ROLLBACK TO delete1;
完整SQL Server例子
BEGIN TRANSACTION
INSERT INTO Customers (cust_id, cust_name)
VALUES ('1000000010', 'Toys Emporium');
--保留点,任何一个INSERT操作失败事务处理能回退到这里
SAVE TRANSACTION StartOrder;
INSERT INTO Orders (order_num, order_date, cust_id)
VALUES (20100, '2001/12/1', '10000000010');
-- SQL Server 检查名为@@ERROR的变量,看操作是否成功。
--如果@@ERROR反回一个非0值,表示有错误发生,事务处理回退到保留点。
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
INSERT INTO OrderItems (order_num, order_item, prod_id,
quantity, item_price)
VALUES (20100, 1, 'BR01', 100, 5.49);
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
INSERT INTO OrderItems (order_num, order_item, prod_id,
quantity, item_price)
VALUES (20100, 2, 'BR03', 100, 10.99);
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
--整个事务处理成功,发布COMMIT 以保留数据。
COMMIT TRANSACTION
第21课.使用游标
游标是一个储存在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。
在储存了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。
DECLARE --> OPEN --> FETCH–> CLOSE
--创建游标来检索没有电子邮件地址的所有顾客
DECLARE CustCursor CURSOR --创建游标
FOR
SELECT * FROM Customers
WHERE cust_email IS NULL
--打开游标
OPEN CURSOR CustCursor
--处理OPEN CURSOR语句时,执行查询,储存检索出的数据以供浏览和滚动
--FETCH语句访问游标数据,Oracle 从游标中检索第一行
DECLARE TYPE CustCursor IS REF CURSOR
RETURN Customers%ROWTYPE;
DECLARE CustRecord Customers % ROWTYPE
BEGIN
OPEN CustCursor
--FETCH检索当前行(自动从第一行开始),放到声明的变量CustRecord中。
--对检索出来的数据不做任何处理。
FETCH CustCursor INTO CustRecord;
CLOSE CustCursor;
END;
--Oracle 从第一行到最后一行,对检索出来的数据进行循环
DECLARE TYPE CustCursor IS REF CURSOR
RETURN Customers%ROWTYPE;
DECLARE CustRecord Customers % ROWTYPE
BEGIN
OPEN CustCursor
LOOP
--FETCH 位于LOOP内,因此它反复执行
FETCH CustCursor INTO CustRecord;
--在取不出更多的行时终止处理(退出循环)
EXIT WHEN CustCursor % NOTFOUND;
...
END LOOP;
CLOSE CustCursor;
END;
--SQL Server
--为检索出来的列声明一个变量
DECLARE @cust_id CHAR(50),
@cust-name CHAR(50),
@cust_city CHAR(50)
OPEN CustCursor
--FETCH语句检索每一行并保存到这些变量中
FETCH NEXT FROM CustCursor
INTO @cust_id, @cust-name, @cust_city
--WHILE循环处理每一行,在取不出更多的行时终止处理
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM CustCursor
INTO @cust_id, @cust-name, @cust_city
...
END
CLOSE CustCursor
游标使用完毕时需要关闭,有的DBMS要求明确释放游标所占用的资源。
CLOSE CustCursor
一旦关闭,如果不再次带卡,将不能使用。第二次使用不需要再声明,只需用OPEN打开。(类似于临时变量 或者 new之后释放资源,但指针还在)
第22课.高级SQL特性
22.1.约束
管理如何插入或处理数据库数据的规则。
DBMS通过在数据库表上施加约束来实施引用完整性。大多数约束是在表定义中定义的。
包含主键值的列从不修改或更新。
主键值不能重用。
关键字 PRIMARY KEY
CONSTRAINT语法
22.2.外键
是表中的一列,其值必须列在另一表的主键中。
关键字REFERENCES
CREATE TABLE Orders
(
order_num INTEGER NOT NULL PRIMARY KEY,--order_num为主键
order_date DATETIME NOT NULL,
--cust_id中的任何值都必须是Customers表的cust_id中的值
cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id)
);
ALTER TABLE Orders
ADD CONSTRAINT
FOREIGN KEY (cust_id) REFERENCES Customers (cust_id)
DBMS不允许删除在另一个表中具有关联行的行。
级联删除,即在一个表中删除行时删除所有相关的数据。
唯一约束:保证一列(或一组列)中的数据是唯一的。
UNIQUE关键字或者用单独的CONSTRAINT定义。
检查约束用来保证一列(或一组列)中的数据满足一组制定的条件。
CHECK关键字。
用户自定义数据类型。
22.3.索引
定义:创建在数据库表对象上,由表中的一个字段或多个字段生成的键组成。这些建储存在数据结构B-树或哈希表中。
作用:用来排序数据以加快搜索和排序操作的速度。
主键数据总是排序的,因此按主键检索特定行时快速有效的操作。
可以在一列或者多列上定义索引。
索引用CREATE INDEX语句创建,索引必须唯一命名。
--在Products表的产品列上创建一个简单的索引
CREATE INDEX prod_name_ind
--ON 表 (列名)
ON Products (prod_name);
DROP INDEX table_name.index_name;
SHOW INDEX FROM table_name;
22.4.触发器
特殊的储存过程,与单个表相关联,可在特定操作执行之前或之后执行。
CREATE TRIGGER
22.5.数据库安全
GRANT和REVOKE语句