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

    xiaoxiao2022-07-12  136

    第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语句

    最新回复(0)