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

Cha*_*adD -4 t-sql sql-server-2008

假设MBR_DTH_DT的所有值都计算为值'00000000'以外的Date数据类型,如果在过滤器之前通过竞争线程执行CAST,则在多个处理器上运行时,以下UPDATE 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'
Run Code Online (Sandbox Code Playgroud)

我试图找到以下错误的来源

Error: 2014-01-30 04:42:47.67
   Code: 0xC002F210
   Source: Execute csp_load_ipdp_member_demographic Execute SQL Task
   Description: Executing the query "exec dbo.csp_load_ipdp_member_demographic" failed with the following error: "Conversion failed when converting date and/or time from character string.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
End Error
Run Code Online (Sandbox Code Playgroud)

它可能是另一个UPDATE或INSERT查询,但是所讨论的othrs似乎有从我看到的内容中输入的数据,所以我对上面的内容保持不变.

Aar*_*and 5

不,它只是听起来你在MBR_DTH_DT列中有坏数据,VARCHAR但这应该是一个日期(一旦你清除了坏数据).

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

SELECT MBR_DTH_DT 
  FROM dbo.IPDP_MEMBER_DEMOGRAPHIC_DECBR
  WHERE ISDATE(MBR_DTH_DT) = 0;
Run Code Online (Sandbox Code Playgroud)

现在,您可能只会获得恰好与您用于过滤的where子句相匹配的行(例如MBR_DTH_DT = '00000000').

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

兰迪建议添加一个附加条款,但这还不够,因为CAST它仍然可以在任何/所有过滤器之前发生.你通常会通过这样的方式解决这个问题(尽管在你的情况下,当一切都是同一列时,它完全没有意义):

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';
Run Code Online (Sandbox Code Playgroud)

(我不确定为什么在你使用UPDATE alias FROM table AS alias语法的问题中;使用单表更新,这只会使语法更复杂.)

但是,在这种情况下,这绝对没有好处; 由于目标列是一个字符串,您只是尝试将字符串转换为日期并再次转换回字符串.

真正的解决方案:停止使用字符串来存储日期,并停止使用令牌字符串'00000000'来表示日期不可用.您可以为您的日期使用维度表,也可以只使用维度表NULL.