1. テーブル、カラム情報

テーブル、カラム情報

シェルスクリプトでMySQLのコマンドやSQLを実行して結果を標準出力に出力する方法についての説明。

  • 全テーブルにdescribeコマンドを実行

  • 指定データベースの全テーブ名を取得して、各テーブルごとにdescribeコマンド実行するサンプル。 各テーブルごとに、テーブル名とdescribeコマンドの結果を出力します。

    #!/bin/bash
    
    if [ "$1" = "" ]; then
        cat <<-EOS
        usage  $0 [db name]
    
    EOS
        exit
    fi
    
    DB=$1
    OPTIONS="-u root -D $DB"
    
    # 指定したデーベースのテーブル名を全て取得
    CMD="echo 'show tables;' | mysql $OPTIONS -N"
    TABLES=(`eval $CMD`)
    
    # 各テーブルごとにdescribeコマンドを実行
    for table in "${TABLES[@]}"
    do
        CMD="echo 'desc $table' | mysql $OPTIONS"
        echo "$table"
        eval "$CMD"
        echo
    done			
    ※上記の結果は1行目にテーブル名の"cond_instances"、2行目に出力項目名、3~4行目にテーブル"cond_instances"のカラム情報・・・と標準出力に出力されます。

    実行はデータベース名を指定します。データベース名が"test_db"の場合、以下のようになります。

    $ sh desc.sh test_db
    user
    Field   Type    Null    Key     Default Extra
    id      int(11) NO      PRI     NULL    auto_increment
    name    varchar(64)     NO              NULL
    user_group_id   int(11) YES             NULL
    
    user_group
    Field   Type    Null    Key     Default Extra
    id      int(11) NO      PRI     NULL    auto_increment
    name    varchar(64)     NO              NULL

  • 全テーブルのカラム情報をCSVで表示

  • 指定データベースの全カラムに対して、テーブル名、カラム名、カラム情報(型、default値等)を出力します。 各カラムは1行で表示し、各項目の区切りはカンマやタブのCSV形式で出力します。

    #!/bin/bash
    
    function usage() {
        cat <<-EOS
            usage: $0 [DB name]
    
    EOS
    }
    
    if [ $# -ne 1 ]; then
        usage
        exit
    fi
    
    
    MYSQL_OPT="-u root"
    
    # 区切り文字の指定
    DELIMITER="\t"
    
    # 一時ファイル
    TMP_FILE="tmp_all_column"
    
    DB=$1
    
    CMD="echo 'use $DB;show tables;' | mysql $MYSQL_OPT | sed '1d'"
    
    FORMAT="awk 'BEGIN {FS=\"\\n\"; RS=\"\"; OFS=\"${DELIMITER}\"} {for(i=3;i<=NF;i++){print \$1, \$i}}'"
    
    LIST_TABLE=(`eval $CMD`)
    
    :> $TMP_FILE
    for table in "${LIST_TABLE[@]}"
    do
        DESC="echo 'use $DB;desc $table' | mysql $MYSQL_OPT"
        echo "$table" >> $TMP_FILE
        eval "$DESC >> $TMP_FILE"
        echo "" >> $TMP_FILE
    done
    
    HEADER=`cat $TMP_FILE | sed -n '2p'`
    echo -e "Table${DELIMITER}${HEADER}"
    cat $TMP_FILE | eval "$FORMAT" | sed -e "s/\t/${DELIMITER}/g"
    rm $TMP_FILE
    上記の区切りはタブになっています。カンマ区切りにする場合は、DELIMITER="," に変更します。

    データベースtest_dbの出力は以下のようになります。(タブ区切り)

    $ sh all_column.sh test_db
    Table   Field   Type    Null    Key     Default Extra
    user    id      int(11) NO      PRI     NULL    auto_increment
    user    name    varchar(64)     NO              NULL
    user    user_group_id   int(11) YES             NULL
    user_group      id      int(11) NO      PRI     NULL    auto_increment
    user_group      name    varchar(64)     NO              NULL

  • TRUNCATEを全テーブルや一部テーブルに実行

  • TRUNCATEを全テーブルや、一部の数テーブルに対して行う場合のスクリプトサンプル。

    #!/bin/sh
    
    function usage() {
        cat <<-EOS
            usage:
              execute: $0 -x
              test:    $0 -t
    
    EOS
    }
    
    if [ $# -ne 2 ]; then
        usage
        exit
    fi
    
    if [ "$1" = '-x' ]; then
        IS_TEST=0
    elif [ "$1" = '-t' ]; then
        IS_TEST=1
    else
        usage
        exit
    fi
    DB=$2
    
    OPTIONS="-u root --show-warnings "
    
    CMD="echo 'USE $DB;show tables;' | mysql $OPTIONS -N"
    SQL=`cat <<-EOS
            use $DB;
            show tables;
    EOS`
    
    # 全テーブルを対象とする場合
    CMD="echo '$SQL' | mysql $OPTIONS -N"
    LIST_TABLE=(`eval $CMD`)
    
    # TRUNCATEを行うテーブルを指定
    #LIST_TABLE=(user user_group)
    
    
    # TRUNCATEから除外するテーブルを指定
    LIST_EXCEPT=(user_group)
    
    for table in "${LIST_TABLE[@]}"
    do
        # 除外テーブルの確認
        is_except=0
        for except in "${LIST_EXCEPT[@]}"
        do
            if [ "$table" = "$except" ]; then
                is_except=1
            fi
        done
        if [ $is_except -eq 1 ]; then
            continue
        fi
    
        # TRUNCATEの実行
        truncate="echo 'USE $DB;TRUNCATE $table;' | mysql $OPTIONS"
        if [ $IS_TEST -eq 0 ]; then
            eval $truncate
        else
            echo -n "test: "
            echo "$truncate"
        fi
    done