当不应该进行转换时 SQL 日期时间转换失败

2024-02-02

我正在修改客户的现有查询,并且遇到了一个有点令人困惑的问题。

我们的客户使用 SQL Server 2008 R2,并且相关数据库使用户能够通过使用 EAV 结构为其表之一指定自定义字段。该结构中存储的所有值都是varchar(255),其中几个字段用于存储日期。正在修改有问题的查询以使用其中两个字段,并将它们(一个是开始,另一个是结束)与当前日期进行比较,以确定哪一行是“当前”。

我遇到的问题是查询的一部分执行了CONVERT(DateTime, eav.Value)为了转动varchar into a DateTime。转换本身全部成功,我可以将该值包含在SELECT子句,但问题的一部分给了我一个转换错误:

Conversion failed when converting date and/or time from character string.

真正的问题是:如果我定义此查询的基础(获取两个自定义字段值平铺到单行中的实体列表)作为视图,然后针对该视图进行选择并按以下条件过滤视图getdate(),那么它可以正常工作,但如果我使用视图中的(非日期)字段之一将联接添加到第二个表,则会失败。我意识到这可能有点难以理解,因此如果需要,我可以发布一个示例查询,但这个问题已经有点长了。

我尝试在另一个数据库中重新创建基本结构并包含示例数据,但新数据库的行为符合预期,所以我在这里不知所措。

EDIT如果它有用,这里是视图的声明:

create view Festival as 
select
    e.EntityId as FestivalId,
    e.LookupAs as FestivalName,
    convert(Date, nvs.Value) as ActivityStart,
    convert(Date, nve.Value) as ActivityEnd

from tblEntity e

left join CustomControl ccs on ccs.ShortName = 'Activity Start Date'
left join CustomControl cce on cce.ShortName = 'Activity End Date'
left join tblEntityNameValue nvs on nvs.CustomControlId = ccs.IdCustomControl and nvs.EntityId = e.EntityId
left join tblEntityNameValue nve on nve.CustomControlId = cce.IdCustomControl and nve.EntityId = e.EntityId

where e.EntityType = 'Festival'

失败的查询是这样的:

select * 

from Festival f

join FestivalAttendeeAll fa on fa.FestivalId = f.FestivalId

where getdate() between f.ActivityStart and f.ActivityEnd

但这有效:

select * 

from Festival f

where getdate() between f.ActivityStart and f.ActivityEnd

(EntityId/FestivalId是 int 列)


我以前遇到过这种类型的错误,这是由于执行计划执行的“操作顺序”造成的。

您收到该错误消息是因为语句的执行计划(由优化器生成)正在对包含无法转换为 DATETIME 的字符串值的行执行 CONVERT() 操作。

基本上,您无法控制优化器对哪些行执行转换。您知道您只需要对某些行进行转换,并且您有排除这些行的谓词(WHERE 或 ON 子句)(将这些行限制为需要转换的行),但您的执行计划正在执行 CONVERT() 操作在排除这些行之前的行。

(例如,优化器可能会选择进行表扫描,并在应用任何谓词之前对每一行执行该转换。)

如果没有具体问题和生成错误的具体 SQL,我无法给出具体答案。


解决该问题的一种简单方法是使用 ISDATE() 函数来测试字符串值是否可以转换为日期。

即替换:

CONVERT(DATETIME,eav.Value)

with:

CASE WHEN ISDATE(eav.Value) > 0 THEN CONVERT(DATETIME, eav.Value) ELSE NULL END

or:

CONVERT(DATETIME, CASE WHEN ISDATE(eav.Value) > 0 THEN eav.Value ELSE NULL END)

请注意,ISDATE() 函数受到一些重大限制,例如受会话的 DATEFORMAT 和 LANGUAGE 设置的影响。


如果 eav 行上有其他指示,您可以使用其他测试来有条件地执行转换。

CASE WHEN eav.ValueIsDateTime=1 THEN CONVERT(DATETIME, eav.Value) ELSE NULL END

