Reputation: 668
I need help converting an integer
to a varchar
.
I'm trying to write a procedure that takes in a ProfileID
and a Currenttime
; using those two values it finds the start time of the profileID
and subtracts currenttime
from
starttime
and returns hours:minutes:seconds
.
What am I doing wrong, is there a better way to write this?
Thanks.
CREATE PROCEDURE [dbo].[CalculateElaspedTime]
-- Add the parameters for the stored procedure here
@ProfileID nvarchar(10),
@CurrentDateTime datetime = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
if @CurrentDateTime = CAST('' as datetime)
set @CurrentDateTime = GETDATE()
DECLARE @StartTime datetime;
DECLARE @ElaspedTime time;
DECLARE @hh int;
DECLARE @mm int;
DECLARE @ss int;
Declare @TimeString varchar
set @StartTime = (Select top 1 [DateTime] From Log WHERE ProfileID = @ProfileID);
set @hh = DateDiff(hour,@StartTime,@CurrentDateTime);
set @mm = DateDiff(minute,@StartTime,@CurrentDateTime)-60*@hh;
set @ss = DateDiff(second,@StartTime,@CurrentDateTime)-60*@mm;
set @TimeString = (Select CAST(@hh as varchar)); -- Fails Here
set @ElaspedTime = convert(datetime, cast(@hh as varchar) + ':' + cast(@mm as varchar) + ':' + cast(@ss as varchar));
INSERT INTO Log (ElaspedTime) Values (@ElaspedTime);
END
Upvotes: 3
Views: 39566
Reputation: 2565
Try this. All of that excitement in the function may be unnecessary.
CONVERT(varchar(10),(@CurrentDateTime-@Start_Time),108)
Upvotes: 8
Reputation: 74187
One problem you have is this statement:
set @StartTime = (Select top 1 [DateTime] From Log WHERE ProfileID = @ProfileID);
Its results are indeterminate as SQL makes no guarantees about result order unless you explicitly specify it in an ORDER BY clause. You should be using ORDER BY or using an aggregate function like MAX() to get the row you want.
And you're doing a lot more work than necessary. SQL Server (recent versions, anyway) support date arithmetic, with the result of subtracting two dates being another date (offset from the SQL Server epoch of 1 Jan 1900 00:00:00.000. This simpler form ought to do you, unless the elapsed time will exceed 1 day:
create procedure dbo.CalculateElaspedTime
@ProfileID nvarchar(10) ,
@CurrentDateTime datetime = ''
as
set nocount on
declare
@now dateTime ,
@start datetime ,
@elapsed varchar(32)
select @now = case coalesce(@currentDateTime,'') when '' then current_timestamp else @currentDateTime end ,
@start = max( [DateTime] )
from dbo.Log
where ProfileId = @profileId
set @elapsed = convert(varchar,@now-@start,108)
insert dbo.Log ( ElapsedTime ) Values (@elapsed);
return 0
go
If your elapsed time might exceed one day, then your original approach is what you want:
create procedure dbo.CalculateElaspedTime
@ProfileID nvarchar(10) ,
@CurrentDateTime datetime = ''
as
set nocount on
declare @now dateTime = case coalesce(@currentDateTime,'') when '' then current_timestamp else @currentDateTime end ,
declare @start datetime = ( select max([DateTime]) from dbo.Log where profileId = @profileId )
declare @elapsed int = select datediff(ss,@now,@start)
declare
@hh int ,
@mm int ,
@ss int
set @hh = @elapsed / 3600 -- 3600 is seconds/hour
set @elapsed = @elapsed % 3600
set @mm = @elapsed / 60 -- 60 is seconds/minute
set @elapsed = @elapsed % 60
set @ss = @elapsed / 1 -- 1 is seconds/second :)
declare @hhmmss = right('00'+convert(varchar,@hh),2)
+ ':' + right('00'+convert(varchar,@mm),2)
+ ':' + right('00'+convert(varchar,@ss),2)
insert dbo.Log ( ElapsedTime ) Values (@hhmmss);
return 0
go
Upvotes: 1