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 を float に変換中にエラーが発生しました。

本当に奇妙なことは、取得された値が数値であることを調べるためUPDATEに toを変更すると、次のようになります。SELECT

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 2012 ではなく SQL Server 2008 で実行しています。ティア。

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わけではありません。SQL Server は、一括計算を実行して不要な行を除外することを簡単に決定できます。selectwhere

そうは言っても、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 に答える