--示例--原始数据
create table t1(id int primary key,name varchar(10))
create table t2(id int primary key,sex char(2),age int)
go--视图
create view v
as
select a.id,a.name,b.sex,b.age
from t1 a join t2 b on a.id=b.id
go--处理的触发器
--新增处理
create trigger tr_insert on v
instead of insert
as
insert t1 select id,name from inserted
insert t2 select id,sex,age from inserted
go--删除处理
create trigger tr_delete on v
instead of delete
as
delete t1
from t1 a join deleted b on a.id=b.iddelete t2
from t2 a join deleted b on a.id=b.id
go--更新处理
create trigger tr_update on v
instead of update
as
select mid=identity(int,1,1),* into #i from inserted
select mid=identity(int,1,1),id into #d from deletedupdate t1 set id=b.i_id,name=b.name
from t1 a join(
select i_id=i.id,d_id=d.id,name
from #i i join #d d on i.mid=d.mid
)b on a.id=b.d_idupdate t2 set id=b.i_id,sex=b.sex,age=b.age
from t2 a join(
select i_id=i.id,d_id=d.id,sex,age
from #i i join #d d on i.mid=d.mid
)b on a.id=b.d_id
go--数据测试
--插入数据
insert v  select 1,'张三','男',23
union all select 2,'李三','女',23
union all select 3,'王三','男',25--更新数据
update v set age=25 where age=23
update v set id=id+3,name=name+'_new'
where id>1--删除数据
delete from v where id=1
go--显示结果
select * from v
select * from t1
select * from t2
go--删除测试
drop table t1,t2
drop view v/*--测试结果id          name       sex  age         
----------- ---------- ---- ----------- 
5           李三_new     女    25
6           王三_new     男    25(所影响的行数为 2 行)id          name       
----------- ---------- 
5           李三_new
6           王三_new(所影响的行数为 2 行)id          sex  age         
----------- ---- ----------- 
5           女    25
6           男    25(所影响的行数为 2 行)
--*/

