it-swarm.com.de

Header bei Verwendung von SELECT INTO OUTFILE einbeziehen?

Kann ich bei Verwendung des MySQL-Codes INTO OUTFILE die Header irgendwie einfügen?

96
Brett

Sie müssten diese Header selbst hart codieren. So etwas wie:

SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
    FROM YourTable
    INTO OUTFILE '/path/outfile'
135
Joe Stefanelli

Die von Joe Steanelli bereitgestellte Lösung funktioniert, aber das Erstellen einer Spaltenliste ist unpraktisch, wenn Dutzende oder Hunderte von Spalten beteiligt sind. So erhalten Sie eine Spaltenliste der Tabelle my_table in my_schema .

-- override GROUP_CONCAT limit of 1024 characters to avoid a truncated result
set session group_concat_max_len = 1000000;

select GROUP_CONCAT(CONCAT("'",COLUMN_NAME,"'"))
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'my_table'
AND TABLE_SCHEMA = 'my_schema'
order BY ORDINAL_POSITION

Jetzt können Sie die resultierende Zeile als erste Anweisung in Joes Methode kopieren und einfügen.

72
matt

Für komplexe Auswahl mit ORDER BY verwende ich Folgendes:

SELECT * FROM (
    SELECT 'Column name #1', 'Column name #2', 'Column name ##'
    UNION ALL
    (
        // complex SELECT statement with WHERE, ORDER BY, GROUP BY etc.
    )
) resulting_set
INTO OUTFILE '/path/to/file';
12
evilguc

Dadurch können Sie Spalten und/oder ein Limit bestellen

SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT * from (SELECT ColName1, ColName2, ColName3
    FROM YourTable order by ColName1 limit 3) a
    INTO OUTFILE '/path/outfile';
5
Donald Wagner

Sie können die vorbereitete Anweisung mit der Antwort von lucek verwenden und die Tabelle mit Spaltennamen in CSV dynamisch exportieren:

