shinke1987.net
雑多な備忘録等のはず。
他のカテゴリ・タブ
目次
PR

fakerを利用してバルクINSERT文を生成

2023-11-09 2023-11-09
カテゴリ: PHP

概要

fakerを利用してテストデータのバルクINSERT文を生成してみたので、ログとして残す。
実際にDBへ挿入できたのは確認した。
これを参考にfakerのメソッド確認すれば色々なテストデータ挿入用のINSERT文生成できるはず。

コード

<?php

require_once 'vendor/autoload.php';

/**
 * 指定したテーブル名に対する、
 * 指定した列名と値の
 * 実行可能なバルクINSERT文を返す。
 *
 * 配列は次の形をとる。
 * (flagStringがtrueの場合、INSERT文での値はシングルクォーテーションで囲われる。
 *   falseならシングルクォーテーションで囲われない。)
 * $values = [
 *  '列名1' => [
 *      'flagString' => true,
 *      'values' => [
 *          '値1', '値2',
 *      ],
 *  ],
 *   '列名2' => [
 *       'flagString' => false,
 *       'values' => [
 *           '値1', '値2',
 *       ],
 *   ],
 * ];
 *
 * @param string $tableName テーブル名
 * @param array $values 列名と値の連想配列
 * @return string|null 実行可能なINSERT文 または エラー時にはnull
 */
function getInsertQuery(string $tableName, array $values): string|null {
    /**********************************************
     * 引数の確認
     **********************************************/
    // テーブル名が空でないことを確認。
    if ($tableName === '') return null;

    // 空配列でないことを確認。
    if (count($values) === 0) return null;

    // 値の数が全ての列名で等しいことを確認。
    $valueCount = count(array_values($values)[0]['values']);
    foreach($values as $key => $arrays) {
        if($valueCount !== count($arrays['values'])) return null;
    }

    /**********************************************
     * INSERT文の列名まで生成。
     **********************************************/
    $strInsert = 'INSERT INTO ' . $tableName . ' ';

    # INSERT文の列名含む箇所まで作成。
    $keys = array_keys($values);
    $strColumns = '(';
    foreach($keys as $key) {
        $strColumns .= ($key . ', ');
    }
    $strColumns = mb_substr($strColumns, 0, mb_strlen($strColumns) - 2);
    $strColumns .= ') ';
    $strInsert .= $strColumns;
    unset($strColumns);

    /**********************************************
     * INSERT文の値を生成。
     **********************************************/
    $strValues = 'VALUES ';
    $strValuesElement = '';
    for ($i = 0; $i < $valueCount; $i++) {
        if ($i === 0) {
            $strValuesElement .= '(';
        } else {
            $strValuesElement .= ', (';
        }

        foreach ($values as $key => $arrays) {
            if ($arrays['flagString']) {
                $strValuesElement .= "'" . $arrays['values'][$i] . "'";
                $strValuesElement .= ', ';
            } else {
                $strValuesElement .= $arrays['values'][$i];
                $strValuesElement .= ', ';
            }
        }
        unset($key);
        unset($arrays);
        $strValuesElement = mb_substr($strValuesElement, 0, mb_strlen($strValuesElement) - 2);
        $strValuesElement .= ')';
        $strValues .= $strValuesElement;
        $strValuesElement = '';
    }
    $strValues .= ';';

    return $strInsert . $strValues;
}

$faker = Faker\Factory::create('ja_JP');

$temp = [
    'family_name' => [
        'flagString' => true,
        'values' => [],
    ],
    'personal_name' => [
//        'flagString' => false,
        'flagString' => true,
        'values' => [],
    ],
];

for ($i = 0; $i < 1000; $i++) {
    $temp['family_name']['values'][] = $faker->lastName();
    $temp['personal_name']['values'][] = $faker->firstName();
}

$result = getInsertQuery('test', $temp);
printf("%s", $result);
同一カテゴリの記事