------------------------插入数据-----------------------
-- 80.1. 插入完整的行
-- 各个列必须以他们在表定义中出现的次序填充
INSERT INTO customers
VALUES ('Pep E. LaPew','100 Main Street','LOS Angeles','CA','90046','USA',NULL,NULL)

-- INSERT 语句的安全操作方法,指定列, INTO 关键字是可选的
INSERT INTO customers
(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email)
VALUES ('Pep E. LaPew','100 Main Street','LOS Angeles','CA','90046','USA',NULL,NULL)

-- 80.2.  插入行的一部分
INSERT INTO customers
(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)
VALUES ('Pep E. LaPew','100 Main Street','LOS Angeles','CA','90046','USA')


-- 80.3. 插入多行,一次只能插入一行值,单条INSERT语句不支持多个VALUES子句
INSERT INTO customers
(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)
VALUES ('Pep E. LaPew','100 Main Street','LOS Angeles','CA','90046','USA')
INSERT INTO customers
(cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)
VALUES ('M. Martian','42 Galaxy Way','New York','NY','11213','USA')


-- 80.4. 插入某些查询的结果
INSERT INTO customers(
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
)
SELECT cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
FROM customers
where cust_id=10001

-- 80.5. 创建一个包含从一个或多个表检索出的行,可以用SELECT INTO 表,此表必须不存在,否则将出错;
SELECT cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country
INTO customersExport
FROM customers

------------------------更新数据-----------------------

-- 要更新的表
-- 列名和它们的新值
-- 确定要更新行的过滤条件


-- 81.1 更新表中特定行:更新客户10005的电子邮件地址
update customers
set cust_email ='elmer@fudd.com'
where cust_id = 10005

update customers
set cust_email = NULL
where cust_id = 10005

-- 81.2 更新表中所有行:更新所有客户的电子邮件地址,为'elmer@fudd.com'
update customers
set cust_email ='elmer@fudd.com'

-- 81.3 更新客户10005的多个列,电子邮件地址和姓名
update customers
set cust_email ='elmer@fudd.com',
    cust_name = 'The Fudds'
where cust_id = 10005


------------------------删除数据-----------------------

-- 删除和更新的指导规则: 最好使用带where的update和delete子句, SQL Server没有撤销under按钮。所有必须小心地使用update和delete;


-- 82.1 从表中删除特定的行:删除cust_id=10006的行
DELETE FROM customers
WHERE cust_id= 10006

-- 82.2 从表中删除所有行
DELETE FROM customers

------------------------创建和操作表-----------------------

-- 创建表的两种方法: 1. 使用SSMS 等创建和管理表的公交 。 2.使用SQL 语句操纵

-- 创建表基础: 新表的名字,表列的名字和定义,用逗号分隔;

-- 83.1  创建customers表,主键为cust_id 唯一并且自动增长,也可以用多个列组成;NULL值用关键字NULL而不是空串指定,空串''是表示一个有效的值,它不是无值;
create table customers
(
cust_id         INT        NOT NULL IDENTITY(1,1),
cust_name       NCHAR(50)  NOT NULL,
cust_address    NCHAR(50)  NULL,
cust_city       NCHAR(50)  NULL,
cust_state      NCHAR(5)   NULL,
cust_zip        NCHAR(10)  NULL,
cust_country    NCHAR(50)  NULL,
cust_contact    NCHAR(50)  NULL,
cust_email      NCHAR(255) NULL,
PRIMARY KEY (cust_id)
);

create table orderitems
(
order_num     INT         NOT NULL,
order_item    INT         NOT NULL,
prod_id       NCHAR(10)   NOT NULL,
quantity      INT         NOT NULL,
item_price    MONEY       NOT NULL,
PRIMARY KEY (order_num,order_item)
)

-- IDENTITY(1,1) 表示从种子1开始,每次生成新编号的增量为1; IDENTITY(100,10)表示从种子100开始,增量为10;

-- 83.2 更新表,给表orderitems添加一个列vend_phone,类型为char(20),即使表中存在数据也可以添加列,但是不建议这样做
ALTER TABLE orderitems
ADD vend_phone CHAR(20)

-- 83.3 更新表,给表orderitems删除一个列vend_phone,但是删除之前请确认,表中该列数据也会删除
ALTER TABLE orderitems
DROP COLUMN vend_phone


-- 83.4 更新表,添加外键

-- 给表orderitems添加外键fk_ordertiems_orders,即表orders的主键order_num
ALTER TABLE orderitems
ADD CONSTRAINT fk_ordertiems_orders FOREIGN KEY (order_num)
REFERENCES orders(order_num)
 
ALTER TABLE products
ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id)
REFERENCES vendors(vend_id)

-- ALTER TABLE可以用来更改表列(或约束,索引等对象)

-- 83.5 表结构更改的手动删除过程,最好在操作前先做个完全备份,需要遵守以下步骤:

