※ この記事にはアフィリエイトリンクが含まれます
OracleでSQLを扱っていると、文字列中にシングルクォート(')が含まれているだけで、突然エラーになってしまうことがあります。
たとえば、次のようなSQLを実行した経験はありませんか?
SELECT * FROM authors WHERE name = 'O'Reilly';一見正しいように見えますが、実際に実行すると次のようなエラーが発生します。
ORA-01756: quoted string not properly terminatedこれは、Oracleがシングルクォートを「文字列の開始と終了」を示す特別な記号として扱っているためです。つまり、途中に' があると、「ここで文字列が終わった」と誤解してしまい、文全体の構文が崩れてしまうのです。
実務では、会社名・人名・コメント文など、文字列の中にシングルクォートが入るケースは珍しくありません。
特に「O’Reilly」(オライリー)「It’s OK」「Children’s」など、英語表記のデータでは頻出です。
この記事では、Oracleで文字列内にシングルクォートが含まれる場合の正しい対処法を、
実際に使えるSQL例とともにわかりやすく解説します。
構文エラーを防ぐだけでなく、安全で保守しやすいSQLを書くためのコツも紹介しますので、ぜひ最後までチェックしてみてください。
対策① クォートを二重にしてエスケープする(基本)
Oracleでは、シングルクォート(')を文字列の中で扱いたい場合、シングルクォートを2つ連続で書くことで「1つの'」として認識させることができます。
つまり、次のように修正すればOKです。
SELECT * FROM authors WHERE name = 'O''Reilly';このように' を'' (二重)にすることで、Oracleはこれを1つのシングルクォート文字として正しく解釈します。結果、構文エラーは発生せず、期待通りの検索結果が得られます。
実務での注意点
この方法はSQLを直接書く場合には非常にシンプルで便利ですが、アプリケーションからSQLを組み立てる場合には注意が必要です。
例えば、C#やJavaなどで次のようにSQL文字列を連結していると・・・
string name = "O'Reilly";
string sql = "SELECT * FROM authors WHERE name = '" + name + "'";この状態でSQLを実行すると、Oracleは 'O' の部分で途切れてエラーになります。
したがって、アプリ側で ' を '' に置き換える前処理をしておく必要があります。
string name = "O'Reilly".Replace("'", "''");
string sql = "SELECT * FROM authors WHERE name = '" + name + "'";これで、SQLとして安全に実行できるようになります。
対策② REPLACE関数で自動置換する
次に紹介するのは、OracleのREPLACE関数を使って、文字列中のシングルクォートを自動的に二重化(エスケープ)する方法です。
基本構文
REPLACE(文字列, 検索文字, 置換文字)たとえば、'O'Reilly' という文字列を正しく扱う場合、次のように書けます。
SELECT REPLACE('O'Reilly', '''', '''''') AS safe_text FROM dual;実行結果
O''Reillyこのように、REPLACE関数を使うことで、
文字列中に含まれるシングルクォート(')を 自動的に '' に変換 できます。
注意点
この方法は「一時的なSQL実行」や「簡単な置換テスト」では便利ですが、
常用するのはおすすめしません。
理由は以下の通りです。
| 問題点 | 内容 |
|---|---|
| 可読性が下がる | SQL文が複雑になり、保守が難しくなる |
| パフォーマンス低下 | 毎回REPLACEを実行するため |
| セキュリティ対応としては不十分 | SQLインジェクションを完全に防ぐわけではない |
この方法が向いてるケース
- SQL文を一時的に直接実行する場面(例:SQL*Plus、SQL Developerでのテスト)
- バッチ処理などで「特定の列をクリーンアップしたい」とき
- データ登録時に
'を安全な形に変換したい場合
対策③ バインド変数を使う(推奨)
Oracleでシングルクォートを安全に扱う、最も確実で実務的な方法が「バインド変数」を使うやり方です。
バインド変数とは、SQL文内で値を直接書くのではなく、プレースホルダ(変数)として指定し、後から値を安全に渡す仕組みのことです。
基本構文
SELECT * FROM authors WHERE name = :name;上記の:nameの部分に、アプリケーションコード側から文字列をバインド(結びつけ)します。
たとえば、値に "O'Reilly" を設定しても、Oracleが内部で自動的にエスケープ処理を行うため、構文エラーにはなりません。
実際の利用例(C#の場合)
string sql = "SELECT * FROM authors WHERE name = :name";
OracleCommand cmd = new OracleCommand(sql, connection);
cmd.Parameters.Add(new OracleParameter(":name", "O'Reilly"));
OracleDataReader reader = cmd.ExecuteReader();このようにバインド変数を使えば、文字列にどんな記号が含まれていても安全にSQLが実行されます。
しかも、' を '' に置換するような前処理は不要です。
他の言語でも同様に対応可能
| 言語 | 使用方法 |
|---|---|
| Java | PreparedStatement の setString() を使用 |
| Python | cursor.execute(sql, [value]) の引数として渡す |
| PHP | PDOStatement::bindValue() を使用 |
どの言語でも共通して、バインド変数を使うとOracleが自動的に文字列を安全化してくれます。
セキュリティ面も重要
バインド変数を使うことで、SQLインジェクション攻撃の防止にもつながります。
たとえば、悪意あるユーザーが以下のような入力を行った場合、
' OR '1'='1これを文字列連結でSQLに埋め込むと、全件検索されてしまう危険性があります。
しかし、バインド変数を使っていれば、Oracleがその文字列を単なるデータとして扱うため、攻撃は成立しません。
まとめ
実務では「入力値をSQLにそのまま埋め込む」ことが原因で、
意図しないエラーや、最悪の場合はSQLインジェクションのリスクを生むこともあります。
そのため、文字列の扱いは「安全第一」を意識しましょう。
特に、アプリケーション開発では バインド変数の利用 が最も推奨される方法です。
今後さらに Oracle の知識を深めたい方は、実務で役立つ書籍やトレーニングを活用しながら体系的に学ぶのがおすすめです。私がおすすめする書籍を紹介します。
図解入門よくわかる 最新Oracleデータベースの基本と仕組み
図解で解説されている箇所が多く、初心者が全体像を理解するのに最適です。
Oracleの現場を効率化する100の技
初心者からベテランまで、経験レベルを問わず活用できる一冊で、Oracle Databaseユーザー必携の実践書 といえます。
忙しい現場でも、効率的に学びながら実践できる点が魅力。
データベーススキルを活かしてキャリアを広げたい方は、エンジニア転職サイトを活用するのも一つの手です。おすすめの転職サイトをまとめた記事がありますので、ぜひご覧ください。

コメント