1

ストアド プロシージャで ANSI 警告をオフにする方法を知りたいです。エラーが発生し続けます

文字列型やバイナリは省略されます。

ただし、これを期待して許可するので、これをオフにしたいと思います。

発言を追加しました

SET ANSI_WARNINGS OFF 
GO

ただし、ストアドプロシージャの直前に、これを行ってもエラーがまったく抑制されないようです。

そもそもこの切り捨てエラーが発生する理由として、ストアド プロシージャの 1 つが動的 Sql を実行して値を取得します (コードを表示する SQLFIddle )。そして、すべてのフィールドの長さを最大の長さ (NVarchar(3072)) に設定する必要がありました。ただし、クエリが実行されると、クライアントに出力するときに正しいサイズに戻す必要があります。

これに対処する最善の方法についての情報をいただければ幸いです。前もって感謝します。

4

1 に答える 1

5

私は@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 に 変換できることを願っています。この問題の詳細については、こちらこちらこちら、およびこちらをご覧ください。

于 2012-10-13T19:28:49.963 に答える