SQLのCASTは、式を明示したデータ型へ変換するための機能です。まず結論を言うと、CAST(式 AS 型)という形は広く使えますが、指定できる型、変換失敗時の挙動、日付書式、文字列長はデータベース製品ごとに違います。検索条件の列そのものを毎回変換するのではなく、入力値側を列と同じ型にそろえ、変換できない値を先に分離するのが最も事故の少ない使い方です。
本記事ではSQL Server、MySQL 8.4、PostgreSQL 18を区別して説明します。サンプルをそのまま貼る前に、接続先製品と列定義を確認してください。とくに本番テーブルの型変更、金額の桁数変更、日付の一括変換は、単なる表示変更ではなくデータ欠損や検索性能低下につながるため、読み取り専用のSELECTで結果と件数を確認してから進めます。
最初に確認すること
| 目的 | 第一候補 | 注意点 |
|---|---|---|
| 表示用に型を変える | SELECT句でCAST | 文字列長と小数精度を明示する |
| 外部文字列を数値・日付にする | 検証後にCAST。SQL ServerならTRY_CASTも検討 | 変換失敗をNULLと正常なNULLで区別する |
| 検索条件の型を合わせる | パラメーター側を列型に合わせる | 列側のCASTは索引利用を妨げることがある |
| 列自体の型を変更する | 新列へ段階移行 | バックアップ、照合、切り戻しを用意する |
| DB製品をまたいで移植する | 標準形のCASTを中心にする | CONVERT、TRY_CAST、二重コロンは方言 |
CASTの基本と戻り値
基本構文はCAST(expression AS target_type)です。式がNULLなら、多くの一般的な変換でも結果はNULLになります。一方、変換元の内容が対象型として不正なら、エラーになるか、警告を伴う値になるか、失敗を示すNULLになるかは製品と関数で異なります。したがって『CASTすれば自動的に安全な値になる』とは考えないでください。
整数から文字列へ変換するときは、保存または連結される最大桁数を見積もって文字列長を決めます。数値からDECIMAL(p,s)へ変換するときは、pが全体の桁数、sが小数点以下の桁数です。金額や計測値では丸め方が業務要件と一致するかを、境界値、負数、最大値で確認します。浮動小数点数を整数にする例だけを見て、会計値にも同じ変換を適用してはいけません。
日付と時刻の変換
日付文字列は、曖昧な01/02/03ではなく、利用製品が明確に解釈できる形式とパラメーター型を使います。SQL Serverではセッションの言語や日付形式が結果に影響する入力があり、PostgreSQLやMySQLにもそれぞれ入力規則があります。時刻を含む列ではタイムゾーンの有無も別問題です。日付だけへCASTすると時刻部分が失われるため、元値を残したまま変換結果を比較します。
文字セットと照合順序
文字列へのCASTは、文字コードや照合順序まで自動的に目的どおり統一するとは限りません。MySQLのCASTやCONVERTには文字セット変換に関する構文があり、SQL Serverでは文字列型と照合順序、PostgreSQLでは型と照合規則を別に確認する必要があります。日本語、絵文字、結合文字を扱う列では、表示できたことだけでなく、長さ、並べ替え、比較結果も確認します。
製品ごとの違い
SQL Server
SQL ServerではCASTとCONVERTが変換に使われます。CONVERTのstyle引数は日付やバイナリの表現を指定する用途がありますが、移植性を優先する単純な型変換ならCASTが読みやすい選択です。変換に失敗し得る外部データではTRY_CASTを使うと多くの失敗でNULLを返せます。ただし、明示的に許可されない変換はTRY_CASTでもエラーになり得ます。
TRY_CASTの結果がNULLでも、元からNULLだったのか、不正値だったのかは別途判定が必要です。取り込み処理では元文字列、変換結果、エラー理由をステージング表に残し、WHERE source_value IS NOT NULL AND TRY_CAST(source_value AS ... ) IS NULLのように不正行を抽出します。ISNUMERICだけでは目的の整数型へ確実に変換できることを保証しないため、最終的な対象型で判定します。
MySQL
MySQL 8.4の公式リファレンスには、CAST(expr AS type)で使用できる型が列挙されています。SQL ServerのVARCHAR指定やstyle引数をMySQLへそのまま移植できるとは限りません。また、不正入力の扱いはSQLモードや文脈によって警告やエラーが関係するため、実行後の警告を無視しないでください。文字列比較をバイト単位へ変える旧来のBINARY exprは非推奨で、公式資料はCAST(... AS BINARY)を案内しています。
PostgreSQL
PostgreSQLは標準形のCAST(expression AS type)に加え、expression::typeも受け付けます。二重コロンはPostgreSQL固有の書き方なので、複数製品へ移植するSQLでは標準形を使う方が意図を共有しやすくなります。適切な変換操作が定義されていなければ変換は成功しません。入力値が不正な場合にSQL ServerのTRY_CASTと同じ感覚でNULLになると仮定しないでください。
失敗しにくい実装手順
- 接続先DBMSとバージョン、変換元の実データ型、対象型の上限を確認する。
- NULL、空文字、空白、全角数字、桁あふれ、負数、小数、うるう日などの境界データを抽出する。
- まずSELECT句だけで変換し、成功件数、不正件数、最大・最小値、文字列長を照合する。
- 変換不能行を除外せず、理由と元値を監査できる場所へ分離する。
- 更新が必要ならトランザクションまたは新列で小さく実施し、アプリケーションの読み書きを段階的に切り替える。
- 行数、合計値、NULL数、重複数、代表レコードを比較してから旧列を廃止する。
本番の列型を直接変更すると、長時間ロック、索引再構築、ログ増大、アプリケーションとの型不一致が起きる可能性があります。安全側の移行は、対象型の新列を追加し、変換可能な行を小分けでコピーし、検証後に参照先を切り替える方法です。切り戻し期間中は旧列を保持し、二重書きの整合性を監視します。DDLのロールバック可否は製品と実行方法で違うため、事前に復元手順まで確認します。
検索性能を落とさない考え方
索引付きの日時列に対してWHERE CAST(event_time AS VARCHAR(...)) = '...'のように列全体へ関数を適用すると、単純な範囲検索より効率が落ちる場合があります。日付なら開始以上・翌日未満の範囲、数値なら型付きパラメーターを使い、列をそのまま比較できる形を優先します。実行計画で索引探索、推定行数、暗黙変換の警告を確認し、代表データ量で比較してください。
JOINでも左右の列型が異なると暗黙変換が起こり、性能だけでなく比較結果が変わることがあります。設計段階でキー型を統一し、やむを得ない移行期間だけ明示変換を使います。頻繁に同じ変換をするなら、保存設計、計算列、式索引など製品固有機能を検討できますが、更新コストと移植性を含めて判断します。
元記事から引き継いだSQL例
以下のカスタムコードブロックは、元記事の構成とコードを保つため原文のまま掲載しています。複数DB製品の方言が混在し、列側CAST、ISNUMERIC、日付書式など現在の推奨と一致しない例も含まれます。上の製品別説明を優先し、読み取り専用環境で確認せず本番へ適用しないでください。
CAST(expression AS target_data_type)SELECT CAST('123' AS INT);SELECT CAST('456' AS INT) AS ConvertedValue;SELECT CAST(789 AS VARCHAR(10)) AS ConvertedValue;SELECT CAST('2024-05-24' AS DATE) AS ConvertedValue;SELECT CAST(123.456 AS INT) AS ConvertedValue;CAST(expression AS target_data_type)CONVERT(target_data_type, expression [, style])SELECT CAST('123' AS INT) AS ConvertedValue;SELECT CONVERT(INT, '123') AS ConvertedValue;SELECT CONVERT(VARCHAR, GETDATE(), 101) AS USFormattedDate;SELECT 'Order Number: ' + CAST(OrderID AS VARCHAR) AS OrderDescription
FROM Orders;SELECT CAST(SalesAmount AS DECIMAL(10, 2)) AS FormattedSalesAmount
FROM Sales;SELECT *
FROM Events
WHERE CAST(EventDate AS VARCHAR) = '2024-05-24';SELECT
CASE
WHEN IsNumeric(Value) = 1 THEN CAST(Value AS INT)
ELSE NULL
END AS ConvertedValue
FROM SampleTable;SELECT TRY_CAST('abc' AS INT) AS SafeConversion;SELECT
CASE
WHEN ISNUMERIC(Value) = 1 THEN CAST(Value AS INT)
ELSE NULL
END AS SafeConversion
FROM SampleTable;SELECT TRY_PARSE('2024-05-24' AS DATE USING 'en-US') AS SafeDateConversion;SELECT
Name,
TRY_CAST(Age AS INT) AS SafeAge
FROM Users;エラー時の切り分け
| 症状 | 主な確認 | 次の行動 |
|---|---|---|
| 変換エラーで文全体が停止 | 不正値、桁あふれ、許可されない型の組合せ | 対象型で失敗行を抽出し、元値を修正または隔離 |
| 結果がNULL | 元NULLかTRY_CAST失敗か | 元値との組合せで理由を記録 |
| 数値が丸められた | precision、scale、整数化の規則 | 業務ルールに合うROUND等を明示し再検証 |
| 文字が切れた・化けた | 長さ、文字セット、照合順序 | 最大長と多言語データで再試験 |
| 急に遅くなった | 列への関数適用、暗黙変換、実行計画 | パラメーター側の型を合わせて比較 |
変換後の合計や件数が業務上の正解と合わない、同じSQLが環境ごとに違う、移行中に書き込みが継続する、ロック時間を見積もれない場合は、DBAまたはアプリケーション所有者へエスカレーションします。エラーを握りつぶしてNULLへ置き換えるだけでは、請求額や在庫数の欠落を発見できません。受け入れ条件を数値で決め、失敗データを追跡できる状態にします。
よくある質問
CASTとCONVERTはどちらを使うべきですか?
単純な明示変換と移植性を重視するならCASTが出発点です。SQL Server固有のstyle指定などが必要ならCONVERTを使い、方言であることをコードレビューで明確にします。
文字列を安全に整数へ変換する方法は?
まず対象型の範囲と許容書式を決めます。SQL ServerではTRY_CASTで失敗候補を抽出できますが、NULLの理由を区別してください。MySQLやPostgreSQLでは各製品の失敗挙動に合わせてステージングと検証を行います。
CASTした列をWHEREで検索してもよいですか?
正しさは得られても索引を効率よく使えない場合があります。列型に合うパラメーターや範囲条件へ書き換え、実行計画で確認するのが基本です。
日付をVARCHARへして比較するのはなぜ危険ですか?
書式、言語、時刻、文字列順序に依存しやすく、列への関数適用で性能も落ち得ます。日時型の境界値を使った範囲比較を優先します。
変換できない値を0へ置き換えてよいですか?
0が実データとして有効なら欠損と区別できなくなります。不正値は元値と理由を残して隔離し、業務判断で修正してください。
列型を一括変更する前に何を保存しますか?
スキーマ、行数、NULL数、最小最大、合計、重複、代表データ、実行計画、復元可能なバックアップを保存します。旧列を一定期間保持できる段階移行が安全です。
公式情報源
まとめ
CASTは型を明示してSQLの意図を伝える基本機能ですが、安全性は対象型、入力品質、DBMS方言、検索条件の置き方で決まります。製品を特定し、SELECTで境界値と失敗行を確認し、列ではなく入力側の型を合わせることから始めてください。更新や列型変更は新列を使った段階移行と切り戻しを用意し、NULL化や丸めを『成功』と見なさないことが重要です。

コメント