如何向视图插入数据


/*
drop table a
drop table b
go
*/

create table A(ID int identity(1,1) primary key,Avalue varchar(10))
create table B(ID int identity(1,1) primary key,AID int,Bvalue varchar(10))
go


/*
drop view AB_view
go
*/


create view AB_view
as
select A.*, B.Bvalue from A join B on (A.ID = B.AID)
go
 

--drop trigger  AB_tr on AB_view
 
create trigger AB_tr on AB_view instead of insert
as
begin

insert into a(Avalue)
select Avalue
from 
(
select distinct id,Avalue
from inserted i
)t

insert into b(aid,Bvalue)
select  scope_identity(),Bvalue
from inserted i

end
go

 

insert into AB_view (Avalue, Bvalue) values ('A3', 'B3')


select * from a
/*
ID	Avalue
1	A3
*/

select * from b
/*
ID	AID	Bvalue
1	1	B3
*/


/*
--建立2个表
create table t1(id int not null primary key,tbl varchar(5) not null)

create table t2(id int not null primary key,tbl varchar(5) not null)

go


--插入数据
insert into t1
select object_id,'01'
from sys.objects

insert into t2
select OBJECT_ID ,'02'
from sys.objects

if exists(select * from sys.views where name = 'v_t')
   drop view v_t
go


--创建视图
create view v_t
as

select * from t1
union all
select * from t2
go

*/



if exists(select * from sys.triggers where name = 'trigger_t')
   drop trigger dbo.trigger_t
go

--1.通过判断区分列tbl的值是'01'或'02',把数据分别插入t1或t2   
create trigger dbo.trigger_t
on dbo.v_t
instead of insert
as

declare @t varchar(8);
set @t = '';


if @t = '01'
	insert into dbo.t1
	select * from inserted
else 
    insert into dbo.t2
    select * from inserted

go


--1.测试
insert into v_t
select 115,'02'

select *
from dbo.t2
where ID = 115



if exists(select * from sys.triggers where name = 'trigger_t')
   drop trigger dbo.trigger_t
go

--2.通过判断区分列tbl的值是'01'或'02',来动态生成语句实现插入数据 
create trigger dbo.trigger_t
on dbo.v_t
instead of insert
as

declare @t varchar(8);
declare @sql varchar(max);
declare @id int ;
set @t = '';

select @t = tbl,@id = ID
from inserted

set @sql = 'insert into dbo.t' + RIGHT(@t,1) + 
           '(id,tbl) values(' +
           + CAST(@id as varchar) + ',''' + @t +''')' 

exec(@sql)

go


--2.测试
insert into v_t
select 116,'01'

select *
from dbo.t1
where ID = 116



if exists(select * from sys.triggers where name = 'trigger_t')
   drop trigger dbo.trigger_t
go

--3.前两种是通过insted of触发器来实现的,接下来通过check约束来实现

--先删除原来的主键,因为分区列必须包含在主键中
alter table t1 
drop constraint PK__t1__3213E83F7F60ED59

--可以不加check约束,但会导致查询优化器必须要搜索所有的表
--加了check约束后,会直接搜索符合分区依据列的表.
alter table t1
add constraint ck_t1_tbl check(tbl='01')

--加上主键约束
alter table t1
add constraint pk_t1 primary key(id,tbl)


alter table t2
drop constraint PK__t2__3213E83F03317E3D

alter table t2
add constraint ck_t2_tbl check(tbl='02')

alter table t2
add constraint pk_t2 primary key(id,tbl)


--3.测试
insert into v_t
select 12345,'01'

select *
from dbo.t1
where ID = 12345



--4.建立索引视图

if exists(select * from sys.views where name = 'v_t')
   drop view v_t
go


--创建视图
--必须加上架构,以及明确指定列
create view dbo.v_t
with schemabinding
as

select ID,tbl from dbo.t1
union all
select id,tbl from dbo.t2

go


select * from v_t


/*
报错:

消息 10116,级别 16,状态 1,第 1 行
无法对视图 'WC.dbo.v_t' 创建 索引,
因为其中包含一个或多个 UNION、INTERSECT 或 EXCEPT 运算符。
如果将查询作为原始视图的 UNION、INTERSECT 或 EXCEPT 运算符的输入,
请考虑为每个这样的查询创建一个单独的索引视图。

说明当视图中有union all时,无法建立索引视图
*/
create unique clustered index idx_v_t on dbo.v_t(id)


### 在 SQL 视图插入数据 视图本质上是一个虚拟表,其内容由查询定义。尽管可以直接对某些类型的视图执行 `INSERT` 操作,但这取决于底层基础表的设计以及视图本身的定义方式。下面详细介绍如何向视图插入数据的具体方法和注意事项。 #### 插入数据的前提条件 为了能够顺利地通过视图插入新记录,必须满足以下几个基本前提: - **唯一性约束**:视图所基于的基础表中的列应该具有明确的主键者唯一索引来区分每一条记录。 - **无聚集函数查询**:如果视图定义中含有诸如 `SUM()`, `AVG()` 等聚合运算符者是嵌套子查询,则无法支持直接的数据修改操作。 - **字段映射清晰**:参与构成视图的所有列都应该能清楚对应到实际物理表上的某列,并且这些列允许写入新的值[^1]。 #### 向视图 v6 中插入学生信息的例子 假设我们有一个简单的视图 `v6` 它是从 `students` 表派生而来并且仅仅选取了几项基本信息作为展示用途: ```sql CREATE VIEW v6 AS SELECT student_id, name, gender, birth_date FROM students; ``` 现在如果我们想往这个视图里面增加一位名叫 "Alice", 性别为 Female 出生于 2000 年 1 月 1 日的新同学的话,可以这样编写 INSERT 语句: ```sql INSERT INTO v6 (student_id, name, gender, birth_date) VALUES (nextval('seq_student'), 'Alice', 'F', '2000-01-01'); ``` 这里需要注意的是 `student_id` 应该来自序列生成器者其他自动增长机制以确保不会发生重复冲突的情况。 然而值得注意的一点是,即使上面这条指令被执行完毕之后,在再次查询整个视图时也许看不到刚刚加入的那个条目。这主要是因为之前提到过的关于带有限制条件的视图特性问题——即当试图违反原有设定规则的情况下仍有可能成功完成原始表格层面的变化却未能反映至最终呈现给用户的视角之中[^2]。 因此为了避免此类现象的发生,在设计阶段就应该尽量减少不必要的过滤表达式的应用除非绝对必要;另外还可以考虑采用 INSTEAD OF 类型触发器来实现更加灵活可控的行为模式。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值