--If your table has too many columns
SET GLOBAL group_concat_max_len = 100000000;
--Prepared statement
SET @SQL = ( select CONCAT('SELECT * INTO OUTFILE \'YOUR_PATH\' FIELDS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'"\' ESCAPED BY \'\' LINES TERMINATED BY \'\\n\' FROM (SELECT ', GROUP_CONCAT(CONCAT("'",COLUMN_NAME,"'")),' UNION select * from YOUR_TABLE) as tmp') from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'YOUR_TABLE' AND TABLE_SCHEMA = 'YOUR_SCHEMA' order BY ORDINAL_POSITION );
--Execute it
PREPARE stmt FROM @SQL;
EXECUTE stmt;

Danke lucek.

5
Vrag

Ich mache einfach zwei Abfragen, erstens, um die Abfrage-Ausgabe (Grenzwert 1) mit Spaltennamen (kein Hardcode, keine Probleme mit Joins, Sortieren nach, benutzerdefinierte Spaltennamen usw.) abzurufen, und zweitens, um die Abfrage selbst zu erstellen und Dateien zu einer CSV zu kombinieren Datei:

CSVHEAD=`/usr/bin/mysql $CONNECTION_STRING -e "$QUERY limit 1;"|head -n1|xargs|sed -e "s/ /'\;'/g"`
echo "\'$CSVHEAD\'" > $TMP/head.txt
/usr/bin/mysql $CONNECTION_STRING -e "$QUERY into outfile '${TMP}/data.txt' fields terminated by ';' optionally enclosed by '\"' escaped by '' lines terminated by '\r\n';"
cat $TMP/head.txt $TMP/data.txt > $TMP/data.csv
5
user3037511

Bei der Ausführung der mysql-Abfrage für große Tabellen in NodeJS war ich mit einem ähnlichen Problem konfrontiert. Der Ansatz, dem ich folgte, um Kopfzeilen in meine CSV-Datei aufzunehmen, ist wie folgt

  1. Verwenden Sie die OUTFILE-Abfrage, um eine Datei ohne Header vorzubereiten

        SELECT * INTO OUTFILE [FILE_NAME] FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED 
        BY '\"' LINES TERMINATED BY '\n' FROM [TABLE_NAME]
    
  2. Ruft Spaltenüberschriften für die in Punkt 1 verwendete Tabelle ab

        select GROUP_CONCAT(CONCAT(\"\",COLUMN_NAME,\"\")) as col_names from 
        INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = [TABLE_NAME] AND TABLE_SCHEMA 
        = [DATABASE_NAME] ORDER BY ORDINAL_POSITION
    
  3. Hängen Sie die Spaltenüberschriften an die in Schritt 1 erstellte Datei mithilfe des Pakets prepend-file npm an

Die Ausführung jedes Schrittes wurde mit Versprechungen in NodeJS gesteuert.

3
rahul shukla

Dies ist ein alternativer Cheat, wenn Sie mit Python oder R vertraut sind und Ihre Tabelle in den Speicher passen kann. 

Importieren Sie die SQL-Tabelle in Python oder R und exportieren Sie sie von dort als CSV. Anschließend werden die Spaltennamen und die Daten angezeigt.

So mache ich es mit R, erfordert die RMySQL-Bibliothek:

db <- dbConnect(MySQL(), user='user', password='password', dbname='myschema', Host='localhost')

query <- dbSendQuery(db, "select * from mytable")
dataset <- fetch(query, n=-1)

write.csv(dataset, 'mytable_backup.csv')

Es ist ein bisschen ein Schummel, aber ich fand, dass dies eine schnelle Abhilfe war, wenn meine Anzahl von Spalten zu lang war, um die Concat-Methode oben zu verwenden. Hinweis: R fügt am Anfang der CSV eine Spalte 'row.names' hinzu. Wenn Sie also die Tabelle neu erstellen müssen, sollten Sie diese löschen.

3
Joining Dots

Da die 'include-headers'-Funktionalität noch nicht eingebaut zu sein scheint und die meisten "Lösungen" hier die Spaltennamen manuell eingeben müssen und/oder Joins gar nicht berücksichtigen, würde ich dies empfehlen Problem umgehen.

  • Die beste Alternative, die ich bisher gefunden habe, ist die Verwendung eines anständigen Tools (ich benutze HeidiSQL) .
    Stellen Sie Ihre Anfrage, wählen Sie das Raster aus, klicken Sie mit der rechten Maustaste und exportieren Sie es in eine Datei. Es hat alle notwendigen Optionen für einen sauberen Export und sollte die meisten Anforderungen erfüllen.

  • In der gleichen Idee funktioniert der Ansatz von user3037511 gut und kann leicht zu automatisieren..__ sein.
    Starten Sie einfach Ihre Anfrage mit einer Befehlszeile, um Ihre Kopfzeilen abzurufen. Sie erhalten die Daten möglicherweise mit SELECT INTO OUTFILE ... oder indem Sie Ihre Abfrage ohne Begrenzung ausführen.

    Beachten Sie, dass die Ausgabeumleitung in eine Datei sowohl unter Linux als auch unter Windows wie ein Zauber wirkt.


Deshalb möchte ich hervorheben, dass 80% der Zeit, wenn ich SELECT FROM INFILE oder SELECT INTO OUTFILE verwenden möchte, am Ende etwas anderes verwendet habe aufgrund einiger Einschränkungen (hier die Fehlen einer 'Header-Option', bei einem AWS-RDS die fehlenden Rechte usw.)

Daher antworte ich nicht genau auf die Frage question ... der op, aber sie sollte ihre needs:).) beantworten. 
EDIT: und um seine Frage tatsächlich zu beantworten: nein
Seit dem 07.09.2017 können Sie keine Kopfzeilen einschließen, wenn Sie den SELECT INTO OUTFILE-Befehl
: | beibehalten

1
Balmipour

Also, wenn alle Spalten in my_table ein Zeichendatentyp sind, können wir die ersten Antworten (von Joe, Matt und Evilguc) zusammenfassen, um den Header automatisch in einer "einfachen" SQL-Abfrage hinzufügen zu lassen. z.B.

select * from (
  (select column_name
    from information_schema.columns
    where table_name = 'my_table'
    and table_schema = 'my_schema'
    order by ordinal_position)
  union all
  (select *  // potentially complex SELECT statement with WHERE, ORDER BY, GROUP BY etc.
  from my_table)) as tbl
into outfile '/path/outfile'
fields terminated by ',' optionally enclosed by '"' escaped by '\\'
lines terminated by '\n';

wo die letzten Zeilen die Ausgabe csv machen.

Beachten Sie, dass dies langsam sein kann, wenn my_table sehr groß ist.

1
TheBamf

ein Beispiel aus meiner Datenbank Tabellenname Sensor mit Spalten (ID, Zeit, Einheit)

select ('id') as id, ('time') as time, ('unit') as unit
UNION ALL
SELECT * INTO OUTFILE 'C:/Users/User/Downloads/data.csv'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM sensor
1
Dayanand SK

Ich schrieb meinen Code in PHP und hatte einige Probleme bei der Verwendung von Concat- und Union-Funktionen. Außerdem wurden keine SQL-Variablen verwendet.

//first I connected to the information_scheme DB

$headercon=mysqli_connect("localhost", "USERNAME", "PASSWORD", "information_schema");

//took the healders out in a string (I could not get the concat function to work, so I wrote a loop for it)

    $headers = '';
    $sql = "SELECT column_name AS columns FROM `COLUMNS` WHERE table_schema = 'YOUR_DB_NAME' AND table_name = 'YOUR_TABLE_NAME'";
    $result = $headercon->query($sql);
    while($row = $result->fetch_row())
    {
        $headers = $headers . "'" . $row[0] . "', ";
    }
$headers = substr("$headers", 0, -2);

// connect to the DB of interest

$con=mysqli_connect("localhost", "USERNAME", "PASSWORD", "YOUR_DB_NAME");

// export the results to csv
$sql4 = "SELECT $headers UNION SELECT * FROM YOUR_TABLE_NAME WHERE ... INTO OUTFILE '/output.csv' FIELDS TERMINATED BY ','";
$result4 = $con->query($sql4);
0
user5671922

Ich möchte die Antwort von Sangam Belose hinzufügen. Hier ist sein Code:

select ('id') as id, ('time') as time, ('unit') as unit
UNION ALL
SELECT * INTO OUTFILE 'C:/Users/User/Downloads/data.csv'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM sensor

Wenn Sie Ihren "secure_file_priv" jedoch nicht in den Variablen eingerichtet haben, funktioniert er möglicherweise nicht. Überprüfen Sie dazu den Ordner, der für diese Variable festgelegt ist:

SHOW VARIABLES LIKE "secure_file_priv"

Die Ausgabe sollte so aussehen:

mysql> show variables like "%secure_file_priv%";
+------------------+------------------------------------------------+
| Variable_name    | Value                                          |
+------------------+------------------------------------------------+
| secure_file_priv | C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\ |
+------------------+------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

Sie können diese Variable entweder ändern oder die Abfrage so ändern, dass die Datei im angezeigten Standardpfad ausgegeben wird.

0
RGregg

MySQL allein reicht nicht aus, um dies einfach zu tun. Unten ist ein PHP Skript, das Spalten und Daten an CSV ausgibt.

Geben Sie oben Ihren Datenbanknamen und Ihre Tabellen ein.

<?php

set_time_limit( 24192000 );
ini_set( 'memory_limit', '-1' );
setlocale( LC_CTYPE, 'en_US.UTF-8' );
mb_regex_encoding( 'UTF-8' );

$dbn = 'DB_NAME';
$tbls = array(
'TABLE1',
'TABLE2',
'TABLE3'
);

$db = new PDO( 'mysql:Host=localhost;dbname=' . $dbn . ';charset=UTF8', 'root', 'pass' );

foreach( $tbls as $tbl )
{
    echo $tbl . "\n";
    $path = '/var/lib/mysql/' . $tbl . '.csv';

    $colStr = '';
    $cols = $db->query( 'SELECT COLUMN_NAME AS `column` FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "' . $tbl . '" AND TABLE_SCHEMA = "' . $dbn . '"' )->fetchAll( PDO::FETCH_COLUMN );
    foreach( $cols as $col )
    {
        if( $colStr ) $colStr .= ', ';
        $colStr .= '"' . $col . '"';
    }

    $db->query(
    'SELECT *
    FROM
    (
        SELECT ' . $colStr . '
        UNION ALL
        SELECT * FROM ' . $tbl . '
    ) AS sub
    INTO OUTFILE "' . $path . '"
    FIELDS TERMINATED BY ","
    ENCLOSED BY "\""
    LINES TERMINATED BY "\n"'
    );

    exec( 'gzip ' . $path );

    print_r( $db->errorInfo() );
}

?>

Dies muss das Verzeichnis sein, in das Sie ausgeben möchten. MySQL muss in der Lage sein, in das Verzeichnis zu schreiben.

$path = '/var/lib/mysql/' . $tbl . '.csv';

Sie können die CSV-Exportoptionen in der Abfrage bearbeiten:

INTO OUTFILE "' . $path . '"
FIELDS TERMINATED BY ","
ENCLOSED BY "\""
LINES TERMINATED BY "\n"'

Am Ende gibt es einen Exec-Aufruf an GZip der CSV.

0
Kohjah Breese

Eigentlich kann man es sogar mit einer ORDER BY-Funktion schaffen.

Benötigt nur einige Tricksereien in der Anweisung order by - wir verwenden eine case-Anweisung und ersetzen den Header-Wert durch einen anderen Wert, der garantiert als erstes in der Liste sortiert wird (natürlich hängt dies vom Typ des Felds und davon ab, ob Sie ASC oder sortieren) DESC)

Angenommen, Sie haben drei Felder, name (varchar), is_active (bool), date_something_happens (date), und Sie möchten die zweiten beiden absteigend sortieren:

select 
        'name'
      , 'is_active' as is_active
      , date_something_happens as 'date_something_happens'

 union all

 select name, is_active, date_something_happens

 from
    my_table

 order by
     (case is_active when 'is_active' then 0 else is_active end) desc
   , (case date when 'date' then '9999-12-30' else date end) desc
0
Simon Woolf

Ich denke, wenn Sie eine UNION verwenden, wird es funktionieren:

select 'header 1', 'header 2', ...
union
select col1, col2, ... from ...

Ich kenne keine Möglichkeit, die Header direkt mit der INTO OUTFILE-Syntax anzugeben.

0
Paul W

Hier können Sie die Überschriften der Spaltennamen dynamisch ermitteln. 

/* Change table_name and database_name */
SET @table_name = 'table_name';
SET @table_schema = 'database_name';
SET @default_group_concat_max_len = (SELECT @@group_concat_max_len);

/* Sets Group Concat Max Limit larger for tables with a lot of columns */
SET SESSION group_concat_max_len = 1000000;

SET @col_names = (
  SELECT GROUP_CONCAT(QUOTE(`column_name`)) AS columns
  FROM information_schema.columns
  WHERE table_schema = @table_schema
  AND table_name = @table_name);

SET @cols = CONCAT('(SELECT ', @col_names, ')');

SET @query = CONCAT('(SELECT * FROM ', @table_schema, '.', @table_name,
  ' INTO OUTFILE \'/tmp/your_csv_file.csv\'
  FIELDS ENCLOSED BY \'\\\'\' TERMINATED BY \'\t\' ESCAPED BY \'\'
  LINES TERMINATED BY \'\n\')');

/* Concatenates column names to query */
SET @sql = CONCAT(@cols, ' UNION ALL ', @query);

/* Resets Group Contact Max Limit back to original value */
SET SESSION group_concat_max_len = @default_group_concat_max_len;

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
0
RNickMcCandless