-- a. 创建一个新的表,新的表名,使之包含新的列
CREATE TABLE orderitems_temp
  (
  order_num INT NOT NULL,
  order_item INT NOT NULL,
  prod_id  nchar(10) NOT NULL,
  quantity INT NOT NULL,
  item_price  MONEY  NOT NULL,
  item_price2  MONEY  NOT NULL,
  PRIMARY KEY (order_num,order_item) 
  )

-- b. 使用INSERT SELECT INTO 语句将旧表的数据复制到新表
  INSERT INTO orderitems_temp
  SELECT * FROM orderitems

-- c. 检验新表的数据包含旧表的信息,select * from orderitems_temp

-- d. 重命名旧表,建议重命名旧表不要删除,待验证成功后,可删除: exec sp_rename 'orderitems', 'orderitems_old'

-- e. 用旧表原来的名字重命名新表: exec sp_rename 'orderitems_temp', 'orderitems'

-- f. 根据需要重新创建触发器,存储过程,索引和外键; 下面重新创建外键

ALTER TABLE orderitems_old
DROP CONSTRAINT fk_ordertiems_orders

ALTER TABLE orderitems_old
DROP CONSTRAINT fk_orderitems_products

ALTER TABLE orderitems
ADD CONSTRAINT fk_ordertiems_orders FOREIGN KEY (order_num) REFERENCES orders(order_num) 

ALTER TABLE orderitems
ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products(prod_id)

-- 84.1 删除表orderitems_old,该语句不需要确认,也不能撤销,执行后将永久删除该表。

DROP TABLE orderitems_old


------------------------使用视图-----------------------

-- 85.1 视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询; 视图包含的是一个SQL 查询

-- 85.2 为什么使用视图

-- a. 可以重用SQL 语句;
-- b. 简化复杂的SQL 操作; 可以一次性编写基础的SQL, 然后根据需要多次使用;
-- c. 使用表的组成部分而不是整个表;
-- d. 保护数据,可以咯用户授予表的特定部分的访问权限而不是整个表的访问权限;
-- e. 更改数据格式和表示,视图可返回与底层表的表示和格式的不同的数据;
-- f. 视图本身不包含数据,返回的数据是从其他表检索出来的,在添加或更改这些表中的数据时,视图将返回改变过的数据。

-- 85.3 视图的规则和限制

-- a. 与表一样,视图必须唯一命名;
-- b. 对于可以创建的视图数目没有限制;
-- c. SQL SERVER视图可能只包含不多于1024列;
-- d. 为了创建视图,必须具有足够的访问权限。这些限制通常由数据库管理员授予;
-- e. 视图可以嵌套,即可以从其他视图中检索数据的查询来构造一个视图;
-- f. order by 不可以用在视图中,但可以用在从视图中检索数据的select 语句里;
-- g. 视图不能索引,也不能有关联的触发器或默认值;
-- h. 视图可以和表一起使用,如编写一条联结表和视图的select语句

-- 85.4 视图的使用

-- a. 创建视图productcustomers,返回已订购任意产品的所有客户的列表

-- 创建视图productcustomers
CREATE VIEW productcustomers AS
SELECT cust_name,cust_contact, prod_id
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id
AND orderitems.order_num = orders.order_num

-- 返回已订购任意产品的所有客户的列表
SELECT * FROM productcustomers

-- 返回订购了产品TNT2的客户的列表
SELECT cust_name,cust_contact
FROM productcustomers
WHERE prod_id = 'TNT2'

-- b. 创建视图vendorlocations,用来重新格式化检索出的数据
CREATE VIEW verdorlocations AS
SELECT RTrim(vend_name) + '(' + RTrim(vend_country) + ')'
AS vend_title
FROM vendors

SELECT *
FROM verdorlocations
ORDER BY vend_title

-- c. 创建视图customer_email_list,过滤掉不要的数据,返回没有电子邮件地址的客户
CREATE VIEW customer_email_list AS
SELECT cust_id, cust_name, cust_email
FROM customers
WHERE cust_email IS NOT NULL

SELECT *
FROM customer_email_list

-- d. 创建视图orderitemsexpanded,简化计算字段,检索订单为20005的详细内容;

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 = 20005

-- e.删除视图orderitemsexpanded:

DROP VIEW orderitemsexpanded

-- 85.5 视图的更新:实际上是对基表的增加或删除行; 视图主要是用于数据检索的;

-- 视图是可更新的,可对他们使用INSERT,UPDATE和DELETE操作;

-- 并非所有视图都可更新,如果视图定义中有以下情况,视图将不可以进行更新;

-- a. 有多个基表
-- b. 有分组(使用GROUP BY 和HAVING)
-- c. 有联结(JOIN)
-- d. 有子查询
-- e. 有并(UNION)
-- f. 有聚集函数(Min(),Count(),Sum()等)
-- g. 有DISTINCT 关键字
-- h. 有导出(计算)列