SQL必知必会(五) 使用视图、使用储存过程、管理事务处理、使用游标、高级SQL特性
2016-06-11 20:32
597 查看
十八、使用视图
视图
SELECT prod_name, vend_name, prod_name, prod_price, quantity FROM OrderItems, Vendors, Products WHERE Vendors.vend_id = Products.vend_id AND OrderItems.prod_id = Products.prod_id AND order_num = 20007;
将上面查询包装成一个名为ProductCustomers的虚拟表,则可以很轻松地检索出相同的数据
SELECT prod_name, vend_name, prod_name, prod_price, quantity FROM ProductCustomers WHERE order_num = 20007;
为什么使用视图
简化复杂的SQL操作使用表的一部分而不是整张表
保护数据
更改数据格式和表示。(可返回与底层表格式不同的数据)
创建视图
CREATE VIEW ProductCustomers AS SELECT prod_name, vend_name, prod_name, prod_price, quantity FROM OrderItems, Vendors, Products WHERE Vendors.vend_id = Products.vend_id AND OrderItems.prod_id = Products.prod_id
使用视图重新格式化检索出的数据
SELECT RTRIM(vend_name) + '(' + RTRIM(vend_country) + ')' FROM Vendors ORDER BY vend_name;
如果经常需要上面这个格式的结果,可转换成视图
CREATE VIEW VendorLocations AS SELECT RTRIM(vend_name) + '(' + RTRIM(vend_country) + ')' FROM Vendors
用视图过滤不想要的数据
CREATE VIEW CustomerEMailList AS SELECT cust_id,cust_name,cust_email FROM Customers WHERE cust_email IS NOT NULL SELECT * FROM CustomerEMailList
使用视图与计算字段
CREATE VIEW OrderItemsExpanded AS SELECT order_num, prod_id, quantity, item_price, quantity * item_price AS expanded_price FROM OrderItems; SELECT * FROM OrderItems WHERE order_num = 20008;
十九、使用储存过程
储存过程就是为以后使用而保存的一条或多条AQL语句,功能类似为批文件。执行储存过程
EXECUTE AddNewProduct( 'JTS01', 'Stuffed Eiffel Tower' 6.49 'This is a description');
这里执行一个名为AddNewProduct的储存过程,将一个新产品添加到Product表中。
创建储存过程
CREATE PROCEDURE MailingListCount AS DECLARE @cnt INTEGER --@cnt局部变量 SELECT @cnt = COUNT(*) FROM Customers WHERE NOT cust_email IS NULL; RETURN @cnt; --调用 DECLARE @ReturnValue INT EXECUTE @ReturnValue = MailingListCount SELECT @ReturnValue;
CREATE PROCEDURE NewOrder @cust_id CHAR(10) DECLARE @order_num INTEGER SELECT @order_num = MAX(order_num) FROM Orders SELECT @order_num = @order_num + 1 INSERT INTO Orders(order_num,order_date,cust_id) VALUES(@order_num,GETDATE(),@cust_id) RETURN @order_num;
改储存过程在Orders表中创建了一个新订单,它只有一个参数cust_id。
首先声明一个局部变量order_num储存订单号,接着检索最大订单号并加1,然后将新订单号、当前系统时间、顾客ID插入到加1那行。最后返回订单号。
二十、管理事务处理
使用事务处理,确保成批的SQL操作要么完全执行,要么不执行,来维护数据库的完整性。事务
回退
提交
保留点
控制事务处理
-- SQL Server版本 BEGIN TRANSACTION ... COMMIT TRANSACTION -- MySQL 版本 START TRANSACTION --Oracle版本 SET TRANSACTION
使用ROLLBACK 回退
DELETE FROM Orders; ROLLBACK;
使用 COMMIT
BEGIN TRANSACTION DELETE OrderIetms WHERE order_num = 12345; DELETE Orders WHERE order_num = 12345; COMMIT TRANSACTION
使用保留点
-- oracle、MySQL版本 SAVEPOINT delete1; ROLLBACK TO delete1; -- SQL SERVER版本 SAVE TRANSACTION delete1; ROLLBACK TRANSACTION delete1;
二十一、使用游标
有时,需要在检索出来的行中前进或后退一行或多行,这就是游标的作用使用游标
-- MySQL、SQL Server版本 DECLARE CustCursor CURSOR FOR SELECT * FROM Customers WHERE cust_email IS NULL --oracle版本 DECLARE CURSOR CustCursor IS SELECT * FROM Customers WHERE cust_email IS NULL
OPEN CURSOR CustCursor
使用OPEN CURSOR打开游标,FETCH访问游标数据
DECLARE TYPE CustCursors IS REF CURSOR RETURN Customers%ROWTPYE DECLARE CustRecord Customer%ROWTYPE BEGIN OPEN CustRecord; LOOP FETCH CustCursor INTO CustRecord; EXIT WHEN CustCursor%NOTFOUND; --在取不出更多行时退出 ... END LOOP; CLOSE CustCursor; END;
二十二、高级SQL特性
约束
主键
CREATE TABLE Vendors ( vend_id char(10) NOT NULL PRIMARY KEY , vend_name char(50) NOT NULL , vend_address char(50) NULL , vend_city char(50) NULL , vend_state char(5) NULL , vend_zip char(10) NULL , vend_country char(50) NULL ); -- 也可在表创建后更新 ALTER TABLE Vendors ADD PRIMARY KEY (vend_id);
外键
外键是表中的一列,其值必须列在另一个表的主键中。CREATE TABLE Orders ( order_num int NOT NULL PRIMARY KEY, order_date datetime NOT NULL , cust_id char(10) NOT NULL REFERENCES Customers(cust_id) ); -- 也可在表创建后更新 ALTER TABLE Orders ADD CONSTRAINT FOREIGN KEY (cust_id) REFERENCES Customers (cust_id);
唯一约束
用来保证一列中数据是唯一的,如社会号。 但可以修改和更新检查约束
检查最大最小值指定范围
只允许特定的值
CREATE TABLE OrderItems ( order_num int NOT NULL , order_item int NOT NULL , prod_id char(10) NOT NULL , quantity int NOT NULL CHECK (quantity > 0), item_price decimal(8,2) NOT NULL ); ADD CONSTRAINT CHECK (gender LIKE '[MF]')
索引
索引用来排序数据以加快搜索和排序操作的速度可以在一列或者多个列定义索引
索引改善了搜索的性能,但降低了数据插入修改和删除的性能,因为在执行这些操作时要动态更新索引
CREATE INDEX prod_name_id ON Products (prod_name)
索引必须唯一命名
触发器
触发器是特殊的储存过程,可以与INSERT、UPDATE、DELETE相关联触发器常见用途
保证数据一致 。 例如将州名大写
基于某个表的变动在其他表上执行活动。 例如每当更改时写入日志表
进行额外的验证并根据需要回退数据
计算计算列的值或更新时间戳
-- SQL Server版本 CREATE TRIGGER customer_state ON Customers FOR INSERT , UPDATE AS UPDATE Customers SET cust_state = Upper(cust_state) WHERE Customers.cust_id = inserted.cust_id; --oracle版本 CREATE TRIGGER customer_state ON Customers AFTER INSERT OR UPDATE FOR EACH NOW BEGIN UPDATE Customers SET cust_state = Upper(cust_state) WHERE Customers.cust_id = :OLD.cust_id; END;
约束比触发器更快,在可能的时候,尽量使用约束
数据库安全
GRANTREVOKE
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 数据库链接字符串查询网站
- DB2实例管理
- DB2实例管理
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- 第三章 数据库备份和还原
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- CentOS下DB2数据库安装过程详解
- EasyASP v1.5发布(包含数据库操作类,原clsDbCtrl.asp)第1/2页
- sql2008 还原数据库解决方案
- Oracle 数据库自动存储管理-安装配置
- Oracle数据库执行脚本常用命令小结
- Oracle 数据库 临时数据的处理方法
- 数据库分页查询语句数据库查询
- 最近比较流行的数据库挂马