create table table1(id int,plan varchar(20),Area varchar(20), output int,DailyOutput int)
数据如下
id plan Area output DailyOutput
1 P1 A1 500 1500
2 P1 A2 500 1500
3 P1 A3 500 1500
4 P2 A1 500 1400
5 P2 A2 400 1400
6 P2 A3 500 1400
我在修改output的时候DailyOutput 也要修改 假如我要修改A1的output 为300 那对应的P1的DailyOutput 全部修改为1300在修改A1的数据最好以ID为条件,因为可能有重复数据!用一条语update语句实现!
数据如下
id plan Area output DailyOutput
1 P1 A1 500 1500
2 P1 A2 500 1500
3 P1 A3 500 1500
4 P2 A1 500 1400
5 P2 A2 400 1400
6 P2 A3 500 1400
我在修改output的时候DailyOutput 也要修改 假如我要修改A1的output 为300 那对应的P1的DailyOutput 全部修改为1300在修改A1的数据最好以ID为条件,因为可能有重复数据!用一条语update语句实现!
不会是这个吧?
还是说你要一旦output被更新,DailyOutput也要同时更新?
那就要用update触发器额
--id plan Area output DailyOutput
--这个应该是触发器吧!create trigger tb_up on tb
for update
as
if update(output)
update a
set a.DailyOutput = a.DailyOutput + a.output - b.output
from tb a,inserted b
where a.plan = b.plan
不知道对不对。
where id=(select id from table1 where plan='P1' and Area='A1')
select 1,'p1','A1',500,1500 union
select 2,'p1','A2',500,1500 union
select 3,'p1','A3',500,1500 union
select 4,'p2','A1',500,1400 union
select 5,'p2','A2',400,1400 union
select 6,'p2','A3',500,1400 CREATE TRIGGER tr_name ON table1
AFTER UPDATE
as
BEGIN
if update(outputs)
begin
update a set a.DailyOutput=a.DailyOutput-b.outputs+c.outputs
from table1 a,deleted b,inserted c
where a.plans=b.plans
end
ENDupdate table1 set outputs=100 where id=1select * from table1
/*
id plans Area outputs DailyOutput
----------- -------------------- -------------------- ----------- -----------
1 p1 A1 100 1100
2 p1 A2 500 1100
3 p1 A3 500 1100
4 p2 A1 500 1400
5 p2 A2 400 1400
6 p2 A3 500 1400(6 行受影响)
每次 output 更新一下 就执行一次下面的语句
update table1
set DailyOutput=a.sum_output
from table1 b,
(
select plan,sum(output) as sum_output
from table1
group by plan
) a
where a.plan=b.plan
set output=300,DailyOutput=1300
where id in (select id from table1 where Area='A1')
--不能用触发器?
--那就两条update tb
set output = 300
where id = 1update a
set a.DailyOutput = a.DailyOutput + a.output - b.output
from tb a,(select * from tb where id = 1)b
where a.plan = b.plan
update tb
set output = (case when id = 1 then 300 else output end),DailyOutput = DailyOutput - 300
where plan = (select plan from tb where id = 1)
你弄个视图好了
create view test
as
select plan,sum(output) as DailyOutput
from table1
group by plan
go主表变 视图跟着变 DailyOutput通过plan关联 用现成的
你不能用触发器 视图也不能用啊
DailyOutput你是用一组相同plan求和的吧?
查询的时候关联下就好了。update也不需要的
要么触发器
一条update搞不定
insert #table1
select 1 ,'P1','A1',500,1500 union all
select 2 ,'P1','A2',500,1500 union all
select 3 ,'P1','A3',500,1500 union all
select 4 ,'P2','A1',500,1400 union all
select 5 ,'P2','A2',400,1400 union all
select 6 ,'P2','A3',500,1400 union all
select 7 ,'P4','A1',500,1400declare @T table(id int,[output] int)
update #table1 set [output]=300 output inserted.id,inserted.[output] into @T where Area='A1'
update #table1 set DailyOutput=1000+T.[output] from @T as t where #table1.id=t.idselect * from #table1--id plan Area output DailyOutput
------------- -------------------- -------------------- ----------- -----------
--1 P1 A1 300 1300
--2 P1 A2 500 1500
--3 P1 A3 500 1500
--4 P2 A1 300 1300
--5 P2 A2 400 1400
--6 P2 A3 500 1400
--7 P4 A1 300 1300
--
--(7 row(s) affected)
where plans in (select plans from table1 where area=(select area from table1 where id=1))
没猜错的话 你的这个表里面的非关键字字段dailyoutput并没有依赖于主键 而是依赖于
[plan]和[output]这2个非关键字字段的 所以导致了你写更新语句的时候出现了难题。
一般情况下 非关键字字段都是要依赖于关键字字段的 更新某个字段的时候通过主键关联更新就好了。
但是你已经是这样的设计了 所以上面跟你提供了几个方案来解决希望能够帮助你。
呵呵 你要是硬要说我害你 我也没办法的、
两条语句不是送分吗? 两条语句还用得着在csdn上面发贴!..挺汗!
晕倒! 你脑残吧! 我是学得不好!所以才来csdn上请教,你学得好你写出来了!
自己没本事写出来,出啥风头,跑出来骂人!
这么简单的sql没写出来真不知道你排名怎么来的! 还有脸出来骂人!
素质真差! 还真不知道csdn上面还有这种鸟!
我昨天只看了你的问题,没有看ssp2009的回复,没有抄袭,这是我自己写的,你一定要说我照搬我就照搬吧,妈的,几年没上csdn了,第一次回帖就碰到这鸟事。
set output = case when t1.id = t2.id then 300 else t1.output end ,
dailyoutput = t1.DailyOutput - t2.output + 300
from table1 t1
join table1 t2
on t1.plan = t2.plan
and t2.id = 1 1 和 300 请自行定义变量。
from #table1 a但是实际上那个dailyoutput是错的,因为一次update共享一个行锁所以得到的那个dailyoutput是错误的,它不能体现出output的实际变化
这里你必须用两次update,第一次update output ,第二次 update dailyoutput
的确很多公司不允许触发器,说明其高阶管理人员能力有限,那么你可以用存储过程,如果连存储过程都不行,你就在前台代码里面写两句sql,总不会连前台分两次调sql都不允许吧?
另外lz别那么急躁么,写程序是一辈子的事,不要急,不要急!
说白了,现在的程序员...没几个能写出超过3层嵌套的SQL语句....还有拿范式说的.... 我当时见过一个电信关于地区的表...
用于描述 C县属于B市,B市属于A省....子节点可以无限... 父节点可以有N个同级子节点
这种关系,不是一些简单的什么范式就可以来规定的....
但是业务就在那...你能给电信说...你这不符合规范!我们不做吗??
SQL的灵活性...比JavaScript还要高
还有单条查询通常比存储过程来的更效率,再说...Oracle的存储过程,在用的时候不是那么方便..(相比MSSQL)触发器,在不少的小中型企业...确实有不允许用的规定....原因自己去查.不罗嗦..
LZ的问题有点描述不清楚:
1.你的P1里有A1 ,P2里也有A1...你说P1全部改为1300;那P2的需要不?
2.还有A1的数据,已ID为条件...OK...那你到底哪个字段是条件?Area 还是ID?
set dailyoutput = 1300
where plan='p1' and decode(sign((select count(*) from table1 where id=1 and area='a1' and output='300')-0),1,'Y','N')='Y'