希望您能帮助我找到答案,我会解释我的问题。
我正在使用SQL Server 2005中的生物特征标记设备数据库,实际上我正在开发额外的计算时间软件,因此我正在使用2个不同的数据库(mine和生物特征设备数据库)。
我正在尝试计算两个日期之间的小时差,这将是员工使用DATEDIFF
在1天之内的2个标记记录,我想将其保存为小数,例如1.5小时,这种方式以后我将能够求和并获得准确的数据。
我正在尝试使用触发器和存储过程来实现这一目标,每插入1条新标记记录,触发器就会执行一次。
触发器唯一要做的就是执行我的存储过程,这时一切正常,唯一的问题是我将DATEDIFF
函数转换为十进制。
这是我的触发器:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tri_marcas_ins]
ON [dbo].[Marcas]
AFTER INSERT
AS
DECLARE @codigo VARCHAR(10);
DECLARE @fecha DATETIME;
SELECT @codigo = i.Codigo
FROM inserted i;
SELECT @fecha = i.Fecha
FROM inserted i;
BEGIN
EXEC dbHorasExtra.dbo.calculohoras @fecha,@codigo;
END
这是我的存储过程脚本代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[calculohoras]
@fecha DATETIME,
@codigo VARCHAR(10)
AS
BEGIN
DECLARE @fechainicial DATETIME;
DECLARE @fechafinal DATETIME;
DECLARE @horas DECIMAL(6,2);
DECLARE @createdat VARCHAR(255);
DECLARE @updatedat VARCHAR(255);
DECLARE @codigoemp VARCHAR(255);
BEGIN
SET @codigoemp = (SELECT id
FROM nempleados
WHERE codempleado = @codigo)
END
SELECT fecha
FROM Reloj_3216R.[dbo].Marcas
WHERE Codigo = @codigo
AND DATEPART(YEAR, fecha) = DATEPART(YEAR, @fecha)
AND DATEPART(MONTH, fecha) = DATEPART(MONTH, @fecha)
AND DATEPART(DAY, fecha) = DATEPART(DAY, @fecha);
IF @@ROWCOUNT >= 1
BEGIN
SET @fechainicial = (SELECT MIN(fecha)
FROM Reloj_3216R.[dbo].Marcas
WHERE Codigo = @codigo
AND DATEPART(YEAR, fecha) = DATEPART(YEAR, @fecha)
AND DATEPART(MONTH, fecha) = DATEPART(MONTH, @fecha)
AND DATEPART(DAY, fecha) = DATEPART(DAY, @fecha)
)
SET @fechafinal = (SELECT MAX(fecha)
FROM Reloj_3216R.[dbo].Marcas
WHERE Codigo = @codigo
AND DATEPART(YEAR, fecha) = DATEPART(YEAR, @fecha)
AND DATEPART(MONTH, fecha) = DATEPART(MONTH, @fecha)
AND DATEPART(DAY, fecha) = DATEPART(DAY, @fecha)
)
END
ELSE
RETURN
SELECT *
FROM horas
WHERE codempleado = @codigo
AND DATEPART(YEAR, fecha) = DATEPART(YEAR, @fecha)
AND DATEPART(MONTH, fecha) = DATEPART(MONTH, @fecha)
AND DATEPART(DAY, fecha) = DATEPART(DAY, @fecha)
IF @@ROWCOUNT > 0
RETURN
ELSE
BEGIN
SET @updatedat = GETDATE();
SET @createdat = GETDATE();
SET @horas =
(
DATEDIFF(MINUTE,@fechafinal, @fechainicial)/60
)
--INSERT INTO horas (codempleado,fecha,horas,created_at,updated_at) VALUES(@codigoemp,@fechafinal,@horas,@createdat,@updatedat);
END
END
对不起,如果我没有正确询问,我会提供您询问的任何信息!泰语为您提供帮助!
更新: @horas十进制(2,2)更改为@horas十进制(6,2),解决了该问题!非常感谢!
答案 0 :(得分:0)
正如您已经了解的那样,触发器一定不能只期待一条新记录。要为每个新记录执行存储过程,您将必须使用如下游标:
ALTER TRIGGER [dbo].[tri_marcas_ins]
ON [dbo].[Marcas]
AFTER INSERT
AS
BEGIN
DECLARE @codigo VARCHAR(10);
DECLARE @fecha DATETIME;
DECLARE insertedcur CURSOR FAST_FORWARD FOR
SELECT Codigo, Fecha FROM inserted;
OPEN insertedcur;
FETCH NEXT FROM insertedcur INTO @codigo, @fecha;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC dbHorasExtra.dbo.calculohoras @fecha,@codigo;
FETCH NEXT FROM insertedcur INTO @codigo, @fecha;
END
CLOSE insertedcur;
DEALLOCATE insertedcur;
END
可以稍微简化您的存储过程,但是即使将@horas
变量更改为decimal(6,2)
,结果也将始终是整数,因为DATEDIFF
返回一个整数,而{{ 1}}也是一个整数。要解决此问题,请除以60
。您的过程可能如下所示:
60.0
答案 1 :(得分:0)
我将按照OP的建议将评论发布为答案
尝试declare @horas decimal(6,2);
您使用declare @horas decimal(2,2);
只能从0.00到0.99 – Horaciux 2小时前