2011-09-02 18 views
4

新しい列を追加する前にテーブルの行サイズを決定し、8060バイトの制限を超えないようにする明確な方法はありますか?SQL Server 2005 - テーブルの行サイズ制限に達する

たとえば、テーブルの行の長さが現在8055バイトで、datetime(8バイト)を追加したい場合、これは8063バイトになります(ヌルマッピングを除く)。

しかし、整数(4バイト)を追加すると、テーブルサイズ(nullマッピングを除く)に収まる8059バイトになります。

現在、テーブルのサイズを取得できますが、データ型のサイズ(int、datetimeなど)を取得するためのSQLファンクションを作成するのが難しく、データ型にNULLマッピング。

tablenameとdatatype:fnIsEnoughStorage( 'table1'、int)の2つの変数を受け入れ、スカラ関数からブール値(yes/no)を受け取る関数を使用できますか?

trueの場合、テストが決定された後にALTER TABLEコマンドを実行します。

+5

私のテーブルの1つに8kの限界を超える行があった場合、私はデザインを非常に真剣に見ていきます。 –

+0

どのデータを格納する必要があるかを分析するのではなく、どのデータ型を追加するかによってテーブルを実際に設計していますか? –

答えて

5

ここでこのクエリそれだけでまとめて - これはあなたの行は実際以上の8060バイトを使用しているという意味ではありません

;WITH TableRowSizes AS 
(
    SELECT 
     t.NAME 'TableName', 
     COUNT(1) 'NumberOfColumns', 
     SUM (c.max_length) 'MaxRowLength' 
    FROM 
     sys.columns c 
    INNER JOIN 
     sys.tables t ON c.object_id = t.object_id 
    WHERE 
     c.user_type_id NOT IN (98, 165, 167, 231) -- sql_variant, varbinary, varchar, nvarchar 
    GROUP BY 
     t.name 
) 
SELECT * 
FROM TableRowSizes 
WHERE MaxRowLength > 8060 
ORDER BY MaxRowLength DESC 

:potentitally危険ですし、利用可能な8060のバイトを超えてしまう可能な最大行サイズを持つテーブルを決定します可能な最大サイズch列。

あなたが実際に現在使用されるサイズを決定したい場合、あなたはおそらく、(代わりにsys.columnsから理論最大値を使用しての)DATALENGTH(colname)機能を調べることによって、類似した何かを行うことができます

更新:はにWHERE句を追加しましたgbnの応答に基づく私のCTE SELECT - これらのタイプは、行が8060バイトのサイズ制限を潜在的に破るかどうかを判断するために使用すべきではありません。

+0

可変長+ヌルビットマップ+多分rowversioningポインターごとに2を加える必要があります。そうしないと、誤解を招きます。 – gbn

+0

@gbn:ええ、私は知っていますが、それは非常に面倒です。これは現在のところ近似ですが、通常は十分に近いです。 –

+0

ありがとう、おそらく最も良いアプローチは最も実用的な方法です。最も洗練されたアプローチは、テーブルにどれだけのスペースが残っているかをテストし、32バイト以下であれば、そのカラムが追加されないようにすることです。 – Resurface

3

varchar/nvarcharの列はoverflowになるため、行が8060バイトの制限を破る可能性があります。

警告が表示されますが、許可されます。

固定長のolumnsを使用して8060バイトの制限を破っている場合は、垂直方向に分割する必要があります(たとえば、1:1のテーブル)。 「終わり」

新しいint型の列は行っておりませんのでご注意:ディスク上の構造が明確に定義され、データが新しい固定長フィールドに対応するために移動されます:OneTwo

+0

この場合、スクリプトを修正する必要があります。テーブルのどの列が「オーバーフロー」しているかを調べる方法はありますか?私は 'sys.columns'や' sys.types'でそのプロパティの表示を見つけることができないようです(私は 'is_variable'かそのようなものを探しました....) –

+0

@marc_s:私が知っている方法は私が与えた最初のリンク:varchar、nvarchar、varbinary、sql_variant – gbn

+0

ありがとう!この追加情報を反映するようにスクリプトを更新しました。 –