LoginSignup
2
2

More than 5 years have passed since last update.

SQL整形ツール

Last updated at Posted at 2018-09-11

ログファイルなどに出力されるSQLを整形する。
主な機能は以下。

・INSERT文、UPDATE文を整形する
・SQL文のカラム名を和名に変更
・キャメル式⇔スネーク式の変換
・大文字⇔小文字の変換

例:INSET文の整形

_C__workspaceLob2_4_7_0_00_JsProject_formatSQL.html (1).png

例:SQL文の「物理名 → 論理名」変換

※「物理名」「論理名」に値を設定しておく必要がある。

_C__workspaceLob2_4_7_0_00_JsProject_formatSQL.html (2).png

以下、コード。

htmlファイル

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<script src="https://cdn.jsdelivr.net/jquery/3.1.0/jquery.min.js"></script>
<script src="js/formatSQL.js"></script>
<link rel="stylesheet" type="text/css" href="css/nomaliza.css">
<link rel="stylesheet" type="text/css" href="css/baseStyle.css">
<title>フォーマットSQL</title>
</head>
<body>

    <div id="header">
        <p>SQL変換ツール</p>
    </div>

    <div id="contents">
        <div id="content-00">
            <div id="b-area-01">
                <button type="button" onclick="exeFormat()">カラム名・値
                    摘出(INSERT or UPDATE のみ対象)</button>
                <button onclick="changeLogicNameToSql()">SQL文 変換(物理名 → 論理名)</button>
            </div>

            <div id="b-area-02">
                <div class="b-area-02-inner">
                    <span>変換先:</span>
                    <!--  -->
                    <select id="targetVal">
                        <option value="formatColumn">SQLカラム名</option>
                        <option value="formatValue">SQL値</option>
                        <option value="physicalName">物理名</option>
                    </select>
                </div>
                <div class="b-area-02-inner">
                    <button onclick="changeTxtType()">キャメル式 ⇔ スネーク式 変換</button>
                    <button onclick="changeUpperLower()">大文字 ⇔ 小文字 変換</button>
                </div>
                <span class="clear"></span>
            </div>

            <div class="b-area-03">
                <button onclick="clearTxtVal()">全てクリア</button>
            </div>

            <span class="clear"></span>
        </div>


        <div id="content-01">
            <div id="base">
                <div>SQL文</div>
                <textarea id="baseSQL" wrap="off"></textarea>
            </div>


            <div id="column">
                <div>SQLカラム名</div>
                <textarea id="formatColumn" wrap="off"></textarea>
            </div>


            <div id="value">
                <div>SQL値</div>
                <textarea id="formatValue" wrap="off"></textarea>
            </div>

            <div id="physicalNameArea">
                <div>物理名</div>
                <textarea id="physicalName" wrap="off"></textarea>
            </div>

            <div id="logicNameArea">
                <div>論理名</div>
                <textarea id="logicName" wrap="off"></textarea>
            </div>

            <span class="clear"></span> <span class="clear"></span>
        </div>

    </div>


</body>
</html> 

JavaScript

formatSQL.js


var insertTxtFlg;
var columnBracketsFlg;
var valFlg;
var valBracketsFlg;

var updateTxtFlg;
var setFlg;
var equalFlg;

/**
 * SQLをフォーマットする
 */
