SQL Server 2008 CAST('AS XML)在CASE语句中失败了吗?

时间:2017-09-19 14:21:12

标签: sql sql-server

我使用CAST来转换某些表列,因为我的列不同。例如,一列为VARCHAR(4),新表为integer。旧表中的数据将数字和字母连接在一起。例如100M或50NR或NR或105.所以我写了一个应该转换数据的T-SQL CASE语句。

以下是示例:

CASE
    WHEN CHARINDEX('M',LTRIM(RTRIM(hs_ptr1))) <> 0 
         AND LEN(REPLACE(LTRIM(RTRIM(hs_ptr1)),'M','')) <> 0 
       THEN REPLACE(LTRIM(RTRIM(hs_ptr1)),'M','')
    WHEN CHARINDEX('NR',LTRIM(RTRIM(hs_ptr1))) <> 0 
         AND LEN(REPLACE(LTRIM(RTRIM(hs_ptr1)),'NR','')) <> 0 
       THEN REPLACE(LTRIM(RTRIM(hs_ptr1)),'NR','') 
    WHEN PATINDEX('%[^0-9]%', LTRIM(RTRIM(hs_ptr1))) <> 0 
         OR LEN(LTRIM(RTRIM(hs_ptr1))) = 0 
       THEN NULL
    ELSE 
       CAST('' as xml).value('sql:column("hs_ptr1") cast as xs:integer ?', 'integer')
END AS hs_ptr1

我的代码因此错误而失败:

  

将varchar值'NR'转换为数据类型int时转换失败。

如果我将CAST代码行放在CASE语句之外,则转换中没有错误,但这样我会丢失一些值。我想知道为什么CASTCASE语句中失败了?我还能做些什么来解决这个问题吗?谢谢!

1 个答案:

答案 0 :(得分:2)

解决方案是将所有内容转换为varchar,如此

CASE
    WHEN CHARINDEX('M',LTRIM(RTRIM(hs_ptr1))) <> 0 
         AND LEN(REPLACE(LTRIM(RTRIM(hs_ptr1)),'M','')) <> 0 
       THEN REPLACE(LTRIM(RTRIM(hs_ptr1)),'M','')
    WHEN CHARINDEX('NR',LTRIM(RTRIM(hs_ptr1))) <> 0 
         AND LEN(REPLACE(LTRIM(RTRIM(hs_ptr1)),'NR','')) <> 0 
       THEN REPLACE(LTRIM(RTRIM(hs_ptr1)),'NR','') 
    WHEN PATINDEX('%[^0-9]%', LTRIM(RTRIM(hs_ptr1))) <> 0 
         OR LEN(LTRIM(RTRIM(hs_ptr1))) = 0 
       THEN NULL
    ELSE 
       cast(CAST('' as xml).value('sql:column("hs_ptr1") cast as xs:integer ?', 'integer') as varchar(10))
END AS hs_ptr1

看到结果后,你可能会知道为什么它不能成为integer