如何验证DateTime是否包含SQL Server中的时间

时间:2019-03-14 16:42:41

标签: sql sql-server tsql sql-server-2012

我有一个带有datetime参数的存储过程。我需要确定给定的datetime参数是否包含时间。

现在,DATEPART(hour, @datetimeValue) = 0在我的情况下不起作用,因为可以将日期时间设置为3/14/2019 0:00,表示上午12点且有效。

如果输入为,则返回true

'3/14/2019 0:00'
'3/14/2019 15:00'

仅当输入没有时间时才返回false:

'3/14/2019'

感谢大家的投入。看起来除了将存储过程参数更改为varchar之外,没有其他解决方案。

7 个答案:

答案 0 :(得分:2)

该要求在技术上不可能在存储过程中处理。

存储过程中的DateTime参数将始终包含一个时间方面,该方面要么显式地传递给它,要么默认为传入日期的午夜。无法知道调用方是否在时间方面显式传递。

您有2个选择:

  1. 将参数的传入数据类型更改为varchar,并让存储过程将其解析为DateTime并处理验证。
  2. 让调用者处理所有与时间有关的验证,并将此要求从您的代码中删除。

答案 1 :(得分:1)

我唯一想到的解决方案是ALTER您的SP并使用两(2)个参数,一个是DATE,第二个是TIME数据类型,如下:

CREATE PROCEDURE HasTime(
    @MyDate DATE = NULL,
    @MyTime TIME = NULL
)
AS
BEGIN
    IF @MyTime IS NULL
        SELECT 'There is no time'
            ELSE
                SELECT 'There is time';
END;

EXEC dbo.HasTime '2019-01-01', NULL; --Or EXEC dbo.HasTime '2019-01-01';
EXEC dbo.HasTime '2019-01-01', '00:00:00';

Live Demo

答案 2 :(得分:1)

默认情况下,即使您不使用时间部分,DATETIME也会包含一个设置为午夜的时间(例如'00:00:00')。如果您的日期时间是字符串,则可以使用以下方法查看时间是否是字符串的一部分(尽管有点麻烦):

SELECT CASE WHEN CHARINDEX(':', '3/14/2019 0:00') > 0 THEN 1 ELSE 0 END   -- Returns 1
SELECT CASE WHEN CHARINDEX(':', '3/14/2019 15:00') > 0 THEN 1 ELSE 0 END  -- Returns 1
SELECT CASE WHEN CHARINDEX(':', '3/14/2019') > 0 THEN 1 ELSE 0 END        -- Returns 0

基本上,它只是搜索字符串并查看字符串中是否包含冒号。不过,它符合您的条件。

答案 3 :(得分:1)

这很粗糙,但是可以满足您的需求。如果将其丢弃,例如部分导入,则可能足以满足您的需求。

我确信可以通过更多地了解如何从SQL中检索当前执行的PROC的细节来改进此方法,我快速了解了如何使用query plans

如果时间是午夜,您可能会失败回到此检查,这会使其更有效率

ALTER PROCEDURE Hastime(@d AS DATETIME) 
AS 
  BEGIN

      -- Is there a easier way to get from DBCC INPUTBUFFER to a SQL variable? 
      CREATE TABLE #temp 
        ( 
           spid       INT, 
           eventtype  NVARCHAR(30), 
           parameters INT, 
           eventinfo  NVARCHAR(4000) 
        )     
      INSERT INTO #temp 
                  (eventtype, 
                   parameters, 
                   eventinfo) 

      EXEC ('DBCC INPUTBUFFER(' + @@spid +') WITH NO_INFOMSGS') 

      -- Yes, we could do this better
      IF EXISTS (SELECT * 
                 FROM   #temp 
                 WHERE  eventinfo LIKE '%:%') 
        SELECT 'Time' 
      ELSE 
        SELECT 'No Time' 
  END     
go     
EXEC dbo.Hastime 
  '2000/06/01' 

go     
EXEC dbo.Hastime 
  '2000/06/01 00:00:00' 

答案 4 :(得分:0)

您可以像这样进行检查,但是如果时间实际上是午夜,则它将返回无效时间:

-- returns 'NOTime'
SELECT CASE WHEN CAST('1/1/2019' AS TIME) = '00:00:00.000' THEN 'NOTime' ELSE 'TIME' END

-- returns 'TIME'
SELECT CASE WHEN CAST(GetDate() AS TIME) = '00:00:00.000' THEN 'NOTime' ELSE 'TIME' END

答案 5 :(得分:0)

我会投射为date

select (case when convert(date, @datetimeValue) = @datetimeValue then 'NoTime'
             else 'HasTime'
        end)

答案 6 :(得分:0)

唯一的方法是将varchar类型传递给过程,而不是datetime 否则我们无法区分没有时间的日期和午夜的日期 在这里您可以检查此限制 以下脚本说明了该限制:

declare @d as datetime
declare @d1 as datetime

set @d='01/01/2019'
set @d1='01/01/2019 00:00:00:00'

if @d=@d1 print 'equal' else print 'not equal'