function exeFormat() {

    // 入力されたSQLの改行コードを\nに変換、スペース、シングルコーテーションを削除
    var baseSQL = $('#baseSQL').val() //
    .replace(/\(/g, " ( \n") // ( の後に改行コードを追加
    .replace(/\)/g, " ) \n") // ) の後に改行コードを追加
    // .replace(/\r\n|\r| |,/g, "\n") // 改行コード、スペースを \nに変換
    .replace(/\s|,/g, "\n") // 改行コード、スペースを \nに変換
    .replace(/'/g, ""); //

    initFlg();

    var columnArray = new Array();
    var valArray = new Array();

    // SQLをカラムと値に分ける
    var strList = baseSQL.split('\n');
    strList.some(function(thisTxt) {

        // スペースの削除
        thisTxt = thisTxt.trim();
        if (thisTxt == "") {
            return;
        }

        // INSERT文の整形
        if (divideInsert(thisTxt, columnArray, valArray)) {
            return;
        }

        // UPDATE文の整形
        if (divideUpdate(thisTxt, columnArray, valArray)) {
            return;
        }

    });

    var columnStr = columnArray.join('\r\n');
    if (columnStr.length == 0) {
        columnStr = "カラム名を摘出できません。"
    }
    $('#formatColumn').val(columnStr);

    var valStr = valArray.join('\r\n');
    if (valStr.length == 0) {
        valStr = "値を摘出できません。"
    }
    $('#formatValue').val(valStr);

}

/**
 * SQL文の物理名を論理名に変換する
 *
 * @returns
 */
function changeLogicNameToSql() {

    var physicalNameArray = createArrayTextAreaVal($("#physicalName").val());
    var logicNameArray = createArrayTextAreaVal($("#logicName").val());

    var baseSQL = $("#baseSQL").val();
    var changeSQL = baseSQL.replace(/[\n\|\r\n]/g, "\n ");

    physicalNameArray.some(function(thisTxt, idx) {

        var targetLogicName = logicNameArray[idx];
        if (thisTxt == "" || targetLogicName == "" || !targetLogicName) {
            return;
        }

        var regex = new RegExp(
                "(?<=[ |,|*|\(])" + thisTxt + "(?=[ |,|\n|\r\n|*|\)])", "gi");

        if (changeSQL.match(regex)) {
            changeSQL = changeSQL.replace(regex, logicNameArray[idx])
        }

    });

    changeSQL = changeSQL.replace(/\n /g, "\n");

    $("#baseSQL").val(changeSQL);
}

/**
 * 入力されたSQLの改行コードを正規表現により変換する
 *
 * @returns
 */
function createArrayTextAreaVal(targetVal) {

    var baseVal = targetVal.replace(/\(/g, " ( \n") // ( の後に改行コードを追加
    .replace(/\)/g, " ) \n") // ) の後に改行コードを追加
    // .replace(/\r\n|\r| |,/g, "\n") // 改行コード、スペースを \nに変換
    .replace(/\s|,/g, "\n") // 改行コード、スペースを \nに変換
    .replace(/'/g, "");

    return baseVal.split('\n'); //
}

/**
 * 入力されたSQLの改行コードを正規表現により変換する(元とSQLの形に戻す用)
 *
 * @param targetVal
 * @returns
 */
function createArrayTextAreaValForRevers(targetVal) {

    var baseVal = targetVal.replace(/\r\n|\n/g, " TMP_END_ROW_ELEMENT\n");

    return createArrayTextAreaVal(baseVal);

}

/**
 * フラグの初期化
 */
function initFlg() {
    insertTxtFlg = false;
    columnBracketsFlg = false;
    valFlg = false;
    valBracketsFlg = false;
    updateTxtFlg = false;
    setFlg = false;
    equalFlg = false;
}

/**
 * INSERT文の整形を行う
 *
 * @returns INSERT文の整形結果(ture:insert文の整形済み、false:insert文の整形をしていない)
 */
function divideInsert(thisTxt, columnArray, valArray) {

    if (thisTxt == "INSERT" || thisTxt == "insert") {
        insertTxtFlg = true;
        return true;
    }

    if (insertTxtFlg && thisTxt == "(") {
        columnBracketsFlg = true;
        return true;
    }

    // カラム名のみリストに格納
    if (insertTxtFlg && columnBracketsFlg && thisTxt != ")") {
        columnArray.push(thisTxt);
        return true;
    }

    if (insertTxtFlg && columnBracketsFlg && thisTxt == ")") {
        insertTxtFlg = false;
        columnBracketsFlg = false;
        return true;
    }

    if (thisTxt == "VALUES" || thisTxt == "values") {
        valFlg = true;
        return true;
    }

    if (valFlg && thisTxt == "(") {
        valBracketsFlg = true;
        return true;
    }

    // 値のみリストに格納
    if (valFlg && valBracketsFlg && thisTxt != ")") {
        valArray.push(thisTxt);
        return true;
    }

    if (valFlg && valBracketsFlg && thisTxt == ")") {
        valFlg = false;
        valBracketsFlg = false;
        return true;
    }

    return false;
}

/**
 *
 * @returns UPDATE文の整形結果(ture:insert文の整形済み、false:insert文の整形をしていない)
 */
function divideUpdate(thisTxt, columnArray, valArray) {

    // WHERE句の場合は初期化
    if (thisTxt == "WHERE" || thisTxt == "where") {
        initFlg();
        return true;
    }

    if (thisTxt == "UPDATE" || thisTxt == "update") {
        updateTxtFlg = true;
        return true;
    }

    if (updateTxtFlg && (thisTxt == "SET" || thisTxt == "set")) {
        setFlg = true;
        return true;
    }

    // カラム名のリストに格納
    if (updateTxtFlg && setFlg && !equalFlg && thisTxt != "=") {
        columnArray.push(thisTxt);
        return true;
    }

    // イコールフラグを設定
    if (updateTxtFlg && setFlg && thisTxt == "=") {
        equalFlg = true;
        return true;
    }

    // 値のリストに格納
    if (updateTxtFlg && setFlg && thisTxt && equalFlg) {
        valArray.push(thisTxt);
        equalFlg = false;
        return true;
    }

    return false;
}

/**
 * カラム名の 大文字 ⇔ 小文字 の変換を行う
 */
function changeUpperLower() {

    var targetId = $('#targetVal').val();
    if (!targetId) {
        return;
    }

    var columnStr = $('#' + targetId).val();

    if (columnStr.match(/[A-Z]/g)) {
        columnStr = columnStr.toLowerCase();
    } else {
        columnStr = columnStr.toUpperCase();
    }

    $('#' + targetId).val(columnStr);
}

/**
 * カラム名のスネークケース ⇔ キャメルケース の変換を行う
 */
function changeTxtType() {

    var targetId = $('#targetVal').val();
    if (!targetId) {
        return;
    }

    if ($('#' + targetId).val().match(/_/g)) {
        snakeToCamel(targetId);
    } else {
        camelToSnake(targetId);
    }

}

/*--- スネークケースをキャメルケースにする ---*/
// 返値 文字列(camelCase)
function snakeToCamel(targetId) {

    var camelStrArray = new Array();
    var columnStr = $('#' + targetId).val().split('\n');

    columnStr.some(function(thisTxt) {
        // _+小文字を大文字にする(例:_a を A)
        camelStrArray.push(thisTxt.replace(/_./g, function(s) {
            return s.charAt(1).toUpperCase();
        }));
    });

    $('#' + targetId).val(camelStrArray.join("\r\n"));

}
/*--- キャメルケースをスネークケースにする ---*/
// 返値 文字列(camel_case)
function camelToSnake(targetId) {

    var snakeStrArray = new Array();
    var columnStr = $('#' + targetId).val().split('\n');

    columnStr.some(function(thisTxt) {
        // 大文字を_+小文字にする(例:A を _a)

        var snakeStr = thisTxt.replace(/([A-Z])/g, function(s) {
            return '_' + s.charAt(0).toLowerCase();
        })
        snakeStrArray.push(snakeStr.replace(/^_/g, ""));
    });

    $('#' + targetId).val(snakeStrArray.join("\r\n"));
}

/**
 * 全ての値をクリアする
 *
 * @returns
 */
function clearTxtVal() {
    $('#baseSQL').val("");
    $('#formatColumn').val("");
    $('#formatValue').val("");
    $('#physicalName').val("");
    $('#logicName').val("");
}

Css

baseStyle.css

@charset "UTF-8";

body {
    margin: 10px;
    font-size: 13px;
}

button {
    font-size: 13px;
}

#header, #contents {
    padding: 10px;
}

#content-01>div {
    float: left;
    margin: 10px;
    height: 700px;
}

