※ この記事にはアフィリエイトリンクが含まれます
C#でデータベースとやり取りする際、こんなふうに思ったことはありませんか?
「ユーザーが入力した値をSQLに入れて検索したい」
「変数を使ってINSERTやUPDATEをしたい」
プログラムからデータベースに命令を出すなら、変数をクエリに埋め込むというのは避けて通れません。でも、ここでひとつだけ、気をつけてほしいことがあります。
それは、「やり方を間違えると、思わぬバグやセキュリティの穴につながる」ということ。
実際、SQLに変数をそのまま文字列で組み込んでしまうと、SQLインジェクションと呼ばれる攻撃の対象になってしまうことがあります。これは、プログラムに悪意のあるSQL文を紛れ込ませることで、データが抜き取られたり、最悪の場合、削除されたりするような非常に危険なものです。
ですが、ご安心ください。
C#では、きちんと「安全に変数を埋め込む」ための方法が用意されています。それが、パラメータ化クエリという考え方です。
この記事では、次のことを丁寧に解説していきます。
これからSQLを使っていく方にも、すでに使っているけれど「なんとなく」でやっていた方にも、ぜひ知っていただきたい内容になっています。
それでは、実際にコードを見ながら進めていきましょう。
C#は、業務系のシステムやWindowsアプリ開発など、企業現場で広く使われている言語です。独学でもある程度学べますが、「しっかりとしたカリキュラムで基礎から学びたい」「開発経験を積みたい」と考える方も多いのではないでしょうか。
そんな方におすすめなのが、未経験からエンジニア転職を目指せる「DMM WEBCAMP エンジニア転職」です。

C#に特化しているわけではありませんが、企業でよく使われるJavaやWeb技術と並行して、.NET系技術を扱う現場を視野に入れた学び方も可能です。

文字列連結でクエリを書くとどうなる?
さて、ここでありがちなコードの例をひとつご紹介します。もしかしたら、あなたもこんなふうに書いたことがあるかもしれません。
string userName = "tanaka";
string sql = "SELECT * FROM Users WHERE Name = '" + userName + "'";
ぱっと見、とてもわかりやすいコードですよね。
文字列をつなげて、userName
の値をSQL文に直接埋め込んでいます。
でも――これは絶対にやってはいけません。
なぜかというと、この書き方には深刻なセキュリティリスクがあるからです。
それが「SQLインジェクション」と呼ばれる問題です。
たとえば、次のような悪意ある文字列を変数 userName
に入力されたとしましょう。
' OR '1'='1
すると、生成されるSQL文はこうなります。
SELECT * FROM Users WHERE Name = '' OR '1'='1'
このSQL、よく見るとすべてのユーザーが取得されてしまう内容になっているのがわかります。'1'='1'
は常に真(true)になる条件なので、ユーザー名に関係なく、全レコードが返ってきてしまうんです。
さらに悪質なケースでは、削除系のクエリを挿入される可能性もあります。
'; DROP TABLE Users; --
これが通ってしまえば、Usersテーブルそのものが削除されてしまう可能性も……!
実際、こうした攻撃で情報漏洩やデータ破壊が発生した事例は、少なくありません。
「動くからOK」ではなく「安全かどうか」で判断を
このように、文字列を直接つなげてSQLを作るのは、非常に危険な行為です。
たとえテスト環境でうまく動いていたとしても、ユーザーの入力を扱う本番環境では致命的な穴になります。
だからこそ、C#でSQLを書くときは、「安全に変数を埋め込む」方法を選ぶ必要があります。
では、どう書けば安全なのか?
次のセクションで、正しい方法――「パラメータ化クエリ」について解説していきます。
パラメータ化されたクエリを使おう
危険な書き方を見ていただいたところで、ここからは正しい方法「パラメータ化クエリ」を解説していきます。
C#では SqlCommand
を使って、SQLに変数を安全に渡すことができます。しかも、やり方は思ったより簡単です。
SqlCommand とパラメータの基本形
たとえば、特定のユーザー名で情報を取得する処理は、次のように書けます。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "SELECT * FROM Users WHERE Name = @Name";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@Name", userName);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// レコード処理
}
}
}
}
ポイントはここです。
このようにすることで、ユーザーの入力がそのままSQL文に混入することを防ぎ、SQLインジェクションを確実に回避できます。
AddWithValue の注意点と型を指定する方法
AddWithValue
は手軽ですが、ひとつ注意点があります。
C#の型とSQL Server側の型がうまく一致しない場合、意図しない動作になることがあるのです。
たとえば、数値が文字列として処理されたり、インデックスが効かずにパフォーマンスが悪化することも。
そのため、型を明示的に指定する方法も知っておきましょう。
command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = userName;
この書き方では、
ポイント
安全性とパフォーマンス、両方を大切にするなら、パラメータ化+型指定は基本スキルとして身につけておきたいところです。
INSERTやUPDATEにも変数を使う方法
ここまでで、「パラメータ化クエリ」の基本的な使い方はご理解いただけたかと思います。
ですが、実際の開発では「SELECT文」だけでは終わりませんよね。
ユーザー情報を追加したり、既存のデータを更新したりする――そんな場面でも、もちろん安全な変数の埋め込みが必要です。
ここでは、INSERT文とUPDATE文におけるパラメータ化の使い方をご紹介します。
INSERT文で変数を使う
たとえば、ユーザー名と年齢をデータベースに追加する場合、次のように記述します。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "INSERT INTO Users (Name, Age) VALUES (@Name, @Age)";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
command.ExecuteNonQuery();
}
}
UPDATE文で変数を使う
今度は、指定された名前のユーザーの年齢を更新するケースを見てみましょう。
string sql = "UPDATE Users SET Age = @Age WHERE Name = @Name";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@Age", newAge);
command.Parameters.AddWithValue("@Name", name);
command.ExecuteNonQuery();
}
このように、UPDATE文でも完全に同じ要領でパラメータを使えます。
DELETE文でも同じ考え方でOK
補足ですが、DELETE文でもまったく同じように書けます。
string sql = "DELETE FROM Users WHERE Name = @Name";
command.Parameters.AddWithValue("@Name", name);
どんなSQL文でも、「変数は絶対に文字列連結せず、パラメータで渡す」というルールを守ること。
これが、安全で信頼できるアプリケーションの第一歩です。
まとめ
C#でSQLに変数を埋め込みたいとき、つい文字列をそのままつなげてしまいがちですが、それは非常に危険な書き方です。
なぜなら、ユーザーの入力値をそのままSQLに反映させることで、SQLインジェクションという深刻なセキュリティリスクを生んでしまうからです。
本記事では、そんなリスクを避けるためのパラメータ化クエリの使い方を、以下のポイントに分けてご紹介しました。
覚えておいてほしいのは、「動けばOKではなく、安全に動くかどうか」がこれからの開発ではより大切になるということ。
SQLインジェクションは初心者だけでなく、ベテランでもうっかりやってしまうほど、身近で見落とされやすい問題です。
だからこそ、今このタイミングで「安全な書き方」を身につけたあなたは一歩リードしています。
ぜひ、この記事で学んだことを、明日からのコードに活かしてくださいね。
C#は、堅牢でスケーラブルなアプリケーションを構築できる力強い言語です。将来的にエンジニアとしてキャリアを築きたい方にとっては、非常に価値ある選択肢と言えるでしょう。

もし「本格的に学んで、いずれはエンジニアとして働きたい」とお考えなら、転職サポートが充実した「DMM WEBCAMP エンジニア転職」のようなスクールで学ぶのもおすすめです。

コメント