我有一个带有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
之外,没有其他解决方案。
答案 0 :(得分:2)
该要求在技术上不可能在存储过程中处理。
存储过程中的DateTime
参数将始终包含一个时间方面,该方面要么显式地传递给它,要么默认为传入日期的午夜。无法知道调用方是否在时间方面显式传递。
您有2个选择:
varchar
,并让存储过程将其解析为DateTime
并处理验证。答案 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';
答案 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'