div#physicalNameArea {
    margin-left: 100px;
}

#content-01 textarea {
    width: 100%;
    height: 97%;
}

#content-01 p {
    height: 5%;
    margin: 0px;
}

#base {
    width: 450px;
}

#column {
    width: 200px;
}

#value {
    width: 200px;
}

#tblNameArea {
    width: 430px;
}

#tblName {
    width: 100%;
}

#tblNameArea div {
    margin: 0px;
}

.clear {
    clear: both;
    display: block;
}

#content-00>div {
    float: left;
    display: inline-block;
}

#b-area-01, #b-area-02, #b-area-03 {
    margin-right: 170px;
}

#b-area-01>button {
    display: block;
    margin-bottom: 10px;
}

.b-area-02-inner {
    float: left;
}

.b-area-02-inner button {
    display: block;
    margin-bottom: 10px;
    margin-left: 10px;
}

nomaliza.css

/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * 1. Add the correct box sizing in Firefox.
 * 2. Show the overflow in Edge and IE.
 */

hr {
  box-sizing: content-box; /* 1 */
  height: 0; /* 1 */
  overflow: visible; /* 2 */
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * Remove the gray background on active links in IE 10.
 */

a {
  background-color: transparent;
}

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Embedded content
   ========================================================================== */

/**
 * Remove the border on images inside links in IE 10.
 */

img {
  border-style: none;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */

button,
input { /* 1 */
  overflow: visible;
}

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * 1. Correct the text wrapping in Edge and IE.
 * 2. Correct the color inheritance from `fieldset` elements in IE.
 * 3. Remove the padding so developers are not caught out when they zero out
 *    `fieldset` elements in all browsers.
 */

legend {
  box-sizing: border-box; /* 1 */
  color: inherit; /* 2 */
  display: table; /* 1 */
  max-width: 100%; /* 1 */
  padding: 0; /* 3 */
  white-space: normal; /* 1 */
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Remove the default vertical scrollbar in IE 10+.
 */

textarea {
  overflow: auto;
}

/**
 * 1. Add the correct box sizing in IE 10.
 * 2. Remove the padding in IE 10.
 */

[type="checkbox"],
[type="radio"] {
  box-sizing: border-box; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge, IE 10+, and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

/* Misc
   ========================================================================== */

/**
 * Add the correct display in IE 10+.
 */

template {
  display: none;
}

/**
 * Add the correct display in IE 10.
 */

[hidden] {
  display: none;
}


2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2