解决方案 »

  1.   

    联机丛书有现成的例子; 创建和维护数据库  
    INSTEAD OF INSERT 触发器
    可以在视图或表上定义 INSTEAD OF INSERT 触发器来代替 INSERT 语句的标准操作。通常,在视图上定义 INSTEAD OF INSERT 触发器以在一个或多个基表中插入数据。视图选择列表中的列可为空也可不为空。如果视图列不允许为空,则 INSERT 语句必须为该列提供值。如果定义视图列的表达式包括以下项目,则视图列允许为空: 对任何允许为空的基表列的引用。
    算术运算符。
    对函数的引用。
    具有可为空的子表达式的 CASE 或 COALESCE。
    NULLIF。 
    可以使用 COLUMNPROPERTY 函数报告的 AllowsNull 属性来确定视图列是否允许为空。sp_help 存储过程还报告哪些视图列允许为空。引用具有 INSTEAD OF INSERT 触发器的视图的 INSERT 语句必须为每个不允许为空的视图列提供值。这包括引用不能为其指定输入值的基表列的视图列: 基表中的计算列。
    IDENTITY INSERT 为 OFF 的基表中的标识列。
    具有 timestamp 数据类型的基表列。 
    如果 INSTEAD OF INSERT 视图触发器使用 inserted 表中的数据对基表生成 INSERT,则它应当通过排除 INSERT 语句选择列表中的列忽略这些类型的列值。INSERT 语句可为这些类型的列生成虚值。例如,因为 INSERT 语句必须为映射到基表中标识列或计算列的视图列指定值,所以它可提供占位符值。INSTEAD OF 触发器在构成将值插入基表的 INSERT 语句时会忽略提供的值。下面的语句创建表、视图和触发器,以解释这一过程:CREATE TABLE BaseTable
      (PrimaryKey     int IDENTITY(1,1)
       Color          nvarchar(10) NOT NULL,
       Material       nvarchar(10) NOT NULL,
       ComputedCol AS (Color + Material)
      )
    GO--Create a view that contains all columns from the base table.
    CREATE VIEW InsteadView
    AS SELECT PrimaryKey, Color, Material, ComputedCol
    FROM BaseTable
    GO--Create an INSTEAD OF INSERT trigger on the view.
    CREATE TRIGGER InsteadTrigger on InsteadView
    INSTEAD OF INSERT
    AS
    BEGIN
      --Build an INSERT statement ignoring inserted.PrimaryKey and 
      --inserted.ComputedCol.
      INSERT INTO BaseTable
           SELECT Color, Material
           FROM inserted
    END
    GO直接引用 BaseTable 的 INSERT 语句不能为 PrimaryKey 和 ComputedCol 列提供值。例如:--A correct INSERT statement that skips the PrimaryKey and ComputedCol columns.
    INSERT INTO BaseTable (Color, Material)
           VALUES (N'Red', N'Cloth')--View the results of the INSERT statement.
    SELECT PrimaryKey, Color, Material, ComputedCol
    FROM BaseTable--An incorrect statement that tries to supply a value for the 
    --PrimaryKey and ComputedCol columns.
    INSERT INTO BaseTable
           VALUES (2, N'Green', N'Wood', N'GreenWood')然而,引用 InsteadView 的 INSERT 语句必须为 PrimaryKey 和 ComputedCol 列提供值:--A correct INSERT statement supplying dummy values for the 
    --PrimaryKey and ComputedCol columns.
    INSERT INTO InsteadView (PrimaryKey, Color, Material, ComputedCol)
           VALUES (999, N'Blue', N'Plastic', N'XXXXXX')
    --View the results of the INSERT statement.
    SELECT PrimaryKey, Color, Material, ComputedCol
    FROM InsteadView传递到 InsteadTrigger 的 inserted 表由不可为空的 PrimaryKey 和 ComputedCol 列构成,所以引用该视图的 INSERT 语句必须提供那些列的值。值 999 和 N'XXXXXX' 传递到 InsteadTrigger,但是触发器中的 INSERT 语句没有选择 inserted、PrimaryKey 或 ComputedCol,因此忽略该值。实际插入 BaseTable 的行在 PrimaryKey 中有 2,在 ComputedCol 有 N'BluePlastic'。在表上指定的 INSTEAD OF INSERT 触发器和在视图上指定的 INSTEAD OF 触发器,其 inserted 表中包含的计算列、标识列和 timestamp 列的值不同。
    基表列 
    表上任何 INSERT 触发器的 inserted 表中的值 视图上 INSTEAD OF INSERT 触发器 inserted 表中的值 
    是计算列。 计算表达式 用户指定值或 NULL 
    具有 IDENTITY 属性。 如果 IDENTITY_INSERT 为 OFF 则为 0,如果 IDENTITY_INSERT 为 ON 则为指定值 用户指定值或 NULL 
    具有 timestamp 数据类型。 若该列不允许空值则为二进制零,若该列允许空值则为 NULL 用户指定值或 NULL 
    直接引用基表的 INSERT 语句不必为同样具有 DEFAULT 定义的 NOT NULL 列提供值。如果 INSERT 语句不提供值,则使用默认值。然而,如果含有 DEFAULT 定义的 NOT NULL 列由含有 INSTEAD OF INSERT 触发器的视图中的简单表达式引用,则任何引用该视图的 INSERT 语句必须提供列值。该值对于生成传递给触发器的 inserted 表是必需的。对发信号通知触发器应使用默认值的值必须有相应的规则。最好的规则是让 INSERT 语句提供默认值。INSTEAD OF INSERT 触发器的 deleted 表总是空的。
    请参见COLUMNPROPERTYsp_help©1988-2004 Microsoft Corporation. 保留所有权利。
      

  2.   

    通过试图插入:
       视图包括说有属性为NOT NULL的列
    A、 没有聚合函数(子查询除外)
    B、 不包含 TOP、GROUP BY、UNION、DISTINCT
    C、 没有派生列(任何非简单列表达式(使用函数、加法或减法运算符等)所构成的结果集列)
    D、 select_statement 中的 FROM 子句至少引用一个表
    DELETE
    有当视图在其 FROM 子句中只引用一个表
    没有聚合函数(子查询除外)UPDATE 不能修改派生列
    没有聚合函数(子查询除外)