私は@marc_sに同意します-特にあなたの意図が truncate である場合は、症状ではなく問題を修正してください。別の開発者がやってきて、proc がこれらのエラーをスローし、問題を抑制するために非標準フラグが使用された場合、どう思うでしょうか?
切り捨てる意図を明確にするためのコード。
問題の特定
フィドルは、説明した動作を表示しません。そのため、この問題についてはまだ少し混乱しています。
また、SQL フィドルは、このような質問には密度が高すぎます。以下の質問に答えられない場合は、問題を可能な限り単純なユースケースに切り分けてください。アプリの 500 行をウィンドウにダンプしないでください。
注: Max NVarchar は、SQL 7 および 2000 のバージョンでは 4000、nvarchar(max)
SQL 2005 以降では 2 ギグ ( ) です。どこで 3072 を思いついたのかわかりません。
私のテスト
SPROCパラメーターレベルで切り詰める場合、この MSDN ページで警告されているように、ANSI 警告フラグは無視されます。プロシージャ内にある場合は、切り捨てを許可する ANSI フラグを表示する小さなテスト プロシージャを作成しました。
CREATE Proc DoSomething (@longThing varchar(50)) AS
DECLARE @T1 TABLE ( shortThing VARCHAR(20) );
SET ANSI_WARNINGS OFF
Print ' I don''t even whimpler when truncating'
INSERT INTO @T1 (ShortThing) VALUES ( @longThing);
SET ANSI_WARNINGS ON
Print ' I yell when truncated'
INSERT INTO @T1 (ShortThing) VALUES ( @longThing);
次に、次のように呼び出して、期待どおりに機能します。
exec DoSomething 'Text string longer than 20 characters'
問題の解決
それにもかかわらず、データを (潜在的に) 切り捨てるという意図が明確になるようにコーディングしてみませんか? 警告をオフにするのではなく、回避することができます。次のいずれかを行います。
- 入力に対応するのに十分な長さのプロシージャ パラメータを作成します。
- 文字列データを短くする必要がある場合は、データ
Substring()
をトリミングするために使用します。
CAST
またはを使用CONVERT
して、要件に合わせてデータをフォーマットします。 このページ(「暗黙の変換」という見出しのセクションが役立つはずです) は、キャストと変換がどのように機能するかを詳しく説明しています。
上記の簡単な例を次のように変更すると、フラグを設定する必要がなくなります。
CREATE Proc DoSomethingBETTER (@longThing varchar(50)) AS
SET ANSI_WARNINGS ON
DECLARE @T1 TABLE ( shortThing VARCHAR(20) );
--try one of these 3 options...
INSERT INTO @T1 (ShortThing) VALUES ( Convert(varchar(20), @longThing));
INSERT INTO @T1 (ShortThing) VALUES ( Substring(@longThing, 1, 20));
INSERT INTO @T1 (ShortThing) VALUES ( Cast(@longThing as varchar(20)) );
Print('Ansi warnings can be on when truncating data');
余談 - クラスター化されたガイド
Uniqueidentifer
あなたのフィドルを見ると、あなたがクラスター化インデックスのキーであることに気付きました。ほとんどすべてのシナリオで、これは非常に非効率的なオプションです。GUID のランダム性は、データが常に断片化および再シャッフルされていることを意味します。
Jimmy Nilsson の記事int identity
で説明されているように、 、使用しているnewsequentialid()
、または COMB GUID に 変換できることを願っています。この問題の詳細については、こちら、こちら、こちら、およびこちらをご覧ください。