在where子句中连接Time和DateTime

时间:2016-09-14 15:18:36

标签: sql-server sql-server-2008

我正在尝试将SmallDateTime字段和Time值(标量值函数的结果)合并到DateTime中,并且我不断收到以下错误:

  

从字符转换日期和/或时间时转换失败   字符串。

以下是整个过程中使用的变量:

DECLARE @STARTDATETIME AS DATETIME
DECLARE @ENDDATETIME AS DATETIME
SELECT @STARTDATETIME = '8/29/2016 12:00:00'
SELECT @ENDDATETIME = '8/30/2016 12:00:00'

列定义:

FT_START_DATE   SmallDateTime
FT_END_DATE     SmallDateTime
FT_START_TIME   Int
FT_END_TIME     Int

日期字段不包含时间戳。时间字段基本上是24小时时间而没有冒号分隔符。 (例如:142350 = 14:23:50)

这是我的查询中调用的函数:

USE [PWIN171]
GO
/****** Object:  UserDefinedFunction [dbo].[dbo.IPC_Convert_Time]    Script Date: 9/13/2016 4:50:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[dbo.IPC_Convert_Time] 
(
    @time int
)
RETURNS time
AS
BEGIN
    DECLARE @Result time
    SELECT @Result = CONVERT(time
                            , STUFF(
                                STUFF(
                                    RIGHT('000000' + CONVERT(varchar(6), @time), 6) 
                                , 5, 0, ':')
                            , 3, 0, ':')
                        )
    RETURN @Result
END

示例1 - 失败:

这就是我一般的追求。

SELECT * FROM FT WITH (NOLOCK)
WHERE
CAST(FT_END_DATE AS DATETIME) + DBO.[dbo.IPC_Convert_Time](FT_END_TIME) BETWEEN @STARTDATETIME AND @ENDDATETIME;

示例2 - 作品:

这个运行,但它不会从8/29获得记录,因为结束日期将在8月29日的12:00:00之前。

SELECT * FROM FT WITH (NOLOCK)
WHERE
FT_END_DATE BETWEEN @STARTDATETIME AND @ENDDATETIME
AND CAST(FT_END_DATE AS DATETIME) + DBO.[dbo.IPC_Convert_Time](FT_END_TIME) BETWEEN @STARTDATETIME AND @ENDDATETIME;

我想我可以做一个我分开我的参数并检查结束时间是否在参数的时间部分之间,但这似乎是错误方向的一步。只有在where子句中没有使用FT_START_DATEFT_END_DATE时才会出现错误。

时间转换功能在我创建的每个场景中都能正常工作。我甚至尝试过使用参数的示例2,如果有错误的数据导致错误,它会使示例1所涵盖的数据100%重叠,但运行正常。

我也不确切知道错误发生的位置,因为它只引用select语句开头的行,而不是代码中的实际位置。

为什么它会像这样?

UPDATE:

TIMEFROMPARTS不可用,因为它位于SQL Server 2008上

1 个答案:

答案 0 :(得分:2)

如果我理解这一点,可以做得更简单:

试试这个:

DECLARE @d DATE=GETDATE();
DECLARE @t TIME=GETDATE();
SELECT @d;
SELECT @t;
SELECT CAST(@d AS datetime)+CAST(@t AS datetime);

可以简单地添加日期和时间来组合它们......

更新再次阅读您的问题......

试试这个

SELECT FT_END_DATE
      ,FT_END_TIME 
      ,CAST(FT_END_DATE AS DATETIME) + DBO.[dbo.IPC_Convert_Time](FT_END_TIME) AS CombinedTime
      ,* 
FROM FT

看看你的尝试是否正确。

如果是,可能有助于创建CTE并对命名列执行过滤。

有时,引擎无法按照您期望的顺序运行

由于CTE完全内联,很有可能,这无济于事......

SQL Server很可能会出现这样的错误,因为类型检查会在发生转换之前发生......

使用带有INTO #tbl的给定SELECT将结果集推送到新表并从那里执行逻辑可能是一个想法......