SQL必知必会(第三部分 18-22课)

第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(传递值给储存过程也从储存过程传回值)类型的参数。

储存过程的代码括在BEGINEND语句中。

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.数据库安全

GRANTREVOKE语句

发布了20 篇原创文章 · 获赞 6 · 访问量 4645

猜你喜欢

转载自blog.csdn.net/better_eleven/article/details/90481373