• Aucun résultat trouvé

Controlling mysql Output Destination and Format

Dans le document MySQL Cookbook (Page 45-50)

The Meaning of localhost in MySQL

1.7. Controlling mysql Output Destination and Format

Problem

You want mysql output to go somewhere other than your screen. And you don’t neces‐

sarily want the default output format.

Solution

Redirect the output to a file, or use a pipe to send the output to a program. You can also control other aspects of mysql output to produce tabular, tab-delimited, HTML, or XML output; suppress column headers; or make mysql more or less verbose.

Discussion

Unless you send mysql output elsewhere, it goes to your screen. To save output from mysql in a file, use your shell’s redirection capability:

% mysql cookbook > outputfile

If you run mysql interactively with the output redirected, you can’t see what you type, so in this case you usually also read the input from a file (or another program):

% mysql cookbook < inputfile > outputfile

To send the output to another program (for example, to mail query results to someone), use a pipe:

% mysql cookbook < inputfile | mail paul

The rest of this section shows how to control mysql output format.

Producing tabular or tab-delimited output

mysql chooses its default output format by whether it runs interactively or noninterac‐

tively. For interactive use, mysql writes output to the terminal using tabular (boxed) format:

1.7. Controlling mysql Output Destination and Format | 17

% mysql

mysql> SELECT * FROM limbs WHERE legs=0;

+---+---+---+

| thing | legs | arms | +---+---+---+

| squid | 0 | 10 |

| fish | 0 | 0 |

| phonograph | 0 | 1 | +---+---+---+

3 rows in set (0.00 sec)

For noninteractive use (when the input or output is redirected), mysql writes tab-delimited output:

% echo "SELECT * FROM limbs WHERE legs=0" | mysql cookbook thing legs arms

squid 0 10 fish 0 0

phonograph 0 1

To override the default output format, use the appropriate command option. Consider this command shown earlier:

% mysql cookbook < inputfile | mail paul

Because mysql runs noninteractively in that context, it produces tab-delimited output, which the mail recipient may find more difficult to read than tabular output. Use the -t (or --table) option to produce more readable tabular output:

% mysql -t cookbook < inputfile | mail paul

The inverse operation is to produce batch (tab-delimited) output in interactive mode.

To do this, use -B or --batch. Producing HTML or XML output

mysql generates an HTML table from each query result set if you use the -H (or --html) option. This enables you to easily produce output for inclusion in a web page that shows a query result. Here’s an example (with line breaks added to make the output easier to read):

% mysql -H -e "SELECT * FROM limbs WHERE legs=0" cookbook

<TABLE BORDER=1>

<TR><TH>thing</TH><TH>legs</TH><TH>arms</TH></TR>

<TR><TD>squid</TD><TD>0</TD><TD>10</TD></TR>

<TR><TD>fish</TD><TD>0</TD><TD>0</TD></TR>

<TR><TD>phonograph</TD><TD>0</TD><TD>1</TD></TR>

</TABLE>

The first row of the table contains column headings. If you don’t want a header row, see the next section for instructions.

18 | Chapter 1: Using the mysql Client Program

You can save the output in a file, then view it with a web browser. For example, on Mac OS X, do this:

% mysql -H -e "SELECT * FROM limbs WHERE legs=0" cookbook > limbs.html

% open -a safari limbs.html

To generate an XML document instead of HTML, use the -X (or --xml) option:

% mysql -X -e "SELECT * FROM limbs WHERE legs=0" cookbook

<?xml version="1.0"?>

<resultset statement="select * from limbs where legs=0

">

<row>

<field name="thing">squid</field>

<field name="legs">0</field>

<field name="arms">10</field>

</row>

<row>

<field name="thing">fish</field>

<field name="legs">0</field>

<field name="arms">0</field>

</row>

<row>

<field name="thing">phonograph</field>

<field name="legs">0</field>

<field name="arms">1</field>

</row>

</resultset>

You can reformat XML to suit a variety of purposes by running it through XSLT trans‐

forms. This enables you to use the same input to produce many output formats. Here is a basic transform that produces plain-text output showing the original query, plus the row values separated by commas:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- mysql-xml.xsl: interpret XML-format output from mysql client -->

<xsl:output method="text"/>

<!-- Process rows in each resultset -->

<xsl:template match="resultset">

<xsl:text>Query: </xsl:text>

<xsl:value-of select="@statement"/>

<xsl:value-of select="'&#10;'"/>

<xsl:text>Result set:&#10;</xsl:text>

<xsl:apply-templates select="row"/>

</xsl:template>

1.7. Controlling mysql Output Destination and Format | 19

<!-- Process fields in each row -->

<xsl:template match="row">

<xsl:apply-templates select="field"/>

</xsl:template>

<!-- Display text content of each field -->

<xsl:template match="field">

