開始:このエラーの意味を理解しています-インスタンスを解決しようとはしていません。
このエラーのトラブルシューティングは非常に難しいことで有名です。100列幅のテーブルに100万行を挿入した場合、エラーの原因となっている行の列を特定する方法が事実上ないため、プロセスを変更して1行を挿入する必要があります。一度に、そしてどれが失敗するかを見てください。穏やかに言えば、それは苦痛です。
エラーがこのように見えない理由はありますか?
String or Binary data would be truncated
Error inserting value "Some 18 char value" into SomeTable.SomeColumn VARCHAR(10)
これにより、テーブル構造自体ではなくても、値の検索と修正がはるかに簡単になります。テーブルデータの表示がセキュリティ上の懸念事項である場合は、試行された値の長さや失敗した列の名前を指定するなど、一般的なものでしょうか。
MS Connectには、これに対するオープンな「機能リクエスト」があることが判明しました。機能の変更をご希望の場合は、投票することをお勧めします。
https://connect.Microsoft.com/SQLServer/feedback/details/339410/
追加:
実際には、2005年のユーコンの開発以来傑出したこの同じ機能(名前は不十分ですが)に対する別の要求があるようです。
https://connect.Microsoft.com/SQLServer/feedback/details/125347/
2016年の更新
Microsoftは、このバグの本当の年齢の証拠を削除しようとしたようです。けっこうだ。ここにアーカイブされている 古いサイトを見つけてください。
どこにも受け入れられる答えが見つからなかった後、私は次のことを思いついた:
あなたは次のようなものになるはずです
SELECT
Col1, Col2, ..., [ColN]
INTO [MyTempTable]
FROM
[Tables etc.]
WHERE 0 = 1
これにより、DBにMyTempTableというテーブルが作成され、ターゲットのテーブル構造と比較して、それらの違いを確認できます。つまり、両方のテーブルの列を比較できます。
編集:元のテーブルとMyTempTableの各列のデータ型と列サイズを比較して、それらがどこで異なるかを確認できます。新しいテーブルのすべての列名は古いものと同じになり、データ型とサイズは問題のある列がある場合を除いて同じです。つまり、このクエリを使用すると、SQLは、ソーステーブルから可能な最大のエントリを処理するのに十分な大きさの列を自動的に作成します。
閉鎖されたDUPに回答するため、代わりにここで回答します。このパターンは、多少複雑な場合でも使用できますが、アプリケーションを変更したり、プロファイラーを設定して何が起こっているかを確認するのが簡単ではない場合に役立ちます。場合によっては、エラーをAPP自体に伝播するだけで、APPから直接正しい有用なエラーメッセージを確認できます。
このような場合、このソリューションを使用してDBをすばやく確認すると、時間を大幅に節約できます。テンプレートとして保存し、テーブルをすばやく変更して、この問題を解決します。
サンプルテーブル
create table StringTruncation
(A int, B varchar(10), C nvarchar(5), D nvarchar(max), E datetime)
サンプルステートメント
insert StringTruncation values
(1, '0123456789', 'abcdef', 'This overflows on C', GETDATE())
恐ろしい役に立たないエラー
Msg 8152, Level 16, State 4, Line 1
String or binary data would be truncated.
The statement has been terminated.
この例では、オーバーフローする可能性のある2列のみが示されていますが、20列または40列であると想像してください。
-- First move the table out of the way
exec sp_rename StringTruncation, StringTruncation_;
-- cover it with a query
create view dbo.StringTruncation
with schemabinding
as
select
A,
convert(Nvarchar(max),B) B,
convert(Nvarchar(max),C) C,
D, E
from dbo.StringTruncation_
GO
-- use a trigger to allow INSERTs, with the length checks thrown in
create trigger dbo.trig_ioi_StringTruncation
on StringTruncation
instead of insert
as
set nocount on
declare @offending nvarchar(max)
select TOP 1 @offending = case
when len(C) > 5 then 'Data too long for Column [C] Size 5: ' + C
when len(B) > 10 then 'Data too long for Column [D] Size 10: ' + B
end
from inserted
where len(C) > 5 or len(B) > 10
GO
-- keep good data
if @@rowcount = 0
insert StringTruncation_
select * from inserted
else
raiserror(@offending,16,1)
GO
insert StringTruncation values
(1, '0s123456789', 'abcde', 'This overflows on C', GETDATE())
結果
メッセージ50000、レベル16、状態1、プロシージャtrig_ioi_StringTruncation、行18
列[D]のデータが長すぎますサイズ10:0s123456789
(影響を受ける1行)
ソフトウェアシステムの説明的なエラーメッセージは、存在しないのと同じくらい優れています。
これは、DBMSだけでなく、想像できるあらゆる種類のソフトウェアにも当てはまります。
根本的な理由は、「適切な説明エラーメッセージ」の実装に時間がかかりすぎるためだと思います。 「この特定の種類の例外が発生した場合にユーザーが確認したい情報」について考えることに多くの時間を費やすことは、平均的なソフトウェア開発者の文化の一部ではありませんか? 「適切な説明エラーメッセージ」を表示するためのコードを書き留める必要があるプログラマーは、コスト(時間)のみを確認し、メリットは確認しません。
ソフトウェアシステムから受け取った最新のエラーメッセージの1つは、「問題が発生しました。後でもう一度やり直してください」です。冗談じゃない。
短い答え:それはまさにそれです。
長い回答:行番号と列を表示することには価値がありますが、実際の情報が切り捨てられていることを表示することはおそらく意味がありません。 VARCHAR(10)シナリオでは、おそらく大したことではありませんが、サイズが大きすぎるデータは非常に役立ちます。しかし、うまくいけば、ここに誰もVARCHAR(MAX)が保持できる以上のものを挿入していません;)
マイクロソフトは怠け者ですか?
ちなみに、各行の挿入を個別に試す必要はありません。各テキスト列のmax(len(field))をクエリするだけで、原因であると思われるものから始めます。