MySQL 8.0 リファレンスマニュアル


13.2.10.1 SELECT ... INTO ステートメント

SELECTSELECT ... INTO 形式を使用すると、クエリー結果を変数に格納したり、ファイルに書き込んだりできます。

  • SELECT ... INTO var_list はカラム値を選択し、それらを変数に格納します。

  • SELECT ... INTO OUTFILE は、選択された行をファイルに書き込みます。 カラムおよび行ターミネータを指定すると、特定の出力形式を生成できます。

  • SELECT ... INTO DUMPFILE は、単一行をファイルに形式設定なしで書き込みます。

特定の SELECT ステートメントには最大で 1 つの INTO 句を含めることができますが、SELECT 構文の説明 (セクション13.2.10「SELECT ステートメント」 を参照) に示されているように、INTO は異なる位置に配置できます:

  • FROM より前。 例:

    SELECT * INTO @myvar FROM t1;
  • 後続のロック句の前。 例:

    SELECT * FROM t1 INTO @myvar FOR UPDATE;
  • SELECT の最後。 例:

    SELECT * FROM t1 FOR UPDATE INTO @myvar;

ステートメントの最後の INTO 位置は、MySQL 8.0.20 でサポートされており、推奨位置です。 ロック句の前の位置は、MySQL 8.0.20 では非推奨です。将来のバージョンの MySQL ではサポートされなくなる予定です。 つまり、FROM の後には INTO が生成されますが、SELECT の最後には生成されません。

ネストされた SELECT はその結果を外側のコンテキストに返す必要があるため、このような SELECT では INTO 句を使用してはいけません。 UNION ステートメント内での INTO の使用には制約もあります。セクション13.2.10.3「UNION 句」 を参照してください。

INTO var_list バリアントの場合:

  • var_list では、1 つ以上の変数のリストに名前を付けます。各変数には、ユーザー定義変数、ストアドプロシージャまたはストアドファンクションパラメータ、ストアドプログラムのローカル変数を指定できます。 (準備された SELECT ... INTO var_list ステートメント内では、ユーザー定義の変数のみが許可されます。セクション13.6.4.2「ローカル変数のスコープと解決」 を参照してください。)

  • 選択された値は変数に割り当てられます。 変数の数がカラム数に一致している必要があります。 クエリーは、単一行を返すようにしてください。 クエリーが行を返さない場合は、エラーコード 1329 で警告が発生し (No data)、変数値は変更されないままになります。 クエリーが複数の行を返す場合は、エラー 1172 が発生します (結果が 2 行以上です)。 このステートメントが複数の行を取得する可能性がある場合は、LIMIT 1 を使用して結果セットを単一行に制限できます。

    SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;

INTO var_list は、TABLE ステートメントとともに使用することもできますが、次の制限があります:

  • 変数の数は、テーブルのカラムの数と一致する必要があります。

  • テーブルに複数の行が含まれる場合は、LIMIT 1 を使用して結果セットを単一行に制限する必要があります。 LIMIT 1 は、INTO キーワードの前に指定する必要があります。

このようなステートメントの例を次に示します:

TABLE employees ORDER BY lname DESC LIMIT 1
    INTO @id, @fname, @lname, @hired, @separated, @job_code, @store_id;

単一行を一連のユーザー変数に生成する VALUES ステートメントから値を選択することもできます。 この場合、テーブルのエイリアスを使用し、値リストの各値を変数に割り当てる必要があります。 ここに示す 2 つのステートメントはそれぞれ、SET @x=2, @y=4, @z=8 と同等です:

SELECT * FROM (VALUES ROW(2,4,8)) AS t INTO @x,@y,@z;

SELECT * FROM (VALUES ROW(2,4,8)) AS t(a,b,c) INTO @x,@y,@z;

ユーザー変数名では大/小文字は区別されません。 セクション9.4「ユーザー定義変数」を参照してください。

SELECTSELECT ... INTO OUTFILE 'file_name' 形式は、選択された行をファイルに書き込みます。 ファイルはサーバーホストに作成されるため、この構文を使用するには FILE 権限が必要です。file_name は既存のファイルにすることはできません。特に、/etc/passwd やデータベーステーブルなどのファイルが変更されるのを防ぎます。 character_set_filesystem システム変数は、ファイル名の解釈を制御します。

SELECT ... INTO OUTFILE ステートメントは、サーバーホスト上のテキストファイルへのテーブルのダンプを有効にすることを目的としています。 結果のファイルを他のホストに作成する場合、サーバーホストファイルシステム上のネットワークマップパスを使用してリモートホスト上のファイルの場所にアクセスできないかぎり、サーバーホストファイルシステムを基準にした相対パスをファイルに書き込む方法がないため、SELECT ... INTO OUTFILE は通常は適していません。

または、MySQL クライアントソフトウェアがリモートホストにインストールされている場合は、mysql -e "SELECT ..." > file_name などのクライアントコマンドを使用して、そのホストにファイルを生成できます。

SELECT ... INTO OUTFILE は、LOAD DATA を補完したものです。 カラム値は、CHARACTER SET 句で指定されている文字セットに変換されて書き込まれます。 このような句が存在しない場合、値は binary 文字セットを使用してダンプされます。 事実上、文字セットの変換は実行されません。 結果セットに複数の文字セットのカラムが含まれている場合は、出力データファイルであるため、ファイルを正しくリロードできない可能性があります。

