みなさんこんにちは!ヒロポンです!
画面から入力された文字列を数値や日付に変換するバッチ。書いてて、変な値が1個混ざってた瞬間にジョブが丸ごと落ちた、って経験ないですか??
ありますよね。多分あるはず。
「金額」のはずのカラムに N/A とか全角スペースとか、想定してない文字が入ってる。それを CAST で数値に変換した瞬間、その1行だけじゃなくバッチ全体がエラーで止まる。
夜間バッチだと、翌朝それに気づく。しんどいやつです。
ここで効くのが SQL Server の TRY_CONVERT / TRY_CAST。変換できない値を例外じゃなく NULL で返してくれるので、汚いデータが混ざってもバッチが止まらない。
この記事では、業務でこの手の型変換をやる時に踏みがちな落とし穴を5つ、実テーブルで動かしながらまとめました。
忙しい人向けに最初にまとめ
CAST/CONVERTは変換できない値が1行でもあるとステートメント全体がエラーで止まるTRY_CONVERT/TRY_CASTは変換できない値をNULLにして、他の行はそのまま流す- ただし
NULLが返るので、後続のWHERE/ 集計 /JOINでNULLを考慮しないと結果がズレる TRY_CONVERTは SQL Server 2012 以降。書式(style)を指定したいならTRY_CONVERT、不要ならTRY_CAST- 変換不能な値だけでなく、範囲オーバー(
tinyintに 300 等)もNULLになる
以下、汚いデータの入ったテーブルで実際に動かしていきます。
そもそも何が起きるのか — CAST は1行の失敗で全部落ちる
まず問題を再現します。画面入力を溜めた、ちょっと汚いテーブルを用意する。
CREATE TABLE #Input (Id INT, RawValue VARCHAR(20));
INSERT INTO #Input VALUES
(1, '100'),
(2, '200'),
(3, 'N/A'), -- 変換不能な値
(4, ''), -- 空文字
(5, '300');
これを CAST で INT に変換してみる。
SELECT Id, CAST(RawValue AS INT) AS Value
FROM #Input;
実行結果:

N/A の行に当たった瞬間、そのステートメントは Msg 245(変換エラー)で異常終了します。100 や 200 は先に返っていても、ステートメントとしては失敗。
INSERT ... SELECT みたいなバッチなら、その1件のせいで1行もコミットされません。ん?1行のために全部巻き添え?ってなりますよね。
でもこれが夜間バッチの中で起きると、そのジョブが丸ごと止まる。
同じことを TRY_CONVERT でやると、こんな感じで変わる。
SELECT Id, TRY_CONVERT(INT, RawValue) AS Value
FROM #Input;
実行結果:

N/A の行は NULL、変換できる行はそのまま。全行返ってきて、バッチは止まらない。これがやりたかったこと!! いい感じです。
ここで実行結果をよく見てください。空文字('')の行は NULL じゃなく 0 になってます。
空文字は「変換できない値」ではなく「0 に変換できる値」扱いなんですね。NULL を期待してると足をすくわれるやつ。頭の隅に置いておいてください(落とし穴3でもう一度出てきます)。
では、この置き換えで実務がハマる点を順番に見ていきます。
⏱ 対処の早見表
先に、各落とし穴の「気づいてから直すまでの目安」を置いておきます。
| 落とし穴 | 症状 | 対処の目安 |
|---|---|---|
| 1. CAST が全部落ちる | バッチが1件も処理せず停止 | TRY_ 化で即・5分ほど |
| 2. バージョン非対応 | 'TRY_CONVERT' is not a recognized... |
CASE や ISNUMERIC で代替・30分ほど |
| 3. NULL の考慮漏れ | 集計や件数が静かにズレる | WHERE や ISNULL を追加・15分ほど |
| 4. style 指定ミス | 日付が意図と違う / NULL 多発 | style 番号を確認・10分ほど |
| 5. 範囲オーバー | 想定より NULL が多い | 変換先の型を見直す・15分ほど |
1. CAST/CONVERT は変換失敗でステートメントごと落ちる
これが今回の主役の落とし穴です。上で見たとおり、CAST や CONVERT は変換できない値が1行でもあると、その行だけでなくステートメント全体をエラーで止めます。
業務のバッチは何万行も一括で処理する。たった1件のゴミデータでジョブ全体が死ぬわけです。
俺も昔、月次の取込バッチが1レコードの N/A で止まって、翌朝までデータが入ってなかったことがある。原因のレコードを特定するのに、ログを頭から追う羽目になりました。地味に効くやつ。
対処は、変換を TRY_CONVERT(または TRY_CAST)に置き換えるだけ。

