質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

バッチファイルでの文字列の置換処理を高速にしたい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 598
退会済みユーザー

退会済みユーザー

前提・実現したいこと

バッチファイルにて、SQLPLUSを実行しCSVファイルを作成。その後、作成したCSVファイル内の特定の文字列を置換する、という処理を実現させたいと考えています。
置換処理は、「特定の値を持つのカラムのみ囲み文字を削る」というものです。

CSVファイル出力直後・置換前
"CODE","NAME","AGE","SEX","OTHER"
"0001","太郎",20,"male","XXX"
"0002","花子",21,"female","XXX"
"0003","一郎",22,"male","YYY"

上記のうち、"XXX"をXXXに置換

置換後
"CODE","NAME","AGE","SEX","OTHER"
"0001","太郎",20,"male",XXX
"0002","花子",21,"female",XXX
"0003","一郎",22,"male","YYY"

発生している問題・エラーメッセージ

下記のソースコードで処理自体は実現できているのですが、出力されるCSVファイルのサイズが非常に大きく、文字列置換処理でかなり時間がかかってしまっているので、それを解消したいのです。

置換処理は「特定の値を持つのカラムのみ囲み文字を削る」というものであるため、SQLのREPLACEなどでも対応できません。また、「特定の値」はカラムが限定できません。

該当のソースコード

@echo off
@setlocal enabledelayedexpansion

rem 実行したバッチファイルと同フォルダにある*.sqlファイルを順次処理
for /F %%a in ('dir *.sql /B') do (set sql_filename=%%a&& call :execute_sql)

rem 出力したCSVファイルを順次処理
for /F %%a in ('dir *.csv /B') do (set fname=%%a&& call :tmp_csv)

rem 処理終了
goto end

rem sql実行
:execute_sql
    rem 作成するCSVファイル名
    set CSV_FILE_PATH=%sql_filename:~0,-4%.csv

    sqlplus -s -m "csv on" ORAUSER/ORAPASS@ORAHOST/ORASERVICE %sql_filename% !CSV_FILE_PATH!
    goto :EOF

rem CSVワークファイル作成
:tmp_csv
    rem ワークファイル作成
    copy %fname% tmp_csvfile >nul
    type nul >%fname%

    rem 1行ごとに置換
    for /f "delims=" %%a in ( tmp_csvfile ) do (set line=%%a&& call :replace_str)

    del /f tmp_csvfile
    goto :EOF

rem 置換
:replace_str
    rem CSVファイル内の"AAA"という文字列をAAAに変換
    set l=%line:"AAA"=AAA%
    >>%fname% echo %l%
    goto :EOF

:end

試したこと

置換処理部分を別のバッチファイルにしてみましたが、結局1行ごとに処理する部分は変わりないので、あまり差は出ませんでした。
申し訳ありませんが、諸事情により、フリーのソフトなどはできるだけ使いたくない状況です。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

ヘディングのテキスト> ...出力されるCSVファイルのサイズが非常に大きく、文字列置換処理でかなり時間がかかってしまっている...

何件のデータで、どんな置換をやっていて、どのくらいの時間がかかっている、といった情報が提示されていた適切なコメントが付きそうです。

通常、Database Server はそれなりに高性能のハードウェアを用意するはずなので、とりあえず、SELECT時にREPLACE命令で置換した結果をCSVにしてみては?

追記

SQL> SELECT REPLACE('"XXX"', '"XXX"', 'XXX') AS REPLACED FROM DUAL;

REPLAC
------
XXX

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/06 11:02

    ありがとうございます。前後してしまったかもしれませんが、具体的な置換処理を記載しました。
    データ件数としては100万~200万レコードであり、現状でかかっている時間は2時間半~3時間になります。
    (SQLの実行自体は5分程度になります)

    キャンセル

  • 2020/06/06 11:28

    回答を追記しました。
    最初の回答でSQL言語リファレンスでREPLACEの使い方くらい自分で調べられると思っていたのですが。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る