我使用的另一种方法是尝试使用内联视图或公共表表达式来尝试对优化器的操作顺序进行一定程度的控制,并使用强制优化器具体化它们并应用谓词的操作,以便在之前发生这种情况外部查询中的任何转换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当不应该进行转换时 SQL 日期时间转换失败 的相关文章

  • T-SQL Cross Join 获取缺失值

    这是我的问题的一个简单例子 我有一个创建报告的存储过程 DECLARE Report TABLE Product VARCHAR 10 Purchases MONEY default 0 DECLARE Range TABLE minP M
  • 从日期时间中获取时间并将其转换为秒?

    我正在运行 SQL Server 2005 从技术上讲 我知道如何从 tsql 日期时间中获取时间 CONVERT VARCHAR 8 GETDATE 108 AS HourMinuteSecond 问题是我有一个日期时间字段 我需要本质上
  • 使用 IF..ELSE IF 控制 T-SQL SP 中的流程 - 还有其他方法吗?

    我需要将我的 T SQL 存储过程 MS SQL 2008 控制流分支到多个方向 CREATE PROCEDURE fooBar inputParam INT AS BEGIN IF inputParam 1 BEGIN END ELSE
  • 将查询结果即时导出到文件

    我需要将查询结果导出到 csv 文件并将该文件放在网络共享文件夹中 是否可以在存储过程中实现此目的 如果是 则会出现另一个限制 我可以在没有系统管理员权限的情况下实现此目的 也就是不使用 xp cmdshell BCP 实用程序吗 如果 2
  • 正则表达式 '?' 的类似物(前一项可选)在T-SQL中像什么?

    我想知道 是否可以翻译包含 的正则表达式 前面的项目可选 在 T SQL LIKE 模式中 DB 端无需任何操作 例如 31 4 我可以将其分成几个子句 但如果正则表达式包含很多 这不太方便 LIKE不使用正则表达式 并且它使用的模式语言没
  • 选择具有 SQL Server XML 列类型的特定行

    我正在尝试从类似于以下定义的表中选择数据 Column Data Type Id Int DataType Int LoggedData XML 但我只想选择具有特定 DataType 值并且在 LoggedData 列中包含字符串 或评估
  • 计算运行总计时出错(之前期间的累计)

    我有一张桌子 我们称之为My Table有一个Created日期时间列 在 SQL Server 中 我试图提取一个报告 该报告显示历史上有多少行My Table按月在特定时间 现在我知道我可以显示有多少added每个月 SELECT YE
  • SQL Server:从 OPENDATASOURCE 中删除

    这有效 SELECT FROM OPENDATASOURCE Microsoft ACE OLEDB 12 0 Data Source d JobFiles MyFile xlsx Extended properties Excel 8 0
  • 如何搜索例程的内容/(SP-触发函数)

    我需要在数据库内所有例程的例程主体 存储过程 函数 触发器 中搜索文本 我该怎么做 Thanks SELECT OBJECT NAME object id FROM sys sql modules WHERE definition LIKE
  • 在存储过程中验证用户的最简单方法?

    我需要一个存储过程 可以通过发送以下内容来检查登录尝试时他们是否是有效用户login and password查看它们在数据库中是否匹配 有没有一种简单的方法可以做到这一点 如果没有更多信息 我目前能提供的最好信息是 CREATE STOR
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • 解析带下划线的 SQL Server 数字文字

    我想知道它为什么有效以及为什么它不返回错误 SELECT 2015 11 Result 11 2015 第二种情况 SELECT 2 1 a a 2 1 检查元数据 SELECT name system type name FROM sys
  • 如何在 SQL Server 中连接

    我的数据库没有特定的列 因此我通过开关在查询中创建了一个列 我需要的是将此列与数据库中的另一列连接起来 select certificateDuration DurationType case when certificateDuratio
  • 在 SQL Server 2005/2008 中存储历史数据的最佳方式是什么?

    我的简化和人为的示例如下 假设我想每天测量和存储世界上所有城镇的温度 和其他值 我正在寻找一种存储数据的最佳方法 以便可以轻松获取所有城镇的当前温度 就像获取一个城镇历史上的所有温度一样 这是一个很容易解决的问题 但我正在寻找最好的解决方案
  • sql server 如果不存在则插入并获取插入的id到另一个表中

    我是 SQL Server 新手 正在开发一个记录日志的项目 该表有一个 URL 列 varchar max 它具有重复值 我创建了另一个表 它仅存储不同的 URL ID 存储在主表中 这是我执行此操作的存储过程 CREATE TABLE
  • 如何在 SQL 中刷新 PRINT 缓冲区?

    我在 SQL Server 2005 中有一个运行时间非常长的存储过程 我正在尝试调试它 并且我使用 print 命令来执行它 问题是 我只是在存储过程的最后从 SQL Server 获取消息 我希望能够刷新消息缓冲区并在存储过程的运行时立
  • SQL LIKE 运算符在应该显示任何结果时没有显示任何结果

    我有一个包含大量信息的车辆表 但其中一列是 MSSQL 表中的 所有者 但我使用时无法选择其中一个所有者LIKE但如果我可以使用 Silkeborg Distributionscenter 是所有者 是的 表和参数中都有一个双空格 所以参数
  • SQL:从单个查询列出多对多

    我有 3 个表 分别代表 Users Roles 和多对多 UsersInRoles 键为 UserId RoleId 相关列 用户名 角色名 在管理 html 应用程序中 我想显示所有用户及其所在角色的列表 我尝试从 SQL 构建一个将返
  • T-SQL 中的不等式测试

    我刚刚在 WHERE 子句中遇到了这个 AND NOT t id id 这与以下内容相比如何 AND t id id Or with AND t id lt gt id 我总是自己写后者 但显然其他人有不同的想法 其中一个的表现会比另一个更
  • 删除 SQL Server 上的所有扩展属性

    如何以可编写脚本的方式删除 SQL Server 上的所有扩展属性 如果您想要一个能够一次性删除所有扩展属性的脚本 请使用 Jamie Thomson 创建的脚本 该脚本将为所有扩展属性生成删除 您可以从这里下载article http s

随机推荐