關於SQL SERVER 儲存過程使用(2)
阿新 • • 發佈:2018-12-21
現在有一場景,需要調用出公司員工在本週的請假天數。程式碼如下(1),本人一開始寫的時候用遍歷裡面套著一個遍歷,發現效果出不來如下(2),求是否有什麼方法可以實現遍歷裡面還有個遍歷。
SQL程式碼(1):
--建立儲存過程
create procedure LeaveTimes
--接收傳入值 使用者名稱 當前日期
@UserNames nvarchar(60), --接收的iwork使用者名稱
@CurrentTime datetime, --接收的當前日期,即為登入iwork的校驗系統時間
@LeaveDay decimal(4,1)=0 output --輸出請假天數
as
begin
--傳入的值不能為空
IF(
@UserNames IS NOT NULL AND @UserNames <> ''
AND
@CurrentTime IS NOT NULL AND @CurrentTime <> ''
)
begin
--查出當前日期對應的週一與週日日期
DECLARE @Mondaytime DATETIME; ---本週的週一日期
DECLARE @Sundaytime DATETIME; ---本週的週日日期
set @Mondaytime = DATEADD(week,DATEDIFF(week,0,@CurrentTime),0)
set @Sundaytime = DATEADD(week,DATEDIFF(week,0,@CurrentTime),6)
--建立一個臨時表,用於儲存是否為工作日資料
create table #T(DDay datetime,Whether int)
insert into #T(DDay,Whether)
--呼叫OAWorkTime儲存過程,獲取這周工作日為哪幾天
exec OAWorkTime @Mondaytime,@Sundaytime
delete from #T where Whether <> 0
--申明一個表變數用於存使用者請假資訊
declare @Temp table
(
ID varchar(60),
vastartdate datetime,
vaenddate datetime,
numday decimal(4,1)
);
--將此使用者的所有請假資訊插入到表變數中
insert into @Temp(ID,vastartdate,vaenddate,numday)
select
b.field0023,b.field0025,b.field0026,b.field0027
from
formmain_6113 a,formson_6116 b
where a.ID=b.formmain_id
and dbo.getName(a.field0001)= @UserNames
--申明一個表變數為總表用於後續可以遍歷
declare @CountTemp table
(
IID int identity(1,1),
ID varchar(60),
vastartdate datetime,
vaenddate datetime,
numday decimal(4,1),
DDay datetime,
Whether int
);
--將請假資訊、工作日資訊做錶鏈接放在同一張表上
insert into @CountTemp(ID,vastartdate,vaenddate,numday,DDay,Whether)
select
a.ID,a.vastartdate,a.vaenddate,a.numday,b.DDay,b.Whether
FROM
@Temp as a,#T as b
--定義總表中的每個欄位
declare
@IID int, --唯一值
@ID varchar(60),
@vastartdate datetime,
@vaenddate datetime,
@numday decimal(4,1),
@DDay datetime,
@Whether int;
--定義之後判斷請假中小時使用
DECLARE @vastartdate11 DATETIME;
DECLARE @vaenddate11 DATETIME;
WHILE exists (select IID from @CountTemp)
BEGIN
set rowcount 1
--將第一行的資料賦值給@變數中
select
@IID=IID,@ID=ID,@vastartdate=vastartdate,@vaenddate=vaenddate,@numday=numday,
@DDay=DDay,@Whether=Whether
from
@CountTemp;
set @vastartdate11 = @vastartdate
set @vaenddate11 = @vaenddate
set @DDay = convert(date,convert(varchar(60),@DDay,111))
set @vastartdate = convert(date,convert(varchar(60),@vastartdate,111))
set @vaenddate = convert(date,convert(varchar(60),@vaenddate,111))
--刪除掉總表中當前工作日不在請假日期範圍內部的值
delete from @CountTemp where @DDay NOT BETWEEN @vastartdate AND @vaenddate
--請假的幾種情況
--1、請假開始時間、結束時間都在當天工作日
if @DDay = @vastartdate and @DDay = @vaenddate
begin
set @LeaveDay = @LeaveDay + @numday
end
--2、請假開始時間是今天工作日,結束時間在後邊
if @DDay = @vastartdate and @DDay < @vaenddate
begin
if DATEPART(hh,@vastartdate11) < 12
begin
set @LeaveDay = @LeaveDay + 1
end
else
begin
set @LeaveDay = @LeaveDay + 0.5
end
end
--3、請假開始時間在之前,結束時間在今天工作日
if @DDay > @vastartdate and @DDay = @vaenddate
begin
if DATEPART(hh,@vaenddate11)< 15
begin
set @LeaveDay = @LeaveDay + 0.5
end
else
begin
set @LeaveDay = @LeaveDay + 1
end
end
--4、請假時間在之後,結束時間在之前,在中間
if @DDay > @vastartdate and @DDay < @vaenddate
begin
set @LeaveDay = @LeaveDay + 1
end
set rowcount 0
delete from @CountTemp where [email protected]
END
--待不使用了之後刪除臨時表資料並刪除臨時表
truncate table #T
drop table #T
BEGIN
select @LeaveDay AS 請假天數
END
END
END
--execute LeaveTimes '俞豔','2018-01-19 13:30'
--execute LeaveTimes '尹欣瑋','2018-05-16 09:30'
--DROP PROCEDURE LeaveTimes
SQL程式碼(2):是否有別的方法實現下面的效果呢?
--此為迴圈使用者請假資訊
while exists(select ID from @Temp)
-- 開始遍歷請假每行資料
begin
set rowcount 1
-- 將第一行的資料賦值給@變數中
select @ID=ID,@vastartdate=vastartdate,@vaenddate=vaenddate,@numday=numday from @Temp;
select @ID,@vastartdate,@vaenddate,@numday from @Temp
if exists(select ID from @Temp)
BEGIN
--此為是否為工作日遍歷
while exists(select DDay from #T)
BEGIN
SET rowcount 1
select @DDay =DDay,@Whether=Whether from #T;
select @DDay,@Whether FROM #T
--請假的無種情況
--1、請假開始時間、結束時間都在當天工作日
if @DDay = @vastartdate and @DDay = @vaenddate
begin
set @LeaveDay = @LeaveDay + @numday
end
--2、請假開始時間是今天工作日,結束時間在後邊
if @DDay = @vastartdate and @DDay <= @vaenddate
begin
if DATEPART(hh,@DDay) < 12
begin
set @LeaveDay = @LeaveDay + 1
end
else
begin
set @LeaveDay = @LeaveDay + 0.5
end
end
--3、請假開始時間在之前,結束時間在今天工作日
if @DDay > @vastartdate and @DDay = @vaenddate
begin
if DATEPART(hh,@DDay)< 15
begin
set @LeaveDay = @LeaveDay + 1
end
else
begin
set @LeaveDay = @LeaveDay + 0.5
end
end
--4、請假時間在之後,結束時間在之前,在中間
if @DDay < @vastartdate and @DDay > @vaenddate
begin
set @LeaveDay = @LeaveDay + 1
end
set rowcount 0
delete from #T where [email protected]
END
END