ステートメントの export_options 部分の構文は、LOAD DATA ステートメントで使用されるものと同じ FIELDS 句および LINES 句で構成されます。 デフォルト値や許容値など、FIELDS 句および LINES 句の詳細は、セクション13.2.7「LOAD DATA ステートメント」 を参照してください。

FIELDS ESCAPED BY は、特殊文字を書き込む方法を制御します。 FIELDS ESCAPED BY 文字が空でない場合、その文字は、出力上で次の文字の前に付けられるプリフィクスとして、あいまいさを避けるために必要な場合に使用されます。

  • FIELDS ESCAPED BY 文字

  • FIELDS [OPTIONALLY] ENCLOSED BY 文字

  • FIELDS TERMINATED BY および LINES TERMINATED BY 値の最初の文字

  • ASCII NUL (0 の値のバイト。エスケープ文字のあとに実際に書き込まれる文字は 0 の値のバイトではなく、ASCII の0です)

FIELDS TERMINATED BYENCLOSED BYESCAPED BY、または LINES TERMINATED BY 文字は、そのファイルを確実に読み戻すことができるように、エスケープする必要があります。 ASCII NUL は、一部のページャーで見やすくなるようにエスケープされます。

結果のファイルは SQL 構文に準拠する必要がないため、他にエスケープする必要はありません。

FIELDS ESCAPED BY 文字が空である場合は、どの文字もエスケープされず、NULL\N ではなく、NULL として出力されます。 特に、データ内のフィールド値に今指定したリスト内のいずれかの文字が含まれている場合、空のエスケープ文字を指定することはおそらく適切な方法ではありません。

テーブルのすべてのカラムをテキストファイルにダンプする場合は、INTO OUTFILETABLE ステートメントとともに使用することもできます。 この場合、ORDER BY および LIMIT を使用して順序付けと行数を制御できます。これらの句は、INTO OUTFILE の前に指定する必要があります。 TABLE ... INTO OUTFILE では、SELECT ... INTO OUTFILE と同じ export_options がサポートされており、ファイルシステムへの書込みには同じ制限があります。 このようなステートメントの例を次に示します:

TABLE employees ORDER BY lname LIMIT 1000
    INTO OUTFILE '/tmp/employee_data_1.txt'
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"', ESCAPED BY '\'
    LINES TERMINATED BY '\n';

SELECT ... INTO OUTFILEVALUES ステートメントとともに使用して、値をファイルに直接書き込むこともできます。 次に例を示します:

SELECT * FROM (VALUES ROW(1,2,3),ROW(4,5,6),ROW(7,8,9)) AS t
    INTO OUTFILE '/tmp/select-values.txt';

テーブルのエイリアスを使用する必要があります。カラムのエイリアスもサポートされており、オプションで目的のカラムからのみ値を書き込むために使用できます。 SELECT ... INTO OUTFILE でサポートされているエクスポートオプションのいずれかまたはすべてを使用して、出力をファイルにフォーマットすることもできます。

多くのプログラムで使用されているカンマ区切り値 (CSV) 形式のファイルを生成する例を次に示します。

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

INTO OUTFILE の代わりに INTO DUMPFILE を使用した場合、MySQL はエスケープ処理を実行することなく、カラムや行の終了のない 1 行のみをファイルに書き込みます。 これは、BLOB 値を選択してファイルに格納する場合に便利です。

TABLE は、INTO DUMPFILE もサポートしています。 テーブルに複数の行が含まれている場合は、LIMIT 1 を使用して出力を単一行に制限する必要もあります。 INTO DUMPFILE は、SELECT * FROM (VALUES ROW()[, ...]) AS table_alias [LIMIT 1]とともに使用することもできます。 セクション13.2.14「VALUES ステートメント」を参照してください。

注記

INTO OUTFILE または INTO DUMPFILE によって作成されたファイルは、アカウント mysqld が実行されているオペレーティングシステムユーザーによって所有されます。 (これらの理由のために、mysqldroot としては決して実行しないでください。) MySQL 8.0.17 では、ファイル作成の umask は 0640 です。ファイルの内容を操作するには、十分なアクセス権限が必要です。 MySQL 8.0.17 より前では、umask は 0666 で、ファイルはサーバーホスト上のすべてのユーザーによって書き込み可能です。

secure_file_priv システム変数が空以外のディレクトリ名に設定されている場合、書き込まれるファイルはそのディレクトリ内に存在する必要があります。

イベントスケジューラによって実行されるイベントの一部として実行された SELECT ... INTO ステートメントのコンテキストでは、診断メッセージ (エラーだけでなく、警告も含みます) がエラーログに (Windows ではアプリケーションイベントログにも) 書き込まれます。 詳細は、セクション25.4.5「イベントスケジューラのステータス」を参照してください。

MySQL 8.0.22 の時点では、SELECT INTO OUTFILE および SELECT INTO DUMPFILE によって書き込まれた出力ファイルの定期的な同期がサポートされており、そのバージョンで導入された select_into_disk_sync サーバーシステム変数を設定することで有効になります。 出力バッファサイズおよびオプションの遅延は、それぞれ select_into_buffer_size および select_into_disk_sync_delay を使用して設定できます。 詳細は、これらのシステム変数の説明を参照してください。


関連キーワード:  ステートメント, INTO, CREATE, TABLE, 変数, DROP, OUTFILE, 文字, カラム, テーブル