2013-07-22 256 views
3

我需要幫助將integer轉換爲varcharSQL將int轉換爲varchar

我試圖寫一個程序,需要在ProfileIDCurrenttime;使用這兩個值可以找到profileID的開始時間,並從 starttime中減去currenttime,並返回hours:minutes:seconds

我在做什麼錯,有沒有更好的方法來寫這個?

謝謝。

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 
+0

有什麼錯誤信息 –

+0

什麼是@hh的價值在錯誤發生的地方?另外,你的邏輯ElapsedTime表明你不是指間隔 –

+0

@hh = 1.C的值從字符串轉換日期和/或時間時,反轉失敗。 – Pat

回答

8

試試這個。功能中的所有興奮可能是不必要的。你有

CONVERT(varchar(10),(@[email protected]_Time),108) 
+3

你應該**總是**爲你的'varchar'指定一個**長度**轉換爲它時。如果你忽略了長度,你知道默認值是什麼嗎? –

+1

非常真實。謝謝你的指針。 –

1

的一個問題是這樣的說法:

set @StartTime = (Select top 1 [DateTime] From Log WHERE ProfileID = @ProfileID); 

其結果是不確定的,因爲SQL使有關結果的順序,除非你明確地在ORDER BY子句指定它沒有保證。你應該使用ORDER BY或使用像MAX()這樣的集合函數來獲得你想要的行。

而且你正在做的工作比必要更多。 SQL Server(最新版本,無論如何)都支持日期算術,其結果是將兩個日期相減爲另一個日期(從1900年1月1日00:00:00:00開始的SQL Server時代的偏移量)。這種更簡單的形式應該適用於你,除非經過時間將超過1天:

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,@[email protected],108) 

    insert dbo.Log (ElapsedTime) Values (@elapsed); 

    return 0 
go 

如果你經過的時間可能超過一天,那麼你原來的做法是你想要什麼?

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