sql >> データベース >  >> RDS >> Sqlserver

SQLServerの「IDENTITYをデータ型に変換する算術オーバーフローエラー…」を修正しました

    メッセージ8115、レベル16の算術オーバーフローエラーがIDENTITYをデータ型に変換しています…」というエラーが発生した場合 SQL Serverの「」エラー。これは、IDENTITYのときにテーブルにデータを挿入しようとしていることが原因である可能性があります。 列がデータ型の制限に達しました。

    IDENTITY columnは、新しい行ごとに挿入される値を自動的にインクリメントします。挿入されている値が列のデータ型の範囲外である場合、上記のエラーが発生します。

    エラーの例

    エラーが発生するコードの例を次に示します。

    INSERT INTO t1 VALUES ('Dog');

    結果:

    Msg 8115, Level 16, State 1, Line 1
    Arithmetic overflow error converting IDENTITY to data type tinyint.

    この場合、私のIDENTITY 列はtinyintを使用します データ型。範囲は0〜255です。エラーはIDENTITYを意味します 列が255より大きい値を挿入しようとしています。

    これは通常、列にすでに255行を挿入していて、256行目を挿入しようとしている場合に発生します。

    IDENTITYが含まれるすべての行を選択すると、テーブルは次のようになります。 列が250より大きい :

    SELECT * FROM t1
    WHERE c1 > 250;

    結果:

    +------+------+
    | c1   | c2   |
    |------+------|
    | 251  | Ant  |
    | 252  | Cow  |
    | 253  | Bat  |
    | 254  | Duck |
    | 255  | Bull |
    +------+------+

    この場合、c1 私のIDENTITYです 列(たまたまタイプtinyint )。 IDENTITY 以前に255を生成しました 列の場合、挿入しようとする次の値は256です。 (1の増分値を想定 以前に失敗した挿入はありません)。 256はtinyintの範囲外であるため、これにより上記のエラーが発生します 。

    smallintのデータ型でも同じ問題が発生する可能性があります (最大値32,767)またはint (最大値は2,147,483,647)。 bigintでも発生する可能性があります 十分な行を挿入した場合(9,223,372,036,854,775,807以上)。

    ただし、IDENTITY 値は、挿入された行数と常に一致するとは限りません。 IDENTITYを作成するときにシード値を設定できます 列、および増分値を設定することもできます。したがって、シード値と増分値によっては、テーブルで実行される挿入の数よりもはるかに早く上限に達する可能性があります。

    また、テーブルから行を削除しても、IDENTITYはリセットされません。 値(テーブルの切り捨ては行いますが)。

    したがって、テーブル内の行がIDENTITYよりもはるかに少ない場合でも、上記のエラーが発生する可能性があります。 列のデータ型が示唆する場合があります。

    解決策

    1つの解決策は、IDENTITYのデータ型を変更することです。 桁。たとえば、smallintの場合 、intに変更します 。または、すでにintの場合 、bigintに変更します 。

    別の可能な解決策は、IDENTITYをリセットすることです。 より低い値にシードします。これは、テーブルから多くの行を削除した場合、または元のシード値が1よりもはるかに高い場合にのみ機能します。 。

    たとえば、IDENTITY 列はすでにintです 、ただしIDENTITY シードは、たとえば2,000,000,000から始まりました 、IDENTITYをリセットできます 1にシード 、これにより、さらに20億行を挿入できます。

    役立つ機能

    この問題を特定するのに非常に役立つ機能を次に示します。

    • IDENT_CURRENT() –ID列の指定されたテーブルまたはビューに対して生成された最後のID値を返します。
    • @@IDENTITY –現在のセッションで最後に挿入されたID値を返します。
    • IDENT_SEED() –ID列の元のシードを返します。
    • IDENT_INCR() –ID列の増分値を返します。

    また、列のデータ型がわからない場合に備えて、列のデータ型を取得する3つの方法を次に示します。

    さまざまなシナリオで同じエラー

    データ型間で明示的に変換しようとしたときに、元の値が新しい型の範囲外である場合にも、同じエラー(Msg 8115)が発生する可能性があります(わずかに異なるエラーメッセージが表示されます)。これを修正するには、SQLServerの「intをデータ型numericに変換する算術オーバーフローエラー」を修正するを参照してください。

    SUM()などの関数を使用した場合にも発生する可能性があります 列にあり、計算の結果、列のタイプの範囲外の値になります。これを修正するには、SQLServerの「式をデータ型intに変換する算術オーバーフローエラー」を修正するを参照してください。


    1. Round()がPostgreSQLでどのように機能するか

    2. 名前が特定の文字列で始まるすべてのテーブルを削除します

    3. 一貫性のないPostgreSQLスレーブを再構築する方法

    4. SQL ServerでCHECK制約を無効にする方法(T-SQLの例)