テーブルを csv で出力する。psql の機能を使う。
もしくは、シェルから psql のオプションを利用してクエリを送って実行する。
下記の例では指定していないが、カラム名を出力させたくなければ -t オプションを加えれば良い。
- SQL の結果を出力したいとき
\pset format unaligned -- 出力形式を指定
\pset fieldsep ',' -- フィールドのセパレータにカンマ区切りを指定
\o psql_out.csv -- 出力ファイルを指定
ここに SQL を書く
もしくは、シェルから psql のオプションを利用してクエリを送って実行する。
下記の例では指定していないが、カラム名を出力させたくなければ -t オプションを加えれば良い。
$ psql -c 'SELECT user_id, user_name FROM users ORDER BY user_id;' -A -F,
- テーブルをまるごと出力したいとき。
SQL で SELECT * FROM TABLE_NAME をやってもいいけど、以下のようなやり方もある。COPY system_name TO '/tmp/system_name_tabale.txt' DELIMITERS ',';
- 参考
psql (PostgreSQL) 7.2.1 のヘルプ。$ psql --help
This is psql, the PostgreSQL interactive terminal.
Usage:
psql [options] [dbname [username]]
Options:
-a Echo all input from script
-A Unaligned table output mode (-P format=unaligned)
-c COMMAND Run only single command (SQL or internal) and exit
-d DBNAME Specify database name to connect to (default: tka)
-e Echo commands sent to server
-E Display queries that internal commands generate
-f FILENAME Execute commands from file, then exit
-F STRING Set field separator (default: "|") (-P fieldsep=)
-h HOSTNAME Specify database server host (default: local socket)
-H HTML table output mode (-P format=html)
-l List available databases, then exit
-n Disable enhanced command line editing (readline)
-o FILENAME Send query results to file (or |pipe)
-p PORT Specify database server port (default: 5432)
-P VAR[=ARG] Set printing option 'VAR' to 'ARG' (see \pset command)
-q Run quietly (no messages, only query output)
-R STRING Set record separator (default: newline) (-P recordsep=)
-s Single step mode (confirm each query)
-S Single line mode (end of line terminates SQL command)
-t Print rows only (-P tuples_only)
-T TEXT Set HTML table tag attributes (width, border) (-P tableattr=)
-U NAME Specify database user name (default: tka)
-v NAME=VALUE Set psql variable 'NAME' to 'VALUE'
-V Show version information and exit
-W Prompt for password (should happen automatically)
-x Turn on expanded table output (-P expanded)
-X Do not read startup file (~/.psqlrc)
For more information, type "\?" (for internal commands) or "\help"
(for SQL commands) from within psql, or consult the psql section in
the PostgreSQL documentation.
Report bugs to <pgsql-bugs@postgresql.org>.
- fnumber を使ってカラム名を添字に変換する
print $result->getvalue(0, $result->fnumber('serialnum'));
- 無名ハッシュの配列にマッピングする。
my @sql_result = get_sql_result($result);
print $sql_result[0]->{'ao_cd'};
# SQL の実行結果を結果をハッシュの配列にして返す
sub get_sql_result($) {
my $result = $_[0];
my $record_nums = $result->ntuples;
my $field_nums = $result->nfields;
my @result_records = ();
for (my $i = 0; $i < $record_nums; $i++) {
my $buf = {};
for (my $j = 0; $j < $field_nums; $j++) {
my $field_name = $result->fname($j);
$buf->{"$field_name"} = $result->getvalue($i, $j);
}
push(@result_records, $buf);
}
return @result_records;
}
「nか月前の月の1日から」という日時範囲指定 SQL。Postgres 提供の関数 date_trunc を使う。
# SELECT date_trunc('month', CURRENT_TIMESTAMP + '-2 month');
date_trunc
------------------------
2002-10-01 00:00:00+09
(1 row)
PHP 4.2.1 で正規表現を使ったとき、以下のエラーを出して apache が落ちる。
正規表現で全角スペースを含む文字列を trim する際にこの問題が出た。
結局、長くなるおそれのある文字列は標準の trim() のみ行う、ということにした。
正規表現で置換するとき、検索対象となる文字列があまりに長い場合にこの現象が起きるようだ。以下、問題を再現できるコード。長いけど。
$ tail -f /var/log/httpd/error_log
[Tue Dec 3 20:58:50 2002] [notice] child pid 6053 exit signal Segmentation fault (11)
正規表現で全角スペースを含む文字列を trim する際にこの問題が出た。
結局、長くなるおそれのある文字列は標準の trim() のみ行う、ということにした。
正規表現で置換するとき、検索対象となる文字列があまりに長い場合にこの現象が起きるようだ。以下、問題を再現できるコード。長いけど。
<?php
$base_str = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">';
$Zspace = '(?:\xA1\xA1)'; // 全角スペース
$ascii = '[\x00-\x7F]'; # 1バイト EUC-JP文字
$twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'; # 2バイト EUC-JP文字
$threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト EUC-JP文字
$character = "(?:$ascii|$twoBytes|$threeBytes)"; # EUC-JP文字
$count = 1000;
$str = '';
for ($i = 0; $i < $count; $i++) {
$str .= $base_str;
}
// $str が EUC-JP の場合
$str = preg_replace("/^($character*?)(?:\s|$Zspace)+$/", "$1", $str);
print htmlspecialchars($str);
?>
n 日前の日付を求める SQL。
例) 2002年12月3日の7日前を求める。
00:00:00 になるのか、SELECT した時刻になるのかは、実装依存?
それとも、SQL の規格で決まってるのかな?
例) 2002年12月3日の7日前を求める。
# SELECT to_date(now() + '-7day', 'YYYY-MM-DD');時刻の部分はどうなるかは、試してみる必要あり。
to_date
------------
2002-11-26
(1 row)
00:00:00 になるのか、SELECT した時刻になるのかは、実装依存?
それとも、SQL の規格で決まってるのかな?