教訓: 外部由来の汚いデータを変換するなら、既定を TRY_ にする。落ちてほしいのは例外的な場面だけです。
CAST / CONVERT そのものの基本的な落とし穴(暗黙変換や桁あふれ)は「SQL Server の CAST/CONVERT で踏む3つの罠」にまとめてあります。
これは前段の話なので、興味がある人は別タブ開いて後で読んでくださいな。
2. TRY_CONVERT / TRY_CAST は SQL Server 2012 以降
便利なんですが、TRY_ 系は SQL Server 2012 で追加された関数です。2008 R2 以前のインスタンスでは、そもそも関数が認識されずにエラーになる。
レガシーな現場だと SQL Server 2008 のまま、というのは普通にある。ここは前提を確認してから使ってください。
バージョンはこれで分かります。
SELECT SERVERPROPERTY('ProductVersion') AS Version,
SERVERPROPERTY('ProductLevel') AS Level;
2008 R2 以前で同じことをやりたいなら、CASE 式と ISNUMERIC で自前ガードする手があります。
SELECT Id,
CASE WHEN ISNUMERIC(RawValue) = 1
THEN CAST(RawValue AS INT)
ELSE NULL END AS Value
FROM #Input;
ただし ISNUMERIC は '1e5' や '$100'、'.' みたいな「数値っぽいけど INT にできない値」も 1 を返す曲者。これはこれで別のハマりを生みます。
2012 以降なら素直に TRY_CONVERT の方が安全です。
教訓: TRY_ 系が使えるかはバージョン次第。使う前に ProductVersion を1回確認する。
3. NULL が返るので後続の WHERE / 集計 / JOIN でズレる
TRY_CONVERT は「エラーを消す」んじゃなくて「エラーを NULL に変える」関数です。ここを勘違いすると、静かに結果がズレる。
これが2つ目の大きなハマりどころ。
たとえば「変換した金額の合計」を出すとき。
-- NULL は SUM で無視される → 変換できなかった行は集計から静かに漏れる
SELECT SUM(TRY_CONVERT(INT, RawValue)) AS Total
FROM #Input;
SUM は NULL を飛ばして計算します(厳密には Null value is eliminated by an aggregate という警告が出ますが、エラーにはならない)。
なので変換できなかった N/A の行は集計からこっそり抜ける。おまけに、さっきの空文字は 0 として足し込まれる。
件数が合わない、金額が微妙に足りない。その原因がこのあたりだったりします。これが罠の正体。
「変換できなかった行」を弾きたい、あるいは拾いたいなら、NULL を明示的に扱う。
-- 変換できた行だけを対象にする
SELECT Id, TRY_CONVERT(INT, RawValue) AS Value
FROM #Input
WHERE TRY_CONVERT(INT, RawValue) IS NOT NULL;
-- 変換できなかった行を 0 とみなす
SELECT Id, ISNULL(TRY_CONVERT(INT, RawValue), 0) AS Value
FROM #Input;
JOIN のキーを TRY_CONVERT で作る場合も同じ。NULL 同士は結合しないので、変換に失敗したキーの行はごっそり結合対象から外れます。
教訓: TRY_ は例外を NULL に化かすだけ。NULL をどう扱うかは自分で決める。
4. TRY_CAST と TRY_CONVERT の違い(style 指定の有無)
TRY_CAST と TRY_CONVERT、どっちを使えばいいのか?? 迷ったらこれだけ覚えてください。書式(style)を指定したいかどうかです。
TRY_CAST(値 AS 型)…CASTと同じ。style は渡せないTRY_CONVERT(型, 値, style)…CONVERTと同じ。第3引数に style を渡せる
日付変換で効いてきます。'2026/07/14' みたいなスラッシュ区切りの書式を明示したい時、TRY_CONVERT なら style 番号で「この書式で読んで」と指定できる。
-- style 111 = yyyy/mm/dd (日本でよく使う書式)
SELECT TRY_CONVERT(DATE, '2026/07/14', 111) AS Parsed;
こんな感じで、書式を明示したうえで安全に日付へ変換できます。
ただし style を間違えると、変換自体は通っても意図と違う日付になったり、NULL が多発したりします。日付まわりの style は思い込みで書かず、Microsoft Learn の style 一覧を1回見て確認するのが安全です。
教訓: style を渡したいなら TRY_CONVERT、いらないなら TRY_CAST。日付の style は必ず裏を取る。
5. 変換不能だけでなく範囲オーバーも NULL になる
最後。TRY_CONVERT が NULL を返すのは N/A みたいに変換できない値だけ、と思ってると足をすくわれます。変換はできるけど型の範囲を超える値も NULL になります。
分かりやすいのが tinyint。tinyint は 0〜255 しか入らないので、'300' は「数字だけど範囲外」です。
SELECT TRY_CONVERT(TINYINT, '300') AS Result; -- 範囲外 → NULL
SELECT TRY_CONVERT(TINYINT, '200') AS Result; -- 範囲内 → 200
CAST('300' AS TINYINT) ならオーバーフローのエラーになるところを、TRY_CONVERT は静かに NULL にします。
エラーで気づけない分、「なんか NULL が多いな」の原因が範囲オーバーだった、というのは起きがち。これもタチが悪い。
教訓: NULL が想定より多い時は、「変換不能」だけでなく「変換先の型が狭すぎないか」も疑う。
まとめ・チートシート
汚いデータの型変換で踏む5つを見てきました。最後に3つの関数を一枚で。

