--工资自定义公式的计算方法示例
--邹建--测试数据
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
--邹建--测试数据
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金额,工资项目2金额,工资项目3金额,工资项目4金额................然后,直接update 视图,是否可以更新到工资表?
邹建的方法,可以計算項目中用計算項目(不過也要注意計算順序)但是要是這樣設計表 员工编号 ,会计期间,工资项目,金额那要怎麼樣才可以計算項目中用計算項目 ?
from 工资表,工资表 a ,工资表 b,工资表 c
where 工资表.会计期间=a.会计期间 and 工资表.员工编号=a.员工编号
and 工资表.会计期间=b.会计期间 and 工资表.员工编号=b.员工编号
and 工资表.会计期间=c.会计期间 and 工资表.员工编号=c.员工编号 只是思路,没有具体测试,只是想知道两种方式的优缺点,那一种更合理!
如
個人所得稅 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
謝謝! 我已用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期待 回答! 謝謝!!!