9

以下は、私が扱っている種類のテーブル構造とデータのサブセットです。

CREATE TABLE #Test
(
     Val varchar(5)
    ,Type varchar(5)
)

INSERT #Test VALUES ('Yes','Text')
INSERT #Test VALUES ('10','Int')
INSERT #Test VALUES ('10.00','Float')
INSERT #Test VALUES ('9.00','Float')
INSERT #Test VALUES ('9','Int')

列 'Val' が <= 9.00 (数値データ型である必要があります) かどうかを知らせるクエリを作成したいと考えています。私は次のようにしてこれを行いました:

SELECT *
FROM
    (
        SELECT Val
        FROM #Test
        WHERE Type = 'Int'
    ) IntsOnly
WHERE IntsOnly.Val <= 9.00

これにより、算術オーバーフロー エラーが発生します。ただし、値が「10」のデータ行を除外すると、次のようになります。

SELECT *
FROM
    (
        SELECT Val
        FROM #Test
        WHERE Type = 'Int'
        AND Val <> '10'
    ) IntsOnly
WHERE IntsOnly.Val <= 9.00

問題なく動作します。私の質問は、データを必要な形式に簡単に変換できることを知っているので、これを修正する方法ではありません。

私の質問は、「Val」列の「10」の値がエラーを返す理由です。確かに、ロジックは「False」を返すだけで行を除外する必要があります。これは、「10」(暗黙的に変換されていると思います) が 9.00 より大きいためです。

ありがとう。

4

3 に答える 3

17

Valこれは、暗黙的に列を NUMERIC(3,2) にキャストしようとしているため、算術オーバーフローが生成されます。これは、 10 のような 2 桁の値で自然にオーバーフローします。

9.00対象の型とサイズとして NUMERIC(3,2) を使用しています。これは、収まるように見える最小の数値であるためです。

もちろん、解決策は、暗黙的に行うのではなく、明示的なキャストを使用することです

于 2012-10-31T15:32:12.273 に答える
4

BOLから:

Transact-SQL ステートメントでは、小数点を含む定数は、必要最小限の精度と位取りを使用して、自動的に数値データ値に変換されます。たとえば、定数 12.345 は、精度が 5 で位取りが 3 の数値に変換されます。

つまり、定数の精度9.001 でスケールは 010 、精度は 3 でスケールは 2 であるため、最小精度が必要な値 を格納できません2 + scale

IntsOnly.Valを aCASTまたはでラップしてCONVERT、正しい精度と位取りを指定する必要があります。

于 2012-10-31T15:31:14.620 に答える