3

目前正在解决运行此 SQL 查询的问题:

UPDATE tblBenchmarkData 
SET OriginalValue = DataValue, OriginalUnitID = DataUnitID, 
    DataValue = CAST(DataValue AS float) * 1.335 
WHERE 
    FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5' 
    AND ZEGCodeID IN 
             (SELECT ZEGCodeID FROM tblZEGCode 
              WHERE(ZEGCode = 'C004') OR 
                   (LEFT(ZEGParentCode, 4) = 'C004'))

导致以下错误:

消息 8114,级别 16,状态 5,第 1
行将数据类型 nvarchar 转换为浮点数时出错。

真正奇怪的是,如果我更改UPDATESELECT检查检索到的值是数值:

SELECT DataValue 
FROM tblBenchmarkData 
WHERE FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5' 
AND ZEGCodeID IN 
         (SELECT ZEGCodeID 
          FROM tblZEGCode WHERE(ZEGCode = 'C004') OR 
                               (LEFT(ZEGParentCode, 4) = 'C004'))

结果如下:

DataValue
2285260
1205310

想使用TRY_PARSE或类似的东西;但是,我们在 SQL Server 2008 而不是 SQL Server 2012 上运行。有人有什么建议吗?TIA。

4

3 回答 3

5

查看 tblBenchmarkData 的架构定义会很有帮助,但您可以尝试在查询中使用 ISNUMERIC。就像是:

SET DataValue = CASE WHEN ISNUMERIC(DataValue)=1 THEN CAST(DataValue AS float) * 1.335 
                     ELSE 0 END
于 2012-02-03T23:17:29.830 回答
2

执行顺序并不总是符合一个人的期望。

如果你设置了一个where子句,这通常并不意味着select列表中的计算只会应用于匹配的行where。SQL Server 可能很容易决定进行批量计算,然后过滤掉不需要的行。

也就是说,您可以轻松编写 try_parse 自己:

create function dbo.try_parse(@v nvarchar(30))
returns float
with schemabinding, returns null on null input
as
begin
  if isnumeric(@v) = 1
    return cast(@v as float);

  return null;
end;
于 2012-02-03T23:15:38.603 回答
1

所以从你的更新查询开始,它给出了一个错误(请原谅我为了我自己的清楚而重写它):

UPDATE B
SET
   OriginalValue = DataValue,
   OriginalUnitID = DataUnitID,
   DataValue = CAST(DataValue AS float) * 1.335
FROM
   dbo.tblBenchmarkData B
   INNER JOIN dbo.tblZEGCode Z
      ON B.ZEGCodeID = Z.ZEGCodeID
WHERE
   B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
   AND (
      Z.ZEGCode = 'C004' OR 
      Z.ZEGParentCode LIKE 'C004%'
   )

我想您会发现具有完全相同表达式的 SELECT 语句会给出相同的错误:

SELECT
   OriginalValue,
   DataValue NewOriginalValue,
   OriginalUnitID,
   DataUnitID OriginalUnitID,
   DataValue,
   CAST(DataValue AS float) * 1.335 NewDataValue
FROM
   dbo.tblBenchmarkData B
   INNER JOIN dbo.tblZEGCode Z
      ON B.ZEGCodeID = Z.ZEGCodeID
WHERE
   B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
   AND (
      Z.ZEGCode = 'C004' OR 
      Z.ZEGParentCode LIKE 'C004%'
   )

这应该向您显示无法转换的行:

SELECT
    B.*
 FROM
    dbo.tblBenchmarkData B
    INNER JOIN dbo.tblZEGCode Z
       ON B.ZEGCodeID = Z.ZEGCodeID
 WHERE
    B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
    AND (
       Z.ZEGCode = 'C004' OR 
       Z.ZEGParentCode LIKE 'C004%'
    )
    AND IsNumeric(DataValue) = 0
    -- AND IsNumeric(DataValue + 'E0') = 0 -- try this if the prior doesn't work

最后注释行中的技巧是将内容附加到字符串以仅强制有效数字为数字。例如,如果您只想要整数,IsNumeric(DataValue + '.0E0') = 0则会向您显示那些不是的。

于 2012-02-03T23:39:34.667 回答