-- 测试数据
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的高手如何解决.

解决方案 »

  1.   

    为何第一个a是150,第二个a是50,而不是第一个a 为 100,第二个a 也为100?什么规则? 你括号里写的看不懂
      

  2.   


    上述限制应用于视图的 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)。
      

  3.   

    view是不可以update的..只能update基表..
    基表改了view 也随着改了...
      

  4.   

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

  5.   

    可更新视图是依靠触发器来实现的。方案是可行的,但是没有具体的更新规则,我在1楼已经说明了。如果没有特别的规则,只要求a的sum(num)聚合值为指定的值,那触发器里随便写下就出来了。
      

  6.   

    /*
    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
      

  7.   


    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 
      

  8.   

    月儿弯弯 思路是对的但你没考虑到  update name 必须回滚操作 以及 instead of 以及 deleted 和 inserted 区别.那些说不行的.回去扫盲下.
      

  9.   

    基础表numnum +(更新后视图的 num-更新前视图 num)* 基础表num/更新前视图的 num 
      

  10.   

    改天 出个 上下文信息 来控制触发器 看看 csdn 上到底有没有高手
      

  11.   

    视图的使用在大多数情况下和表使用一致,例如,可以用SELECT/UPDATE/INSERT/DELETE操作视图的数据。
    但是,视图毕竟是在基表的数据上派生的,在通过视图修改基表的数据的时候受到一下诸多限制:
    1)任何修改(包括通过UPDATE\INSERT\DELETE语句)都只能引用一个基表的列
    2)视图中被修改的列必须直接引用表列中的基础数据,它们不能通过其它方式派生,例如:聚合函数、计算等。
    3)
      

  12.   

    csdn 小白太多 无语.别拿那些教课书当权威.有空看看 inside