-- 测试数据
if object_id(N't','U') is not null
drop table t
go
create table t(name varchar(20),num int);
insert into t select name,num from (select name='a',num=100 union all select 'a',50 union all select 'b',100 union all select 'b',200)x
/*
name num
a 100
a 50
b 100
b 200
*/
--建立视图
if object_id(N'v_t','V') is not null
drop view v_t
go
create view v_t
as
select name,sum(num) as num
from t
group by name/*
name num
a 150
b 300
*/现在要求如下 当v_t视图进行update 更行的时候 比如
update v_t set num=200 where name='a'
则相应的基表 t里面也更新
基表的 name=‘a'的行也更新
效果如下
--t
/*
name num
a 150(1+150/200*(200-150))
a 50(1+50/200*(200-150))
b 100
b 200
*/
--v_t
/*
name num
a 200
b 300
*/
有点难度 看看csdn的高手如何解决.
上述限制应用于视图的 FROM 子句中的任何子查询,就像其应用于视图本身一样。
通常,Microsoft SQL Server 2005 必须能够明确跟踪从视图定义到一个基表的修改。例如,以下视图不可更新:CREATE VIEW TotalSalesContacts
AS
SELECT C.LastName,
SUM(O.TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader O, Person.Contact C
WHERE C.ContactID = O.ContactID
GROUP BY LastName
对 TotalSalesContacts 的 LastName 列所做的修改是不可接受的,因为该列已受到 GROUP BY 子句的影响。
如果有多个具有相同姓氏的实例,则 SQL Server 将无法得知要 UPDATE、INSERT 或 DELETE 哪一个实例。
同样,尝试修改 TotalSalesContacts 的 TotalSales 列将返回错误,
因为此列是由聚合函数派生而来的。SQL Server 无法直接跟踪此列到其基表(SalesOrderHeader)。
基表改了view 也随着改了...
drop table t
go
create table t(name varchar(20),num int);
insert into t select name,num from (select name='a',num=100 union all select 'a',50 union all select 'b',100 union all select 'b',200)x
go
if object_id(N'v_t','V') is not null
drop view v_t
go
create view v_t
as
select name,sum(num) as num
from t
group by name
go
create trigger tr on v_t
instead of update
as
update t set t.num=t.num + b.num --因为无法知道你的规则,所以我以num 直接加上那个值来操作
from t
inner join inserted b
on b.name=t.name
goupdate v_t set num=100
go
select * from v_t
/*a 350
b 500
告知规则即可得到你所需要的数据
*/
select * from t
/*
a 200
a 150
b 200
b 300
在a的每行的num列上都加了100
*/
go
drop trigger tr
go
name num
a 150+150/200*(200-150)
a 50+50/200*(200-150)
b 100
b 200
*/
--v_t
/*
name num
a 200
b 300
*/
应该是这个样子
我把公式写错了
但试图是可以更新的
代码如下:
createtrigger tr_vt on v_t
instead of update
as
if @@rowcount=0 return;
if update(name)
begin
raiserror('updates to the name column are not allowed,',16,1);
rollback transaction
return
end;
with
xwj
as
(select a.name,num,round(num+cast(num as float)/c.sum_num*(b.sum_num-c.sum_num),0) as newnum
from t as a
inner join inserted b
on a.name=b.name
inner join deleted c
on a.name=c.name
)
update xwj set num=newnum
;
go
createtrigger tr_vt on v_t
instead of update
as
if @@rowcount=0 return;
if update(name)
begin
raiserror('updates to the name column are not allowed,',16,1);
rollback transaction
return
end;
with
xwj
as
(select a.name,num,round(num+cast(num as float)/c.sum_num*(b.sum_num-c.sum_num),0) as newnum
from t as a
inner join inserted b
on a.name=b.name
inner join deleted c
on a.name=c.name
)
update xwj set num=newnum
;
go
但是,视图毕竟是在基表的数据上派生的,在通过视图修改基表的数据的时候受到一下诸多限制:
1)任何修改(包括通过UPDATE\INSERT\DELETE语句)都只能引用一个基表的列
2)视图中被修改的列必须直接引用表列中的基础数据,它们不能通过其它方式派生,例如:聚合函数、计算等。
3)