SQL Server 2008: Error converting data type nvarchar to float

前端 未结 3 578
清酒与你
清酒与你 2020-11-30 15:25

Presently troubleshooting a problem where running this SQL query:

UPDATE tblBenchmarkData 
SET OriginalValue = DataValue, OriginalUnitID = DataUnitID, 
    D         


        
相关标签:
3条回答
  • 2020-11-30 15:53

    Order of execution not always matches one's expectations.

    If you set a where clause, it generally does not mean the calculations in the select list will only be applied to the rows that match that where. SQL Server may easily decide to do a bulk calculation and then filter out unwanted rows.

    That said, you can easily write try_parse yourself:

    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;
    
    0 讨论(0)
  • 2020-11-30 15:57

    So starting with your update query that's giving an error (please forgive me for rewriting it for my own clarity):

    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%'
       )
    

    I think you'll find that a SELECT statement with exactly the same expressions will give the same error:

    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%'
       )
    

    This should show you the rows that can't convert:

    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
    

    The trick in the last commented line is to tack on things to the string to force only valid numbers to be numeric. For example, if you wanted only integers, IsNumeric(DataValue + '.0E0') = 0 would show you those that aren't.

    0 讨论(0)
  • 2020-11-30 16:06

    It would be helpful to see the schema definition of tblBenchmarkData, but you could try using ISNUMERIC in your query. Something like:

    SET DataValue = CASE WHEN ISNUMERIC(DataValue)=1 THEN CAST(DataValue AS float) * 1.335 
                         ELSE 0 END
    
    0 讨论(0)
提交回复
热议问题