db의 반각 전각 변환
93135 단어 PostgreSQLSQLDB금융tech
나는 이것이 흔히 있는 일이라고 생각한다.
특히 금융과 의료 관련 시스템에서 필요한 조건이 되는 경우가 많다.
또 낡은 외부 결제 시스템과 판매 대행사를 이용하면 고객 명부와 상품명은 반각 가명의 csv로 발송되기도 한다.
이 데이터를 반각으로 변환하다↔전각에 너무 신경 쓰지 말고 시스템을 구축하길 바란다.
그러나 응용 프로그램에서 이 처리를 정의하면 다음과 같은 문제가 발생할 수 있다.
결점
또 프로그램을 쓸 때는 지식보다는 종합적인 글자 대책과 반전 처리 등 간단한 프로그래밍 기술이 테스트된 처리이기 때문에 밖으로 던지지 않는 게 좋다고 생각한다.
어떡하죠?
위의 단점은 논리를 저장 주소로 보내고 응용 프로그램에서 참고하면 전체 시스템의 반쪽 가명 논리는 하나만 관리하면 간단해진다는 것이다.
앞으로 한글 등 다른 문자의 전각 반각 지원이 늘어나면 여기에 추가 처리 기능 수정만 하면 끝난다.
User 테이블의 열에서 사용할 때, 생성 열에서 저장 주소를 호출하면, 전각 가나의 데이터로 반각 가나를 표현할 수 있기 때문에 관리도 수월해진다.기존의 시스템이 모두 orm일지라도 orm와 호환성은 그다지 나쁘지 않다.
소스 코드
postgresql의 예는 다음과 같다.
다른 RDBMS도 같은 요령이다.
function에 immutable을 꼭 붙여주세요.
만약 이것이 없다면 DB 변경을 일으키는 부작용을 일으킨 저장소 주소가 있는지
DB 측에서 판별할 수 없기 때문에 생성 열을 사용할 수 없거나 다른 DB 처리에 큰 영향을 미친다.
이는 다른 RDBMS에서도 마찬가지입니다.
hankakukana2zenkaku_strig-> 반각 문자열을 전각 문자열의 저장 주소로 변경
zenkaku2hankakukana_string-> 전체 문자열을 반각 문자열의 저장 주소로 변경
CREATE FUNCTION zenkaku2hankakukana (c CHAR)
RETURNS VARCHAR(2) AS $$
DECLARE
ret VARCHAR(2);
BEGIN
CASE c
-- ア行
WHEN 'ア' THEN
ret := 'ア';
WHEN 'イ' THEN
ret := 'イ';
WHEN 'ウ' THEN
ret := 'ウ';
WHEN 'エ' THEN
ret := 'エ';
WHEN 'オ' THEN
ret := 'オ';
-- カ行
WHEN 'カ' THEN
ret := 'カ';
WHEN 'キ' THEN
ret := 'キ';
WHEN 'ク' THEN
ret := 'ク';
WHEN 'ケ' THEN
ret := 'ケ';
WHEN 'コ' THEN
ret := 'コ';
-- サ行
WHEN 'サ' THEN
ret := 'サ';
WHEN 'シ' THEN
ret := 'シ';
WHEN 'ス' THEN
ret := 'ス';
WHEN 'セ' THEN
ret := 'セ';
WHEN 'ソ' THEN
ret := 'ソ';
-- タ行
WHEN 'タ' THEN
ret := 'タ';
WHEN 'チ' THEN
ret := 'チ';
WHEN 'ツ' THEN
ret := 'ツ';
WHEN 'テ' THEN
ret := 'テ';
WHEN 'ト' THEN
ret := 'ト';
-- ナ行
WHEN 'ナ' THEN
ret := 'ナ';
WHEN 'ニ' THEN
ret := 'ニ';
WHEN 'ヌ' THEN
ret := 'ヌ';
WHEN 'ネ' THEN
ret := 'ネ';
WHEN 'ノ' THEN
ret := 'ノ';
-- ハ行
WHEN 'ハ' THEN
ret := 'ハ';
WHEN 'ヒ' THEN
ret := 'ヒ';
WHEN 'フ' THEN
ret := 'フ';
WHEN 'ヘ' THEN
ret := 'ヘ';
WHEN 'ホ' THEN
ret := 'ホ';
-- マ行
WHEN 'マ' THEN
ret := 'マ';
WHEN 'ミ' THEN
ret := 'ミ';
WHEN 'ム' THEN
ret := 'ム';
WHEN 'メ' THEN
ret := 'メ';
WHEN 'モ' THEN
ret := 'モ';
-- ヤ行
WHEN 'ヤ' THEN
ret := 'ヤ';
WHEN 'ユ' THEN
ret := 'ユ';
WHEN 'ヨ' THEN
ret := 'ヨ';
-- ワ行
WHEN 'ワ' THEN
ret := 'ワ';
WHEN 'ヲ' THEN
ret := 'ヲ';
WHEN 'ン' THEN
ret := 'ン';
-- ガ行
WHEN 'ガ' THEN
ret := 'ガ';
WHEN 'ギ' THEN
ret := 'ギ';
WHEN 'グ' THEN
ret := 'グ';
WHEN 'ゲ' THEN
ret := 'ゲ';
WHEN 'ゴ' THEN
ret := 'ゴ';
-- ザ行
WHEN 'ザ' THEN
ret := 'ザ';
WHEN 'ジ' THEN
ret := 'ジ';
WHEN 'ズ' THEN
ret := 'ズ';
WHEN 'ゼ' THEN
ret := 'ゼ';
WHEN 'ゾ' THEN
ret := 'ゾ';
-- ダ行
WHEN 'ダ' THEN
ret := 'ダ';
WHEN 'ヂ' THEN
ret := 'ヂ';
WHEN 'ヅ' THEN
ret := 'ヅ';
WHEN 'デ' THEN
ret := 'デ';
WHEN 'ド' THEN
ret := 'ド';
-- バ行
WHEN 'バ' THEN
ret := 'バ';
WHEN 'ビ' THEN
ret := 'ビ';
WHEN 'ブ' THEN
ret := 'ブ';
WHEN 'ベ' THEN
ret := 'ベ';
WHEN 'ボ' THEN
ret := 'ボ';
-- パ行
WHEN 'パ' THEN
ret := 'パ';
WHEN 'ピ' THEN
ret := 'ピ';
WHEN 'プ' THEN
ret := 'プ';
WHEN 'ペ' THEN
ret := 'ペ';
WHEN 'ポ' THEN
ret := 'ポ';
-- 小文字
WHEN 'ァ' THEN
ret := 'ァ';
WHEN 'ィ' THEN
ret := 'ィ';
WHEN 'ゥ' THEN
ret := 'ゥ';
WHEN 'ェ' THEN
ret := 'ェ';
WHEN 'ォ' THEN
ret := 'ォ';
WHEN 'ッ' THEN
ret := 'ッ';
WHEN 'ャ' THEN
ret := 'ャ';
WHEN 'ュ' THEN
ret := 'ュ';
WHEN 'ョ' THEN
ret := 'ョ';
-- その他 伸ばし棒ー(マイナスとは違う)
WHEN 'ー' THEN
ret := 'ー';
-- アルファベット
-- 小文字
WHEN 'a' THEN
ret := 'a';
WHEN 'b' THEN
ret := 'b';
WHEN 'c' THEN
ret := 'c';
WHEN 'd' THEN
ret := 'd';
WHEN 'e' THEN
ret := 'e';
WHEN 'f' THEN
ret := 'f';
WHEN 'g' THEN
ret := 'g';
WHEN 'h' THEN
ret := 'h';
WHEN 'i' THEN
ret := 'i';
WHEN 'j' THEN
ret := 'j';
WHEN 'k' THEN
ret := 'k';
WHEN 'l' THEN
ret := 'l';
WHEN 'm' THEN
ret := 'm';
WHEN 'n' THEN
ret := 'n';
WHEN 'o' THEN
ret := 'o';
WHEN 'p' THEN
ret := 'p';
WHEN 'q' THEN
ret := 'q';
WHEN 'r' THEN
ret := 'r';
WHEN 's' THEN
ret := 's';
WHEN 't' THEN
ret := 't';
WHEN 'u' THEN
ret := 'u';
WHEN 'v' THEN
ret := 'v';
WHEN 'w' THEN
ret := 'w';
WHEN 'x' THEN
ret := 'x';
WHEN 'y' THEN
ret := 'y';
WHEN 'z' THEN
ret := 'z';
-- 大文字
WHEN 'A' THEN
ret := 'A';
WHEN 'B' THEN
ret := 'B';
WHEN 'C' THEN
ret := 'C';
WHEN 'D' THEN
ret := 'D';
WHEN 'E' THEN
ret := 'E';
WHEN 'F' THEN
ret := 'F';
WHEN 'G' THEN
ret := 'G';
WHEN 'H' THEN
ret := 'H';
WHEN 'I' THEN
ret := 'I';
WHEN 'J' THEN
ret := 'J';
WHEN 'K' THEN
ret := 'K';
WHEN 'L' THEN
ret := 'L';
WHEN 'M' THEN
ret := 'M';
WHEN 'N' THEN
ret := 'N';
WHEN 'O' THEN
ret := 'O';
WHEN 'P' THEN
ret := 'P';
WHEN 'Q' THEN
ret := 'Q';
WHEN 'R' THEN
ret := 'R';
WHEN 'S' THEN
ret := 'S';
WHEN 'T' THEN
ret := 'T';
WHEN 'U' THEN
ret := 'U';
WHEN 'V' THEN
ret := 'V';
WHEN 'W' THEN
ret := 'W';
WHEN 'X' THEN
ret := 'X';
WHEN 'Y' THEN
ret := 'Y';
WHEN 'Z' THEN
ret := 'Z';
-- 数字
WHEN '0' THEN
ret := '0';
WHEN '1' THEN
ret := '1';
WHEN '2' THEN
ret := '2';
WHEN '3' THEN
ret := '3';
WHEN '4' THEN
ret := '4';
WHEN '5' THEN
ret := '5';
WHEN '6' THEN
ret := '6';
WHEN '7' THEN
ret := '7';
WHEN '8' THEN
ret := '8';
WHEN '9' THEN
ret := '9';
ELSE
-- 定義されていないものはそのまま返す
ret := c;
END CASE;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 全角文字列を半角文字列に変更する関数。
CREATE FUNCTION zenkaku2hankakukana_string (str TEXT)
RETURNS TEXT AS $$
DECLARE
ret TEXT;
i INTEGER := 1;
-- 何文字取るか
cap INTEGER := 1;
BEGIN
WHILE i <= char_length(str)
LOOP
ret := concat(ret, zenkaku2hankakukana(SUBSTRING(str, i, cap)));
-- 取った数だけ進める
i := i + cap;
END LOOP;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 半角を全角に変更する
CREATE FUNCTION hankakukana2zenkaku (c VARCHAR(2))
RETURNS CHAR(1) AS $$
DECLARE
ret CHAR(1);
BEGIN
CASE c
-- ア行
WHEN 'ア' THEN
ret := 'ア';
WHEN 'イ' THEN
ret := 'イ';
WHEN 'ウ' THEN
ret := 'ウ';
WHEN 'エ' THEN
ret := 'エ';
WHEN 'オ' THEN
ret := 'オ';
-- カ行
WHEN 'カ' THEN
ret := 'カ';
WHEN 'キ' THEN
ret := 'キ';
WHEN 'ク' THEN
ret := 'ク';
WHEN 'ケ' THEN
ret := 'ケ';
WHEN 'コ' THEN
ret := 'コ';
-- サ行
WHEN 'サ' THEN
ret := 'サ';
WHEN 'シ' THEN
ret := 'シ';
WHEN 'ス' THEN
ret := 'ス';
WHEN 'セ' THEN
ret := 'セ';
WHEN 'ソ' THEN
ret := 'ソ';
-- タ行
WHEN 'タ' THEN
ret := 'タ';
WHEN 'チ' THEN
ret := 'チ';
WHEN 'ツ' THEN
ret := 'ツ';
WHEN 'テ' THEN
ret := 'テ';
WHEN 'ト' THEN
ret := 'ト';
-- ナ行
WHEN 'ナ' THEN
ret := 'ナ';
WHEN 'ニ' THEN
ret := 'ニ';
WHEN 'ヌ' THEN
ret := 'ヌ';
WHEN 'ネ' THEN
ret := 'ネ';
WHEN 'ノ' THEN
ret := 'ノ';
-- ハ行
WHEN 'ハ' THEN
ret := 'ハ';
WHEN 'ヒ' THEN
ret := 'ヒ';
WHEN 'フ' THEN
ret := 'フ';
WHEN 'ヘ' THEN
ret := 'ヘ';
WHEN 'ホ' THEN
ret := 'ホ';
-- マ行
WHEN 'マ' THEN
ret := 'マ';
WHEN 'ミ' THEN
ret := 'ミ';
WHEN 'ム' THEN
ret := 'ム';
WHEN 'メ' THEN
ret := 'メ';
WHEN 'モ' THEN
ret := 'モ';
-- ヤ行
WHEN 'ヤ' THEN
ret := 'ヤ';
WHEN 'ユ' THEN
ret := 'ユ';
WHEN 'ヨ' THEN
ret := 'ヨ';
-- ワ行
WHEN 'ワ' THEN
ret := 'ワ';
WHEN 'ヲ' THEN
ret := 'ヲ';
WHEN 'ン' THEN
ret := 'ン';
-- ガ行
WHEN 'ガ' THEN
ret := 'ガ';
WHEN 'ギ' THEN
ret := 'ギ';
WHEN 'グ' THEN
ret := 'グ';
WHEN 'ゲ' THEN
ret := 'ゲ';
WHEN 'ゴ' THEN
ret := 'ゴ';
-- ザ行
WHEN 'ザ' THEN
ret := 'ザ';
WHEN 'ジ' THEN
ret := 'ジ';
WHEN 'ズ' THEN
ret := 'ズ';
WHEN 'ゼ' THEN
ret := 'ゼ';
WHEN 'ゾ' THEN
ret := 'ゾ';
-- ダ行
WHEN 'ダ' THEN
ret := 'ダ';
WHEN 'ヂ' THEN
ret := 'ヂ';
WHEN 'ヅ' THEN
ret := 'ヅ';
WHEN 'デ' THEN
ret := 'デ';
WHEN 'ド' THEN
ret := 'ド';
-- バ行
WHEN 'バ' THEN
ret := 'バ';
WHEN 'ビ' THEN
ret := 'ビ';
WHEN 'ブ' THEN
ret := 'ブ';
WHEN 'ベ' THEN
ret := 'ベ';
WHEN 'ボ' THEN
ret := 'ボ';
-- パ行
WHEN 'パ' THEN
ret := 'パ';
WHEN 'ピ' THEN
ret := 'ピ';
WHEN 'プ' THEN
ret := 'プ';
WHEN 'ペ' THEN
ret := 'ペ';
WHEN 'ポ' THEN
ret := 'ポ';
-- 小文字
WHEN 'ァ' THEN
ret := 'ァ';
WHEN 'ィ' THEN
ret := 'ィ';
WHEN 'ゥ' THEN
ret := 'ゥ';
WHEN 'ェ' THEN
ret := 'ェ';
WHEN 'ォ' THEN
ret := 'ォ';
WHEN 'ッ' THEN
ret := 'ッ';
WHEN 'ャ' THEN
ret := 'ャ';
WHEN 'ュ' THEN
ret := 'ュ';
WHEN 'ョ' THEN
ret := 'ョ';
-- その他 伸ばし棒-(マイナス)とは違う
WHEN 'ー' THEN
ret := 'ー';
-- アルファベット
-- 小文字
WHEN 'a' THEN
ret := 'a';
WHEN 'b' THEN
ret := 'b';
WHEN 'c' THEN
ret := 'c';
WHEN 'd' THEN
ret := 'd';
WHEN 'e' THEN
ret := 'e';
WHEN 'f' THEN
ret := 'f';
WHEN 'g' THEN
ret := 'g';
WHEN 'h' THEN
ret := 'h';
WHEN 'i' THEN
ret := 'i';
WHEN 'j' THEN
ret := 'j';
WHEN 'k' THEN
ret := 'k';
WHEN 'l' THEN
ret := 'l';
WHEN 'm' THEN
ret := 'm';
WHEN 'n' THEN
ret := 'n';
WHEN 'o' THEN
ret := 'o';
WHEN 'p' THEN
ret := 'p';
WHEN 'q' THEN
ret := 'q';
WHEN 'r' THEN
ret := 'r';
WHEN 's' THEN
ret := 's';
WHEN 't' THEN
ret := 't';
WHEN 'u' THEN
ret := 'u';
WHEN 'v' THEN
ret := 'v';
WHEN 'w' THEN
ret := 'w';
WHEN 'x' THEN
ret := 'x';
WHEN 'y' THEN
ret := 'y';
WHEN 'z' THEN
ret := 'z';
-- 大文字
WHEN 'A' THEN
ret := 'A';
WHEN 'B' THEN
ret := 'B';
WHEN 'C' THEN
ret := 'C';
WHEN 'D' THEN
ret := 'D';
WHEN 'E' THEN
ret := 'E';
WHEN 'F' THEN
ret := 'F';
WHEN 'G' THEN
ret := 'G';
WHEN 'H' THEN
ret := 'H';
WHEN 'I' THEN
ret := 'I';
WHEN 'J' THEN
ret := 'J';
WHEN 'K' THEN
ret := 'K';
WHEN 'L' THEN
ret := 'L';
WHEN 'M' THEN
ret := 'M';
WHEN 'N' THEN
ret := 'N';
WHEN 'O' THEN
ret := 'O';
WHEN 'P' THEN
ret := 'P';
WHEN 'Q' THEN
ret := 'Q';
WHEN 'R' THEN
ret := 'R';
WHEN 'S' THEN
ret := 'S';
WHEN 'T' THEN
ret := 'T';
WHEN 'U' THEN
ret := 'U';
WHEN 'V' THEN
ret := 'V';
WHEN 'W' THEN
ret := 'W';
WHEN 'X' THEN
ret := 'X';
WHEN 'Y' THEN
ret := 'Y';
WHEN 'Z' THEN
ret := 'Z';
-- 数字
WHEN '0' THEN
ret := '0';
WHEN '1' THEN
ret := '1';
WHEN '2' THEN
ret := '2';
WHEN '3' THEN
ret := '3';
WHEN '4' THEN
ret := '4';
WHEN '5' THEN
ret := '5';
WHEN '6' THEN
ret := '6';
WHEN '7' THEN
ret := '7';
WHEN '8' THEN
ret := '8';
WHEN '9' THEN
ret := '9';
ELSE
-- 定義されていないものはそのまま返す
ret := c;
END CASE;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 合字(二つで一つの文字か判定)
CREATE FUNCTION ligature (c VARCHAR(2))
RETURNS BOOLEAN AS $$
DECLARE
ret BOOLEAN := FALSE;
BEGIN
-- 2文字の時のみ
IF char_length(c) = 2 THEN
-- 濁音、 半濁音は他の音があって初めてなので
-- 実際あるか同時は他の関数に委ねる。漫画などにある表現として「あ」の濁点とかがあるので。
IF Substring(c, 2, 1) IN ('゙', '゚') THEN
ret := TRUE;
END IF;
-- 2文字以上の合字が出たら足して行く。
-- 3文字以上の合字が出たらELSE IF で追加して行く。
END IF;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- 半角文字列を全角文字列に変更する関数。
CREATE FUNCTION hankakukana2zenkaku_string (str TEXT)
RETURNS TEXT AS $$
DECLARE
ret TEXT;
i INTEGER := 1;
-- 何文字取るか
cap INTEGER := 1;
BEGIN
WHILE i <= char_length(str)
LOOP
-- 合字かどうか。
-- 指定の位置から最大二文字取る。
IF ligature(SUBSTRING(str, i, 2)) THEN
-- 2文字で一つの文字なので二文字取る。
cap := 2;
ELSE
cap := 1;
END IF;
ret := concat(ret, hankakukana2zenkaku(SUBSTRING(str, i, cap)));
-- 取った数だけ進める
i := i + cap;
END LOOP;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
사용법
first_name, secound_만약name에 전각 문자열이 있다면
반각 문자열은 잘 출력됩니다.
SELECT
secound_name
,zenkaku2hankakukana_string(secound_name) AS secound_name_kana
,first_name
,zenkaku2hankakukana_string(first_name) AS first_name_kana
FROM users
도 다음 그림과 같이 생성 열에 포함할 수 있습니다.CREATE TABLE users (
id SERIAL NOT NULL,
secound_name varchar(20),
secound_name_kana varchar(20) GENERATED ALWAYS AS (zenkaku2hankakukana_string(secound_name)) STORED
first_name varchar(20),
first_name_kana varchar(20) GENERATED ALWAYS AS (zenkaku2hankakukana_string(first_name)) STORED
);
최신 소스 코드
github에 있어요.
github
Reference
이 문제에 관하여(db의 반각 전각 변환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/oto/articles/a0ff2597803b44텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)