要は、外部由来の汚いデータを流し込むバッチでは、既定を TRY_CONVERT / TRY_CAST にしておく。
そのうえで、返ってくる NULL を WHERE や ISNULL でどう扱うかまで決めておく。ここまでやれば、N/A 1個でジョブが止まる事故はなくなります。
TRY_ 系を押さえておくと、汚いデータが来る前提の現場でも夜中に叩き起こされる回数が確実に減る。そこが一番の効きどころです。
よくある質問
TRY_CONVERT はパフォーマンスが遅くなりませんか
変換1回あたりのコストは CONVERT とほぼ変わりません。ただし WHERE TRY_CONVERT(...) IS NOT NULL のように条件で使うと、その列のインデックスが効きにくくなる(式が絡むと SARGable でなくなる)ことはあります。大量データで条件に使うなら、変換済みの列を用意する等の設計を検討してください。
TRY_CONVERT で NULL になった行だけ後で調べたいです
元の文字列を残しておいて、WHERE TRY_CONVERT(INT, RawValue) IS NULL AND RawValue IS NOT NULL で「値はあるのに変換できなかった行」を抽出できます。取込バッチではこの結果をエラーテーブルに退避しておくと、後追いが楽になります。
空文字や NULL を変換するとどうなりますか
TRY_CONVERT に NULL を渡すと結果も NULL です。一方で空文字('')は、INT や DECIMAL などの数値型では NULL ではなく 0 に変換されます(実測)。「変換できない=NULL」のつもりで空文字を見落とすと、集計に 0 が紛れ込んで件数や合計がズレます。ちなみに ISNUMERIC('') は 0(数値でない扱い)なので、ISNUMERIC ガードと TRY_CONVERT では空文字の結果が食い違う点にも注意です。
ISNUMERIC ではダメなのですか
ISNUMERIC は「数値として解釈できるか」を返しますが、'1e5' や '$100'、'.' even も 1(数値扱い)を返すので、INT に変換できることの保証にはなりません。2012 以降なら TRY_CONVERT(INT, ...) IS NOT NULL で「INT に変換できるか」を直接判定する方が正確です。
次に読むべき記事



以上!
同じ「N/A 1個でバッチ全滅」を踏んだ人がいたら、どんどんシェア待ってるぜ!!
執筆者
バイブス父さん — 業務 SE 7 年 (SIer 正社員 2 / フリーランス 5)。 現職は SEO 直轄部の AI アドバイザー兼 PL、 副業で中小 SIer の CTO。 SIer の正社員からフリーランスに転じ、 複数のエージェント経由で案件を回してきた経験ベースで「業務 SE 視点」 の技術 + キャリア記事を書いています。
🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る



