【Oracle】文字列内のシングルクォーテーション(’)でエラーになる原因と安全な対処法まとめ

※ この記事にはアフィリエイトリンクが含まれます

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が実行されます。
しかも、''' に置換するような前処理は不要です。

他の言語でも同様に対応可能

言語使用方法
JavaPreparedStatementsetString() を使用
Pythoncursor.execute(sql, [value]) の引数として渡す
PHPPDOStatement::bindValue() を使用

どの言語でも共通して、バインド変数を使うとOracleが自動的に文字列を安全化してくれます。

セキュリティ面も重要

バインド変数を使うことで、SQLインジェクション攻撃の防止にもつながります。
たとえば、悪意あるユーザーが以下のような入力を行った場合、

' OR '1'='1

これを文字列連結でSQLに埋め込むと、全件検索されてしまう危険性があります。
しかし、バインド変数を使っていれば、Oracleがその文字列を単なるデータとして扱うため、攻撃は成立しません。

まとめ

実務では「入力値をSQLにそのまま埋め込む」ことが原因で、
意図しないエラーや、最悪の場合はSQLインジェクションのリスクを生むこともあります。

そのため、文字列の扱いは「安全第一」を意識しましょう。
特に、アプリケーション開発では バインド変数の利用 が最も推奨される方法です。

今後さらに Oracle の知識を深めたい方は、実務で役立つ書籍やトレーニングを活用しながら体系的に学ぶのがおすすめです。私がおすすめする書籍を紹介します。

図解入門よくわかる 最新Oracleデータベースの基本と仕組み

図解で解説されている箇所が多く、初心者が全体像を理解するのに最適です。

Oracleの現場を効率化する100の技

初心者からベテランまで、経験レベルを問わず活用できる一冊で、Oracle Databaseユーザー必携の実践書 といえます。
忙しい現場でも、効率的に学びながら実践できる点が魅力。


こうした書籍を手元に置いて、環境構築と並行して学ぶことで理解が一層深まります。

データベーススキルを活かしてキャリアを広げたい方は、エンジニア転職サイトを活用するのも一つの手です。おすすめの転職サイトをまとめた記事がありますので、ぜひご覧ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

沖縄出身のエンジニアです。IT業界で5年以上の経験があり、主にC#やPHPを使って開発を行ってきました。新しい技術にも興味があり、日々学びながらスキルアップを目指しています。

コメント

コメントする

CAPTCHA


目次