Sql server 2008 在多个处理器上运行时,这个简单的T-SQL更新会失败吗?

Sql server 2008 在多个处理器上运行时,这个简单的T-SQL更新会失败吗?,sql-server-2008,tsql,Sql Server 2008,Tsql,假设MBR_DTH_DT的所有值都计算为除值“00000000”之外的日期数据类型,那么如果强制转换是在运行线程的筛选器之前执行的,那么在多个处理器上运行时,以下更新SQL会失败吗 UPDATE a SET a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date) FROM [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a WHERE a.[MBR_DTH_DT] <> '00000000' 这可能是另一个更新

假设MBR_DTH_DT的所有值都计算为除值“00000000”之外的日期数据类型,那么如果强制转换是在运行线程的筛选器之前执行的,那么在多个处理器上运行时,以下更新SQL会失败吗

UPDATE  a
SET     a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date)
FROM    [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a
WHERE   a.[MBR_DTH_DT] <> '00000000'

这可能是另一个更新或插入查询,但所讨论的OTEHR似乎有我所看到的ProePry类型的数据,所以我只剩下上面的内容了。

不,听起来就像MBR\u DTH\u DT列中有坏数据,这是VARCHAR,但一旦清除坏数据,应该是一个日期

您可以使用以下方法标识这些行:

SELECT MBR_DTH_DT 
  FROM dbo.IPDP_MEMBER_DEMOGRAPHIC_DECBR
  WHERE ISDATE(MBR_DTH_DT) = 0;
现在,您可能只会得到恰好与用于筛选的where子句匹配的行,例如MBR_DTH_DT='00000000'

这与多处理器、竞争条件等无关。只是SQL Server可以在应用筛选器之前尝试执行强制转换

Randy建议添加一个附加子句,但这还不够,因为强制转换仍然可以在任何/所有筛选器之前进行。您通常通过这样的方式来解决这个问题,尽管在您的情况下,当所有内容都是同一列时,这是毫无意义的:

UPDATE dbo.IPDP_MEMBER_DEMOGRAPHIC_DECBR
  SET MBR_DTH_DT = CASE 
    WHEN ISDATE(MBR_DTH_DT) = 1 THEN CAST(MBR_DTH_DT AS DATE) 
    ELSE MBR_DTH_DT END
  WHERE MBR_DTH_DT <> '00000000';
我不知道为什么在这个问题中,您要使用updatealias FROM table作为别名语法;对于单表更新,这只会使语法更加复杂

然而,在这种情况下,这对你绝对没有好处;因为目标列是一个字符串,所以您只是尝试将字符串转换为日期,然后再转换回字符串


真正的解决方案是:停止使用字符串来存储日期,并停止使用像“00000000”这样的令牌字符串来表示日期不可用。要么为日期使用维度表,要么就直接使用NULL。

不太可能。即使使用多个处理器,也不能保证查询将并行处理

假设您使用的是SQL Server 2012,为什么不尝试类似的方法呢。即使您不是,您也可以编写一个UDF来验证这样的日期

UPDATE  a
SET     a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date)
FROM    [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a
WHERE   a.[MBR_DTH_DT] <> '00000000' And IsDate(MBR_DTH_DT) = 1
最有可能的情况是,您没有意识到有坏数据


哎呀,刚刚检查过。IsDate从SQL 2005开始提供。因此,请尝试使用它。

这没有帮助,因为在筛选器消除任何可能导致转换失败的行之前,仍可以尝试转换。在什么情况下,SQL Server会尝试将该值转换为一个日期,然后再确定该行满足where子句?极端地说,如果表有一百万行,而只有10行满足Where子句,SQL Server可以尝试将所有一百万个值强制转换到一个日期,然后再找到满足查询的10行,这当然是非常低效的。是的,这是可能的,而且在很多情况下都会发生。我可能已经回答了十几个这样的问题,这就是发生的事情。当然,你不会认为我只是为了好玩而编造的吧?我甚至会加倍提供:这里还有一个非常简单的复制-它使用一个CTE来证明你不能总是控制过滤器和表达式的顺序,比如CONVERT:这对我来说毫无意义。即使字符串[MBR_DTH_DT]是有效的日期,也不能将日期放入字符串字符列中。在集合的两侧都有相同的列。更正它将尝试隐式转换回字符。此问题似乎脱离主题,因为它缺少足够的信息来诊断问题。我同意将varchar col强制转换为日期并将其分配回自身不是一项有效的任务,但这是我在生产中发现的,我需要确定问题的原因是否是这个SQL。我认为问题的核心是正确的:强制转换是否会失败,因为它是在被过滤掉之前应用于某个记录的。我相信Aaron和其他帖子以及我的经验都告诉我,是的,事实就是这样。感谢所有的回答,即使是那些不喜欢答案的愤怒的人。事实上,SQL Server可以出于各种原因,在大量不同的场景中,尝试在筛选之前执行更新。在您的情况下,似乎删除并行性可能是答案,但我可以向您保证,如果您希望在未来的所有场景中,无论有无提示,都不受此场景的影响,您应该使用case表达式,正如我在回答中所演示的那样。大小写是确保仅对满足条件ISDATE=1的值尝试转换的唯一方法。@ChadD FORCE ORDER与SELECT子句中表达式之前是否处理WHERE无关。这与连接处理有关。From:指定在查询优化期间保留查询语法指示的联接顺序。使用强制顺序不会影响查询优化器可能的角色反转行为。请不要做出假设,然后根据猜测和向墙上扔飞镖发布被接受的答案。Re:你只是在尝试 正在初始化以将字符串转换为日期并再次转换回字符串。天啊。你说得对。我没有意识到源列和目标列是相同的。那太可怕了。这是早已过时的开发人员编写的生产代码。我完全同意预先使用适当的数据类型。
UPDATE  a
SET     a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date)
FROM    [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a
WHERE   a.[MBR_DTH_DT] <> '00000000' And IsDate(MBR_DTH_DT) = 1