在查询中使用 TOP 1 时出现问题

发布于 2024-09-17 17:31:53 字数 471 浏览 2 评论 0原文

我编写了以下查询来获取日期,删除它的时间部分并添加我想要的时间。 如果我在没有 TOP 子句的情况下运行此查询,则效果很好。但是当我添加它时,它返回以下异常:“从字符串转换日期和/或时间时转换失败。”

以下是查询:

SELECT TOP 1 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 
Where VRSAS.EventOn <= '2010-07-31' 
AND VRSAS.[Status] = 1
 order by VRSAS.RangeSheet

字段 EventOn 的类型为 DateTime。

可能发生什么事?

I wrote the following query to obtain a date, remove it's time part and add the time I wanted.
If I run this query without the TOP clause, it works well. But when I add it, it returns the following exception: "Conversion failed when converting date and/or time from character string."

Here is the query:

SELECT TOP 1 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 
Where VRSAS.EventOn <= '2010-07-31' 
AND VRSAS.[Status] = 1
 order by VRSAS.RangeSheet

The field EventOn is of type DateTime.

What could be going on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜还是长夜 2024-09-24 17:31:53

我很容易地重现了这一点。我发现使用 DATEADD 解决了它,

DATEADD(MINUTE, 23*60 + 30, CONVERT(DATETIME,CONVERT(DATE, VRSAS.EventOn)))

但我实际上还不确定为什么。重现步骤如下。

CREATE TABLE ViewRangeSheetActualStatus
(EventOn DATETIME,
[Status] BIT,
RangeSheet INT
)

INSERT INTO [dbo].[ViewRangeSheetActualStatus]([EventOn], [Status], [RangeSheet])
SELECT '20100903 11:02:39.517', 1, 1 UNION ALL
SELECT '20100731 11:03:23.577', 1, 1 UNION ALL
SELECT '20100731 00:00:00.000', 1, 1

/*Selects ALL records - No error*/
SELECT 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

/*Selects top (1) record - Error!*/   
SELECT top (1)
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

查看执行计划中的ComputeScalar属性,两者是不同的。

All

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),0)+[@1])+CONVERT(varchar(50),CONVERT(time(7), 
 [@2],0),0),0))

Top 1

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),121)+' ')+'23:30:00.0000000',0))

在最终转换为 datetime 之前,第一个版本生成一个包含以下内容的 varchar

------------------------------
Sep  3 2010 11:30PM
Jul 31 2010 11:30PM
Jul 31 2010 11:30PM

第二个版本生成一个包含以下内容的 varchar

------------------------------
2010-09-03 23:30:00.0000000

它是 < code>.0000000 会导致转换回 datetime 的问题。我不知道为什么在查询中添加 TOP 会导致这种完全不相关的行为变化。

I've reproduced quite easily this end. I found using DATEADD resolved it

DATEADD(MINUTE, 23*60 + 30, CONVERT(DATETIME,CONVERT(DATE, VRSAS.EventOn)))

But I'm not actually sure why yet. Steps to reproduce below.

CREATE TABLE ViewRangeSheetActualStatus
(EventOn DATETIME,
[Status] BIT,
RangeSheet INT
)

INSERT INTO [dbo].[ViewRangeSheetActualStatus]([EventOn], [Status], [RangeSheet])
SELECT '20100903 11:02:39.517', 1, 1 UNION ALL
SELECT '20100731 11:03:23.577', 1, 1 UNION ALL
SELECT '20100731 00:00:00.000', 1, 1

/*Selects ALL records - No error*/
SELECT 
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

/*Selects top (1) record - Error!*/   
SELECT top (1)
CONVERT(DateTime, (CONVERT(varchar(50),CONVERT(Date, VRSAS.EventOn)) 
+ ' ' + 
CONVERT(varchar(50), CONVERT(Time, '23:30')))) E 
FROM ViewRangeSheetActualStatus VRSAS 

Looking at the ComputeScalar properties in the execution plan the two are different.

All

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),0)+[@1])+CONVERT(varchar(50),CONVERT(time(7), 
 [@2],0),0),0))

Top 1

(CONVERT(datetime,(CONVERT(varchar(50),CONVERT(date,[ViewRangeSheetActualStatus].
 [EventOn] as [VRSAS].[EventOn],0),121)+' ')+'23:30:00.0000000',0))

Before the final conversion to datetime the first one produces a varchar containing the following

------------------------------
Sep  3 2010 11:30PM
Jul 31 2010 11:30PM
Jul 31 2010 11:30PM

The second version produces a varchar containing

------------------------------
2010-09-03 23:30:00.0000000

It is the .0000000 that causes the problem casting back to datetime. I have no idea why the addition of TOP to the query would cause this completely unrelated change in behaviour.

小帐篷 2024-09-24 17:31:53

一个奇怪的问题,你有没有验证过它确实可以在没有“top one”限制的情况下工作?有时,“最上面的一个”只会使错误更加明显。如果您有很多很多行,并且删除了“top one”限制,则查询可能会给人一种工作正常的印象,但在后台,它仍在假脱机结果,并且没有到达导致问题的行。

EventOn 是否不可为空,这可能是主要原因。如果是这样,请首先进行非空检查。

另外,“RangeSheet”类型是什么,它是什么数据类型,可以保存空值吗?

A strange one, have you verified that it really does work with out the "top one" restriction? Sometimes the "top one" just makes the error more visible. If you have many, many rows and you remove the "top one" restriction, the query may give the impression of working, but in the background its still spooling the results and hasn't hit the line that causes the problem.

Is EventOn non-nullable, that could be a prime reason. If so, put a non null check first.

Also, what is the type "RangeSheet", what data type is it and can that hold nulls?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文