【问题标题】:Conversion Error in SQL Server - why?SQL Server 中的转换错误 - 为什么?
【发布时间】:2025-12-27 09:50:17
【问题描述】:

我的代码如下所示,我找不到导致转换错误的原因。有人可以帮助确定问题吗?

[COLUMN_A] = CASE
                WHEN [COLUMN_B] IS NOT NULL 
                     AND [COLUMN_B] <> '' 
                     AND CHARINDEX('MG', [COLUMN_B], 1)  <> 0  
                    THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT([COLUMN_B], CHARINDEX('MG', [COLUMN_B], 1))) 
                WHEN [COLUMN_B] IS NOT NULL 
                     AND [COLUMN_B] <> '' 
                     AND CHARINDEX('MCG', [COLUMN_B], 1) <> 0  
                    THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B], -1)))
                WHEN [COLUMN_B] IS NOT NULL 
                     AND [COLUMN_B] <> '' 
                    THEN CONVERT(DECIMAL(8, 4), RTRIM([COLUMN_B]))
                ELSE NULL  
    END

【问题讨论】:

  • 你遇到了什么错误?
  • 请提供样本数据。我猜这与您正在对字符串的外观以及实际可以在何处剪切字符串以产生小数的位置做出一些假设有关。
  • @Xedni - 没有可能的数据可以匹配 case 表达式的前两个分支并且是数字的。

标签: sql sql-server tsql type-conversion syntax-error


【解决方案1】:

对于COLUMN_B 包含字符串'MCG' 的情况,您正在使用表达式

LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B], -1))

让我们看看包含这个子字符串的字符串返回什么

+-----------+---------+
| COLUMN_B  | Returns |
+-----------+---------+
| MCG       | M       |
| MCG 12.45 | M       |
| 12.45 MCG | 12.45 M |
+-----------+---------+

因此您可以看到任何包含MCG 的字符串都保证产生非数字结果,因为它们都包含匹配子字符串的第一个字母。所以这必然无法转换为十进制。

-1 作为第三个参数传递给CHARINDEX 是没有意义的。这是start_location,字符串没有负数。

我假设您正在尝试查找 charindex,然后减去一个以提取子字符串左侧的所有内容,而不包括 M

所以你需要

LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B]) -1)

对于 12.45 MCGCOLUMN_B 值,这将返回 12.45 and then yourRTRIM` 将删除尾随空格。

这同样适用于您的其他 CHARINDEX 表达式。

您还可以删除[COLUMN_B] IS NOT NULL AND [COLUMN_B] &lt;&gt; '' 的前两个实例 - 因为如果它与charindex 测试匹配,它将不为空且不为空。

【讨论】:

    【解决方案2】:
    [COLUMN_A] = CASE
                WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
                     AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
                     AND CHARINDEX('MG', try_convert(nvarchar(max),[COLUMN_B]), 1)  <> 0  
                    THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT(try_convert(nvarchar(max),[COLUMN_B]), CHARINDEX('MG', try_convert(nvarchar(max),[COLUMN_B]), 1))) 
                WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
                     AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
                     AND CHARINDEX('MCG', try_convert(nvarchar(max),[COLUMN_B]), 1) <> 0  
                    THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT(try_convert(nvarchar(max),[COLUMN_B]), CHARINDEX('MCG', try_convert(nvarchar(max),[COLUMN_B]), -1)))
                WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
                     AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
                    THEN CONVERT(DECIMAL(8, 4), RTRIM(try_convert(nvarchar(max),[COLUMN_B])))
                ELSE NULL  
    END
    

    这应该至少能让你摆脱错误,并至少让你通过使用内联 try catch 函数让它运行。

    【讨论】:

      最近更新 更多