--工资自定义公式的计算方法示例
--邹建--测试数据
create table 公式表(工资项目 sysname,项目代码 sysname,是否打印 bit,计算公式 varchar(1000))
insert into 公式表
select '基本工资','gz1',1,null
union all select '考勤','gz2',1,null
union all select '工龄','gz3',1,null
union all select '奖金','gz4',1,null
union all select '应发工资','gz5',1,'gz1+gz2+gz3+gz4'
union all select '养老保险','gz6',0,null
union all select '应纳税收入','gz7',1,'case when gz5-gz6>0 then gz5-gz6 else 0 end'
union all select '个人所得税','gz8',1,'case when gz7<500 then gz7*.05 else case when gz7>=500 and gz7<2000 then gz7*.1-25 else gz7*.15-125 end end'
union all select '实发工资','gz9',1,'gz5-gz6-gz8'create table 工资表(职员 varchar(10),gz1 int,gz2 int,gz3 int,gz4 int
,gz5 int,gz6 int,gz7 int,gz8 int,gz9 int)
insert into 工资表(职员,gz1,gz2,gz3,gz4,gz6)
select '张三',1000,1,1,100,100
union all select '李四',1200,1,2,150,150
go--工资计算的存储过程
create proc p_calc
as
declare @s1 varchar(8000),@s2 varchar(8000),@s3 varchar(8000)
,@i1 int,@i2 varchar(20)select @s1='',@s2='',@s3=''
,@i1=0
select @i1=@i1+1,@i2='@'+cast(@i1 as varchar)
,@s1=@s1+','+@i2+' varchar(8000)'
,@s2=@s2+'
,'+@i2+'=''update 工资表 set ['+项目代码+']=('+计算公式+')'''
,@s3=@s3+'
exec('+@i2+')'
from 公式表 where 计算公式 is not null
select @s1=substring(@s1,2,8000),@s2=substring(@s2,4,8000)
exec('declare '+@s1+'
select '+@s2+'
'+@s3)
go--调用存储过程,实现工资计算
exec p_calc
go--显示计算结果
select * from 工资表
go--删除测试环境
drop table 公式表,工资表
drop proc p_calc

解决方案 »

  1.   

    楼上误会我的意思了,我意思是用视图进行行列转换的方式将工资表
    员工编号 ,会计期间,工资项目,金额 转换成
    员工编号,会计期间,工资项目1金额,工资项目2金额,工资项目3金额,工资项目4金额................然后,直接update 视图,是否可以更新到工资表?
      

  2.   

    to  zjcxc(邹建) 你的 SP 我看不懂,能否多些注釋,萬分感謝!!!
      

  3.   

    to laker_tmj 你可以在sp中用print将@s1,@s2,@s3输出看看~~~~~
      

  4.   

    實發工資 gz9 1 gz5-gz6-gz8
    邹建的方法,可以計算項目中用計算項目(不過也要注意計算順序)但是要是這樣設計表 员工编号 ,会计期间,工资项目,金额那要怎麼樣才可以計算項目中用計算項目 ?
      

  5.   

    实现是可以实现,类似于update 工资表 set gz9 = a.gz5 - b.gz6 - c.gz8
                         from 工资表,工资表 a ,工资表 b,工资表 c
                         where 工资表.会计期间=a.会计期间 and 工资表.员工编号=a.员工编号 
                         and 工资表.会计期间=b.会计期间 and 工资表.员工编号=b.员工编号
                        and 工资表.会计期间=c.会计期间 and 工资表.员工编号=c.员工编号 只是思路,没有具体测试,只是想知道两种方式的优缺点,那一种更合理!
      

  6.   

    樓上你的不對啊 表結構是這樣的员工编号 ,会计期间,工资项目,金额我現在也想選擇你所說的這種結構,我的方法是加入數據(計算項目中有計算項目用代替行了)

    個人所得稅 gz8 1 case when gz7<500 then gz7*.05 else case when gz7>=500 and gz7<2000 then gz7*.1-25 else gz7*.15-125 end end----->case when (case when gz5-gz6>0 then gz5-gz6 else 0 end)<500 
    then (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.05
      else case 
    when (case when gz5-gz6>0 then gz5-gz6 else 0 end)>=500 and (case when gz5-gz6>0 then gz5-gz6 else 0 end)<2000 
    then (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.1-25 
    else (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.15-125 
            end 
    end
      

  7.   

    to  winstar66() 你的公式定義是怎麼做?
      

  8.   

    至于计算的sp,用的是动态SQL语句,你可以将生成的sql语句print出来分析
      

  9.   

    to  zjcxc(邹建)
    謝謝! 我已用print看懂你的 SP 。我考虑的出发点是,一般工资项目增减的可能性小一些,工资公式的设置为变化多一些,而且不同的部门,也肯定有不同的公式,所以要优先查询/计算/统计你的說法我知道的模糊,沒有測試過沒有具體的比較結果數據,只知道現在公司的工資計算慢得要死(access db),我想你所說(要优先查询/计算/统计)是指性能速度方面的吧。現在想用下面的 A結構 ,所以正在學習你的 “生成交叉表的簡單通用存儲過程”A 员工编号 ,会计期间,工资项目,金额
    B 员工编号 ,会计期间,工资项目1,工资项目2,工资项目3,......以上兩種結構在性能速度上,你有沒有具體的數字比較結果 ?在你的例子SP中計算項目中有計算項目,但是卻沒有區分計算的先後,所以我想把計算項目包括計算項目的算法(如下所示)這樣我就不用管理各項目這間的計算順序了,
    不知道這樣做在性能上要損失多少?個人所得稅 gz8 1 case when gz7<500 then gz7*.05 else case when gz7>=500 and gz7<2000 then gz7*.1-25 else gz7*.15-125 end end----->case when (case when gz5-gz6>0 then gz5-gz6 else 0 end)<500 
    then (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.05
      else case 
    when (case when gz5-gz6>0 then gz5-gz6 else 0 end)>=500 and (case when gz5-gz6>0 then gz5-gz6 else 0 end)<2000 
    then (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.1-25 
    else (case when gz5-gz6>0 then gz5-gz6 else 0 end)*.15-125 
            end 
    end期待 回答! 謝謝!!!