Oracle には文字列を操作するための関数が豊富に用意されています。ゼロ埋め・桁合わせ・特定文字の検索・不要文字の一括置換・文字コード変換など、帳票出力・データクレンジング・CSVパース等の実務でよく使われます。
この記事では SUBSTR・LENGTH・TRIM・REGEXP_* など別記事で解説済みの関数を除き、実務でよく使うが解説が少ない関数を中心にまとめます。
- LPAD / RPAD:左右の桁埋め・整形
- INSTR:文字列内の位置検索(後方検索・n番目の出現も)
- REPLACE:文字列の置換(NULL による削除も)
- TRANSLATE:文字の一対一マッピング置換・削除
- CHR / ASCII:文字コード ⇔ 文字の変換
- UPPER / LOWER / INITCAP:大文字小文字変換
- CONCAT / || :文字列連結と NULL の注意点
- 文字列関数クイックリファレンス
LPAD / RPAD:桁を揃える・ゼロ埋め・右詰め
LPAD(str, n, pad) は文字列 str を長さ n になるよう、左側を pad で埋めます。RPAD は右側に埋めます。ゼロ埋め・スペース整形・固定長フォーマット生成でよく使います。
-- LPAD(str, n, pad): str の左を pad で埋めて全体を n 文字にする
SELECT
LPAD('42', 6, '0') AS zero_pad, -- '000042'
LPAD('ABC', 10) AS space_pad, -- ' ABC'(pad 省略=半角スペース)
LPAD('TOOLONG', 4, '0') AS truncated, -- 'TOOL'(n より長い場合は左から切り捨て)
RPAD('ABC', 8, '-') AS right_pad, -- 'ABC-----'
RPAD('ABC', 8) AS right_space -- 'ABC '
FROM DUAL;
-- ゼロ埋めの実務例:コード値を固定6桁に整形
SELECT
product_code,
LPAD(product_code, 6, '0') AS formatted_code
FROM products;
-- 進捗バーの生成(RPAD の応用)
SELECT
task_name,
pct_done,
'[' || RPAD(RPAD('', ROUND(pct_done / 10), '#'), 10, '-') || '] '
|| pct_done || '%' AS progress_bar
FROM tasks;
-- 例: [######----] 60%
LPAD の長さ n は文字数ではなくNLS_LENGTH_SEMANTICS の設定(BYTE または CHAR)に依存します。日本語を含む場合は LPADБ が意図通りに動かないことがあるため、固定長整形は英数字に限定するか、バイト数を意識した設計が必要です。
INSTR:文字列内の位置を検索する
INSTR(str, substr, start, n) は str の中で substr が何文字目に現れるかを返します。見つからない場合は 0 を返します(NULL ではないので注意)。start で検索開始位置を、n で何番目の出現を返すかを指定できます。
-- INSTR(str, substr [, start [, n]])
SELECT
INSTR('HELLO WORLD', 'O') AS first_o, -- 5
INSTR('HELLO WORLD', 'O', 6) AS o_from6, -- 8(6文字目以降で最初のO)
INSTR('HELLO WORLD', 'O', 1, 2) AS second_o, -- 8(1文字目から2番目のO)
INSTR('HELLO WORLD', 'Z') AS not_found, -- 0(見つからない場合は0)
INSTR('HELLO WORLD', 'O', -1) AS backward -- 8(start が負 = 後ろから検索)
FROM DUAL;
-- 実務例①: CSV の特定フィールドを切り出す
-- 'TANAKA,TARO,30' から2番目のカンマ以降を取得
SELECT
SUBSTR('TANAKA,TARO,30',
INSTR('TANAKA,TARO,30', ',', 1, 2) + 1) AS age_field -- '30'
FROM DUAL;
-- 実務例②: ファイルパスからファイル名を取得
SELECT
file_path,
SUBSTR(file_path, INSTR(file_path, '/', -1) + 1) AS file_name
FROM file_log;
-- 例: '/home/user/data/report.csv' → 'report.csv'
-- 実務例③: 検索ヒットした行のみ取得(INSTR > 0 で WHERE 絞り込み)
SELECT product_name
FROM products
WHERE INSTR(UPPER(product_name), 'PRO') > 0;
-- LIKE '%PRO%' より柔軟な検索(start/n で制御可能)
REPLACE:文字列を置換・削除する
REPLACE(str, search, replacement) は str の中の search をすべて replacement に置換します。replacement を省略(または NULL)にすると search を削除できます。
SELECT
REPLACE('Hello World', 'World', 'Oracle') AS basic, -- 'Hello Oracle'
REPLACE('A-B-C-D', '-', '/') AS delimiter, -- 'A/B/C/D'
REPLACE('AAABBBCCC', 'B', '') AS delete_b, -- 'AAACCC'(空文字で置換=削除)
REPLACE('AAABBBCCC', 'B') AS delete_b2 -- 'AAACCC'(NULL で置換も削除)
FROM DUAL;
-- 実務例①: 全角スペースを半角スペースに統一
SELECT
REPLACE(REPLACE(customer_name,
CHR(12288), ' '), -- 全角スペース(U+3000) → 半角
' ', ' ') -- 連続スペースを1つに
AS clean_name
FROM customers;
-- 実務例②: カンマ区切りを別の区切りに変換
SELECT REPLACE(tag_list, ',', ' | ') AS formatted_tags FROM articles;
-- 実務例③: 電話番号のハイフン・スペースを除去
SELECT REPLACE(REPLACE(phone_number, '-', ''), ' ', '') AS clean_phone
FROM contacts;
TRANSLATE:文字を一対一でマッピング置換する
TRANSLATE(str, from_chars, to_chars) は str の中の文字を、from_chars の各文字を to_chars の対応する位置の文字に1文字ずつ置換します。REPLACE が「文字列単位」なのに対し、TRANSLATE は文字単位の置換です。from_chars に含まれるが to_chars に対応がない文字は削除されます。
-- TRANSLATE(str, from_chars, to_chars)
-- from_chars の各文字 → to_chars の対応文字に1対1で置換
SELECT
TRANSLATE('Hello World', 'aeiou', 'AEIOU') AS vowel_upper, -- 'HEllO WOrld'
TRANSLATE('ABC123DEF', 'ABCDEF', 'abcdef') AS lower_alpha, -- 'abc123def'
-- from_chars に余分な文字があると削除される
TRANSLATE('A1B2C3', 'ABC', 'abc') AS delete_nums -- 'a b c'ではなく'abc'に1,2,3が削除される
FROM DUAL;
-- 実務例①: 数字以外の文字をすべて除去(電話番号クレンジング)
-- TRANSLATE のトリック: to_chars を1文字短くして先頭1文字だけ生き残らせる
SELECT
phone_number,
-- '0' を基準文字にして保持し、英字・記号(ABC...-() )を削除対象に
TRANSLATE(phone_number,
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -+().',
'0123456789') AS digits_only
FROM contacts;
-- 実務例②: 全角数字を半角数字に変換
SELECT
TRANSLATE(price_str,
'0123456789', -- 全角数字
'0123456789') -- 半角数字
AS half_price
FROM items;
| 観点 | REPLACE | TRANSLATE |
|---|---|---|
| 置換の単位 | 文字列(部分一致) | 文字(1文字ずつ) |
| 複数の置換 | 1種類ずつ。複数は REPLACE を入れ子にする | 1回の呼び出しで複数文字を一括置換 |
| 文字の削除 | replacement を NULL や空文字にする | to_chars に対応がない文字は自動削除 |
| 主な用途 | 単語・フレーズの置き換え | 文字コード変換・特定文字の除去・全角半角変換 |
CHR / ASCII:文字コードと文字を相互変換する
CHR(n) は文字コード n に対応する文字を返します。ASCII(str) は str の先頭1文字の文字コード(数値)を返します。改行コード・タブ・制御文字の挿入や除去でよく使います。
-- CHR(n): 文字コード → 文字
SELECT
CHR(65) AS char_a, -- 'A'(ASCII 65)
CHR(97) AS char_a2, -- 'a'(ASCII 97)
CHR(10) AS lf, -- 改行(LF、Line Feed)
CHR(13) AS cr, -- キャリッジリターン(CR)
CHR(9) AS tab, -- タブ
CHR(12288) AS zenkaku_sp -- 全角スペース(U+3000)※NLS_CHARACTERSET が UTF8/AL32UTF8 の場合
FROM DUAL;
-- ASCII(str): 文字 → 文字コード(先頭1文字のみ)
SELECT
ASCII('A') AS code_a, -- 65
ASCII('ABC') AS code_abc, -- 65(先頭のAのコードのみ)
ASCII(' ') AS code_sp -- 32
FROM DUAL;
-- 実務例①: 改行コードを除去する(REPLACE + CHR)
SELECT
REPLACE(REPLACE(memo, CHR(13) || CHR(10), ' '), -- CRLF → スペース
CHR(10), ' ') -- LF → スペース
AS single_line_memo
FROM notes;
-- 実務例②: タブ区切りデータを整形する
SELECT REPLACE(raw_data, CHR(9), ',') AS csv_format FROM import_log;
-- 実務例③: 制御文字(印字不可文字)を一括除去
-- ASCII コードが 32 未満の制御文字をスペースに置換
SELECT REGEXP_REPLACE(data_col, '[' || CHR(0) || '-' || CHR(31) || ']', '') AS clean_data
FROM raw_data;
UPPER / LOWER / INITCAP:大文字小文字の変換
SELECT
UPPER('hello world') AS upper_case, -- 'HELLO WORLD'
LOWER('HELLO WORLD') AS lower_case, -- 'hello world'
INITCAP('hello world') AS title_case, -- 'Hello World'
INITCAP('oracle sql 23ai guide') AS title2 -- 'Oracle Sql 23Ai Guide'
FROM DUAL;
-- 実務例①: 大文字小文字を無視した検索
SELECT employee_id, last_name
FROM employees
WHERE UPPER(last_name) = UPPER(:search_name);
-- インデックスを有効にするには関数ベースインデックスを作成:
-- CREATE INDEX idx_emp_upper ON employees (UPPER(last_name));
-- 実務例②: 氏名の正規化(入力値を統一フォーマットに)
SELECT
INITCAP(TRIM(LOWER(full_name))) AS normalized_name
FROM customers;
-- 'TANAKA taro ' → 'Tanaka Taro'
INITCAP はアルファベット以外の文字(数字・記号・スペース・アンダースコア等)を「単語の区切り」として認識します。そのため oracle_sql → Oracle_Sql、23ai → 23Ai のように変換されます。日本語には効果がありません。
CONCAT / || :文字列連結と NULL の扱い
-- || 演算子(推奨): 複数の値を連結。NULL を連結すると無視される
SELECT
'Hello' || ' ' || 'World' AS concat_op, -- 'Hello World'
'Hello' || NULL || 'World' AS with_null, -- 'HelloWorld'(NULLは無視)
NULL || NULL AS null_null -- NULL
FROM DUAL;
-- CONCAT 関数: 引数は2つのみ。3つ以上は入れ子にするか || を使う
SELECT
CONCAT('Hello', ' World') AS two_args, -- 'Hello World'
CONCAT(CONCAT('A', 'B'), 'C') AS three_args -- 'ABC'(入れ子)
FROM DUAL;
-- 実務例: 氏名・住所の連結(NULL セーフな結合)
SELECT
last_name || ' ' || first_name AS full_name,
-- prefecture が NULL の場合に余分なスペースが入らないようにする
NVL2(prefecture, prefecture || ' ', '') || city AS address
FROM customers;
文字列関数クイックリファレンス
| 関数 | 構文 | 説明 | 例(結果) |
|---|---|---|---|
LPAD |
LPAD(str,n,pad) | 左を pad で埋めて n 文字に | LPAD(‘7′,3,’0’) → ‘007’ |
RPAD |
RPAD(str,n,pad) | 右を pad で埋めて n 文字に | RPAD(‘A’,4,’-‘) → ‘A—‘ |
INSTR |
INSTR(str,sub,start,n) | 部分文字列の位置を返す(なければ0) | INSTR(‘ABC’,’B’) → 2 |
REPLACE |
REPLACE(str,src,dst) | 文字列を置換(dst省略で削除) | REPLACE(‘AB’,’A’,’X’) → ‘XB’ |
TRANSLATE |
TRANSLATE(str,from,to) | 文字を1対1でマッピング変換 | TRANSLATE(‘abc’,’abc’,’ABC’) → ‘ABC’ |
CHR |
CHR(n) | 文字コード → 文字 | CHR(65) → ‘A’ |
ASCII |
ASCII(str) | 先頭1文字のコードを返す | ASCII(‘A’) → 65 |
UPPER |
UPPER(str) | 大文字に変換 | UPPER(‘hello’) → ‘HELLO’ |
LOWER |
LOWER(str) | 小文字に変換 | LOWER(‘HELLO’) → ‘hello’ |
INITCAP |
INITCAP(str) | 各単語の先頭を大文字に | INITCAP(‘hello world’) → ‘Hello World’ |
CONCAT |
CONCAT(str1,str2) | 2つの文字列を連結(|| の方が汎用的) | CONCAT(‘A’,’B’) → ‘AB’ |
SUBSTR |
SUBSTR(str,pos,len) | 部分文字列を切り出す | SUBSTR(‘ABCDE’,2,3) → ‘BCD’ |
LENGTH |
LENGTH(str) | 文字数を返す | LENGTH(‘ABC’) → 3 |
TRIM |
TRIM([chars FROM] str) | 前後の文字を除去(省略=スペース) | TRIM(‘ AB ‘) → ‘AB’ |
まとめ
- LPAD / RPAD:固定長フォーマット・ゼロ埋め・帳票整形に必須
- INSTR:
LIKEでは難しい「n番目の出現」「後方検索」に対応。結果が0かどうかで存在チェックにも使える - REPLACE:文字列単位の置換・削除。複数の置換は入れ子にする
- TRANSLATE:文字単位の一括変換。全角→半角変換・数字以外の除去に強力
- CHR / ASCII:改行(CHR(10))・タブ(CHR(9))の操作に必須。制御文字除去にも使う
- INITCAP:人名・タイトルの正規化。区切り文字の直後の文字を大文字にする
- 文字列連結は
||演算子が推奨。NULL を含んでも連結がつながるため、NULL チェックはNVL2で別途行う
正規表現を使った高度な文字列操作はOracle 正規表現(REGEXP)関数の使い方完全ガイドを、文字列の切り出しにはSUBSTR 関数の使い方も参照してください。

