SQL Serverのsql_variant型で複数行INSERTしたら型が変わった話とAIによる仕様改善の比較
株式会社ネクスタの奥上です。
導入(ハマったこと)
「なぜか本番環境でデータが壊れてる…」
SQL Server で sql_variant 型を使っているとき、複数行 INSERT で予期せぬ型変換が起こり、本番環境で不具合が発生したことはありませんか?
(かなりニッチなことなのでないと思いますが・・・)
実は、複数行の VALUES 句には、知っておくべき「型推論」のルールが存在します。
今回は、実際に発生した不具合を再現コード付きで解説し、その原因と対策、さらにAIを活用した根本的な設計改善案までを深掘りします。
背景(という名の言い訳)
この機能を実装したときは、開発リースが限られる中で、PMF(Product Market Fit)を優先してる時期でした。
そのため、設計上シンプルにできるsql_variant型を利用したテーブル設計を行いました。
再現コード
CREATE TABLE table (column1 INT, column2 SQL_VARIANT);
GO
INSERT INTO table VALUES
(1,'1'),
(2, 1);
GO
原因解説
これは、SQL Server の複数行 VALUES 句における型推論ルールが原因です。
複数行を一括INSERTする場合、すべての行で同じ型に揃える必要があります。
異なる型が混在している場合、SQL Server は「型の優先順位」に基づいて、全ての値を単一の型に暗黙的に変換します。
(これはUNION ALL構文でも同じことが言えます。)
型ごとに優先順位が決められています。
おおざっぱには、日付→数値→文字列の順になります。
上記のケースだと、'1'が数値(int)の1に自動で変換されます。
対策
1行ずつINSERTする
この方法だと型推論が行われず1件ずつINSERTすることが可能です。
INSERT INTO table VALUES (1,'1');
INSERT INTO table VALUES (2, 1);
そもそも設計を見直す
短期的な対策としては上記でしのげますが、このままだと同じ問題が再発しかねません。
当時はあまり普及していなかったAIに、今だとどのような提案をしてもらえるかを確認してみたいと思います。
設計の見直し案(AI)
AI | 見解 | 理由 | 改善策 |
---|---|---|---|
Gemini(2.5Pro) | 「利用は見直し、改善することを強く推奨します」 | 「保守性の低下」「パフォーマンスへの悪影響」 | 「データ型ごとに専用の列を用意する」 |
ChatGPT(5) | 「短期的なPoCや移行期間中などならアリだけど、出口戦略を必ず用意したうえで使うべき」 | 「保守性の低下」「制約や検証ロジックをDB側で持ちづらい」「将来の拡張時に複雑化」「ORMとの相性が悪い」「フルテキスト検索・パーティショニングなど一部機能が使えない」 | 「型ごとにカラム分けする」「型と値をJSONで保持」「設定値型別テーブルに分割」 |
Claude(Sonnet4) | 「型安全性とパフォーマンスの観点から改善すべきであり、移行を推奨します。」 | 「型安全性の欠如」「パフォーマンスの懸念」「運用・保守性の課題」 | 「設定値型別テーブルに分割(EAVパターン)」「型と値をJSONで保持」 |
AIによる違い
Gemini: 根本的な解決を強く推奨
ChatGPT: 短期的な利用を許容しつつも、「出口戦略」という長期的な視点でのアドバイスがユニーク
Claude: 「型安全性」や「運用・保守性」といった、より広範な観点からリスクを指摘している。
特にGTPとClaudeは、移行戦略やマイグレーションの提案まで行ない寄り添ってくれました。
どの手法を採用するべきかどうかは、開発するシステムの特性やフェーズによって変わると思います。
将来の設計の更新頻度、検索・集計の重要性、改修コスト、開発フェーズなどによって自身にとって適切な手法を採用するとよいと思います。
最後に
再設計の必要性は多くのエンジニアが感じることでしょう。
しかし、現実にはさまざまな事情からすぐに着手できないケースも多いはずです。
重要なのは、その負債を放置するのではなく、移行のための戦略を立て、それを定期的に見直しすることです。
- いつまでに、どのような状態にするのか?(移行の条件や期間)
- 具体的な手順はどうするのか?(移行スクリプトの作成)
- この負債を改修する場合のコストはどれくらいか?(数値化)
こうした具体的な戦略を立てることこそが、プロダクトを健全に成長させるための第一歩だと考えています。
Discussion