创建一个虚拟表,该表以另一种方式表示一个或多个表中的数据。CREATE VIEW 必须是查询批处理中的第一条语句。
CREATE VIEW [ < database_name > .] [ < owner > .] view_name [ ( column [ ,...n ] ) ]
[ WITH < view_attribute > [ ,...n ] ]
AS
select_statement
[ WITH CHECK OPTION ]
< view_attribute > ::=
{ ENCRYPTION | SCHEMABINDING | VIEW_METADATA }
view_name
是视图的名称。视图名称必须符合标识符规则。可以选择是否指定视图所有者名称。
column
是视图中的列名。只有在下列情况下,才必须命名 CREATE VIEW 中的列:当列是从算术表达式、函数或常量派生的,两个或更多的列可能会具有相同的名称(通常是因为联接),视图中的某列被赋予了不同于派生来源列的名称。还可以在 SELECT 语句中指派列名。
如果未指定 column,则视图列将获得与 SELECT 语句中的列相同的名称。
WITH CHECK OPTION
强制视图上执行的所有数据修改语句都必须符合由 select_statement 设置的准则。通过视图修改行时,WITH CHECK OPTION 可确保提交修改后,仍可通过视图看到修改的数据。
WITH ENCRYPTION
表示 SQL Server 加密包含 CREATE VIEW 语句文本的系统表列。使用 WITH ENCRYPTION 可防止将视图作为 SQL Server 复制的一部分发布。
下例显示名为 CAonly 的视图,该视图使得只对加利福尼亚州的作者应用数据修改。
USE pubs
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = 'CAonly')
DROP VIEW CAonly
GO
CREATE VIEW CAonly
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO
通过视图向表中插入数据需要满足的要求,视图必须来源于一个表,一般行子集视图都没有问题(但是必须保护关键字段,如primary key ,not null的字段必须有,才可以进行更新)
如果是多表视图,或者是列子集视图(不满足上面的要求),则可以使用instead of insert触发器来实现
单个表通过视图插入数据
1、首先创建表
CREATE TABLE [dbo].[TTotal](
[年份] [nvarchar](50) NULL,
[地区] [nvarchar](50) NULL,
[数值类别] [nvarchar](50) NULL,
[数值] [int] NULL
) ON [PRIMARY]
2、其次,创建视图
create view VTotal
as
select * from TTotal
3、执行insert 语句
insert into VTotal values('2006','测试','1',1)
对于多个表的视图,使用instead of insert 可以执行插入操作
instead of 触发器的用法
INSTEAD OF 触发器的主要优点是可以使不能更新的视图支持更新。基于多个基表的视图必须使用
INSTEAD OF 触发器来支持引用多个表中数据的插入、更新和删除操作。INSTEAD OF 触发器的另一个优点是使您得以编写这样的逻辑代码:在允许批处理的其他部分成功的同时拒绝批处理中的某些部分。
Transact-SQL 语句创建两个基表、一个视图和视图上的 INSTEAD OF 触发器。以下表将个人数据和业务数据分开并且是视图的基表。
/*在视图上定义 instead of insert 触发器以在一个或多个基表中插入数据。*/
--部门表
create table dept
(
d_id int primary key,
d_name varchar(20)
)
--员工表
create table emp
(
e_id int primary key,
e_name varchar(20),
d_id int references dept(d_id)
)
select * from emp
drop view v
create view v
as
select e_id,e_name,d.d_id,d_name from emp e,dept d where e.d_id=d.d_id
select * from v
insert into v values(1001,'张珊',101,'销售部')
/*******************使用instead of 触发器******************/
drop trigger de_em_insert
go
create trigger de_em_insert
on v
instead of insert
as
begin
if (not exists (select d.d_id from dept d, inserted i where d.d_id = i.d_id))
insert into dept select d_id,d_name from inserted
if (not exists (select e.d_id from emp e, inserted i where e.d_id = i.d_id))
insert into emp select e_id,e_name,d_id from inserted
else
update emp set e_id = i.e_id,e_name = i.e_name from emp e, inserted i where e.d_id = i.d_id
end
可以在视图或表中定义 INSTEAD OF DELETE 触发器,以代替 DELETE 语句的标准操作。通常,在视图上定义 INSTEAD OF DELETE 触发器以便在一个或多个基表中修改数据。
可在视图上定义 INSTEAD OF UPDATE 触发器以代替 UPDATE 语句的标准操作。通常,在视图上定义 INSTEAD OF UPDATE 触发器以便修改一个或多个基表中的数据。