<xsl:value-of select="."/>

<xsl:choose>

<xsl:when test="position() != last()">

<xsl:text>, </xsl:text> <!-- comma after all but last field -->

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="'&#10;'"/> <!-- newline after last field -->

</xsl:otherwise>

</xsl:choose>

</xsl:template>

</xsl:stylesheet>

Use the transform like this:

% mysql -X -e "SELECT * FROM limbs WHERE legs=0" cookbook \ | xsltproc mysqlxml.xsl

-Query: SELECT * FROM limbs WHERE legs=0 Result set:

squid, 0, 10 fish, 0, 0 phonograph, 0, 1

The -H, --html-X, and --xml options produce output only for statements that generate a result set, not for statements such as INSERT or UPDATE.

To write your own programs that generate XML from query results, see Recipe 11.9. To write web scripts that generate HTML from query results, see Chapter 18.

Suppressing column headings in query output

Tab-delimited format is convenient for generating datafiles for import into other pro‐

grams. However, the first row of output for each query lists the column headings by default, which may not always be what you want. Suppose that a program named sum‐

marize produces descriptive statistics for a column of numbers. If you produce output from mysql to be used with this program, a column header row would throw off the results because summarize would treat it as data. To create output that contains only data values, suppress the header row with the --skip-column-names option:

% mysql --skip-column-names -e "SELECT arms FROM limbs" cookbook | summarize

Specifying the “silent” option (-s or --silent) twice achieves the same effect:

% mysql -ss -e "SELECT arms FROM limbs" cookbook | summarize

20 | Chapter 1: Using the mysql Client Program

Specifying the output column delimiter

In noninteractive mode, mysql separates output columns by tabs and there is no option for specifying the output delimiter. To produce output that uses a different delimiter, postprocess mysql output. Suppose that you want to create an output file for use by a program that expects values to be separated by colon characters (:) rather than tabs.

Under Unix, you can convert tabs to arbitrary delimiters by using a utility such as tr or sed. Any of the following commands change tabs to colons (TAB indicates where you type a tab character):

% mysql cookbook < inputfile | sed -e "s/TAB/:/g" > outputfile

% mysql cookbook < inputfile | tr "TAB" ":" > outputfile

% mysql cookbook < inputfile | tr "\011" ":" > outputfile

The syntax differs among versions of tr; consult your local documentation. Also, some shells use the tab character for special purposes such as filename completion. For such shells, type a literal tab into the command by preceding it with Ctrl-V.

sed is more powerful than tr because it understands regular expressions and permits multiple substitutions. This is useful for producing output in something like comma-separated values (CSV) format, which requires three substitutions:

1. Escape any quote characters that appear in the data by doubling them, so that when you use the resulting CSV file, they won’t be interpreted as column delimiters.

2. Change the tabs to commas.

3. Surround column values with quotes.

sed permits all three substitutions to be performed in a single command line:

% mysql cookbook < inputfile \

| sed -e 's/"/""/g' -e 's/TAB/","/g' -e 's/^/"/' -e 's/$/"/' > outputfile

That’s cryptic, to say the least. You can achieve the same result with other languages that may be easier to read. Here’s a short Perl script that does the same thing as the sed command (it converts tab-delimited input to CSV output), and includes comments to document how it works:

#!/usr/bin/perl

# csv.pl: convert tab-delimited input to comma-separated values output while (<>) # read next input line

{

s/"/""/g; # double quotes within column values s/\t/","/g; # put "," between column values s/^/"/; # add " before the first value s/$/"/; # add " after the last value print; # print the result

}

If you name the script csv.pl, use it like this:

1.7. Controlling mysql Output Destination and Format | 21

% mysql cookbook < inputfile | perl csv.pl > outputfile

tr and sed normally are unavailable under Windows. Perl may be more suitable as a cross-platform solution because it runs under both Unix and Windows. (On Unix sys‐

tems, Perl is usually preinstalled. On Windows, it is freely available for you to install.) Another way to produce CSV output is to use the Perl Text::CSV_XS module, which was designed for that purpose. Recipe 11.5 discusses this module and uses it to construct a general-purpose file reformatter.

Controlling mysql’s verbosity level

When you run mysql noninteractively, not only does the default output format change, but it becomes more terse. For example, mysql doesn’t print row counts or indicate how long statements took to execute. To tell mysql to be more verbose, use -v or --verbose, specifying the option multiple times for increasing verbosity. Try the following commands to see how the output differs:

% echo "SELECT NOW()" | mysql

% echo "SELECT NOW()" | mysql -v

% echo "SELECT NOW()" | mysql -vv

% echo "SELECT NOW()" | mysql -vvv

The counterparts of -v and --verbose are -s and --silent, which also can be used multiple times for increased effect.

Dans le document MySQL Cookbook (Page 45-50)