*PostgreSQL「ぽすとぐれすきゅーえる」 [#f8a8e204]
#contents
&tag(PostgreSQL,サンプル,PHP);
**トラブルシューティング [#y8864805]
***Windows版をインストールしたらデータベースにEUC_JP、SJISを使用できない。 [#xd00ad55]
インストール時(initdb時)にロケールを「C」(デフォルト)でインストールすると使用できるようになる
**JDBCのインストール [#kae3d227]
[[公式サイト:http://jdbc.postgresql.org/download.html#jdbcselection]] からコンパイル済み jar をダウンロードする
**関数 [#n2d99eaa]
-関数を作成する前に下記の文を実行する
 createlang plpgsql(言語名) template1(DB名)

***[[PL/PGSQL関数]] [#j48572ce]
[[長くなってきたので別ページへ>プログラミング/PosgreSQL/PgSQL関数]]
***SQL関数 [#cd05a63a]
-誕生日(DATE型)から年齢(SMALLINT型)を返す関数
 CREATE FUNCTION func_getage(DATE) RETURNS SMALLINT AS '
   SELECT EXTRACT(YEAR FROM AGE($1))::SMALLINT;
 ' LANGUAGE SQL;

**使用例 [#u0e17a98]
-[[PostgreSQL:http://www.nonexistent.jp/users/loatbell/main/Documents/02prog/postgresql/]]
-[[Postgres バックアップスクリプト version 1.1:http://sonic64.hp.infoseek.co.jp/2003-04-17.html]]([[Landscape - エンジニアのメモ:http://sonic64.hp.infoseek.co.jp/]])
***列名の変更 [#s303e97a]
列名を変更するには、次のようにします。 

ALTER TABLE products RENAME COLUMN product_no TO product_number;

***型変換(指定?)の方法 [#f76887f1]
+CAST('10' AS INTEGER);
+'10'::INTEGER;
+INTEGER '10';

***NULL値の置き換え [#g97b8038]
-[[日本語ドキュメント(COALESCE):http://www.postgresql.jp/document/pg746doc/html/functions-conditional.html#AEN11428]]~
-[[COALESCE() は、引数のうち NULL でないものを返す:http://sonic64.hp.infoseek.co.jp/2003-07-29.html]]
-[[■ヌル判定:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/psql_k15.htm]]
 COALESCE(value [, ...])
 COALESCE関数は、NULLでない自身の最初の引数を返します。
 すべての引数がNULLの場合にのみNULLが返されます。
 データを表示の目的で取り出す際、NULL値の代わりにデフォルト値を使う場合、
 時として便利なことがあります。以下に例を示します。 
 
 SELECT coalesce(null, 'abc', 'def');
 
  case
 ------
  abc
 
 SELECT coalesce(null, null, 'def');
 
  case
 ------
  def

***[[[PHP-users 18891]Re: 検索結果を横軸に配置するには?:http://ml.php.gr.jp/pipermail/php-users/2003-November/019418.html]] [#f03c97a5]

***[[[PHP-users 2995] PEAR+PostgresでInsert時のシリアルを知りたい :http://ns1.php.gr.jp/pipermail/php-users/2001-October/003002.html]] [#gb4a2416]
 単純に
 SELECT nextval('some_sequence') AS next_id;
 としてsequenceから一意的な番号を取得し、結果を取り出します。
 
 $query = "SELECT nextval('$seq_name') AS next_id";
 $query_id = pg_Exec($this->link_id, $query);
 $res = pg_Fetch_Array($query_id, 0, PGSQL_ASSOC);
 
 を実行して取得した値をinsertに利用すればOkです。

***[[テーブルを csv 出力:http://sonic64.hp.infoseek.co.jp/2002-12-25.html]] [#x5a04e2d]
 COPY system_name TO '/tmp/system_name_tabale.txt' DELIMITERS ',';
***[[あるカラムで重複しているレコードの件数を数える:http://www.nn.iij4u.or.jp/~m-manabu/pasocom/sql/sql_tips.html#25]] ([[SQLの目次:http://www.nn.iij4u.or.jp/~m-manabu/pasocom/sql/sql_index.html]]) [#rde5aa56]

 SELECT 項目名1,COUNT(*) FROM テーブル名 
   GROUP BY 項目名1 HAVING COUNT(*) >1 
***大文字小文字を区別しない''「パターンマッチング」''(ILIKE,正規表現) [#k15e528b]
:ILIKE|
大文字小文字を区別しないマッチを行うのであればLIKEの替わりにILIKEキーワードを使うことができます。これは標準SQLではなく、PostgreSQLの拡張です。
:正規表現|
|演算子|説明|例|
|CENTER: ~|正規表現にマッチ、大文字小文字の区別あり|'thomas' ~ '.*thomas.*'|
|CENTER: ~*|正規表現にマッチ、大文字小文字の区別なし|'thomas' ~* '.*Thomas.*'|
|CENTER: !~|正規表現にマッチしない、大文字小文字の区別あり|'thomas' !~ '.*Thomas.*'|
|CENTER: !~*|正規表現にマッチしない、大文字小文字の区別なし|'thomas' !~* '.*vadim.*'|

***psqlで日本語を入力する [#x44bbb9e]
psqlを起動するときに
 $ psql -d DB_NAME -n
とすると日本語が使える
***配列 [#v1ddb111]
-元データ
  name  |      pay_by_quarter       |           schedule            
 -------+---------------------------+-------------------------------
  Bill  | {10000,10000,10000,10000} | {{meeting,lunch},{"",""}}
  Carol | {20000,25000,25000,25000} | {{talk,consult},{meeting,""}}
-1~1個目の配列から1~2個目のデータを取得
 SELECT schedule[1:1][1:2] FROM sal_emp WHERE name = 'Bill';
-結果
      schedule      
 -------------------
  {{meeting,lunch}}

***DB初期化 [#he0be196]
 initdb -d DB_DIRECTORY --encoding=EUC_JP --no-locale
***DB作成 [#f7bdc017]
 createdb -E EUC_JP DB_NAME

***dump(ラージオブジェクトを含まない) [#se9d3ba6]
 pg_dump -Ft DB_NAME > db.tar

***restore(ラージオブジェクトを含まない) [#k0729e3a]
 pg_restore -d NEW_DB_NAME db.tar

***ランダムに1行だけ取得したいとき [#cca7b512]
メーリングリストより

 (1)select ... order by (oid * v1) % v2 ;
 (2)order by random()
 
 と2通り考えられる。
 (2)はランダム性としてはより高いですが
 (1)には再現性があるというメリットがあります。ですから
 
 select ... offset 20 limit 20
 select ... offset 20 limit 40
 
 上のような処理でページ分けをするなら(1)のような手法が必須だと思います。
 そうでなければ(2)の方がいいでしょう。

***SLECTの結果からINSERT [#a59ea5b4]
 INSERT INTO tbl_name_A SELECT * FROM table_name_B;

**リンク[#dd681cd2]
-[[日本 PostgreSQL ユーザ会:http://www.postgresql.jp/]]
--[[PostgreSQL 最新版 文書:http://www.postgresql.jp/document/current/html/]]
--[[PostgreSQL 最新版 リファレンス:http://www.postgresql.jp/document/current/html/reference.html]]
-[[ファイヤープロジェクト:http://www.h7.dion.ne.jp/~matsu/feature/postgresql/index.html]]
-[[エンジニアのメモ:http://sonic64.hp.infoseek.co.jp/cat_postgres.html]]
--[[トリガー:http://sonic64.hp.infoseek.co.jp/2003-06-03.html]]
-[[SQLの窓:http://hp.vector.co.jp/authors/VA003334/]]
-[[PostgreSQL for Solaris:http://www.syns.net/18/4/index.html]]
-[[SQL検索編:http://www.nn.iij4u.or.jp/~m-manabu/pasocom/sql_index.html]]
-[[DBMS/PostgreSQL/簡単リファレンス - PukiWiki:http://marz-soho.dyndns.org/pukiwiki/index.php?cmd=read&page=DBMS%2FPostgreSQL%2F%B4%CA%C3%B1%A5%EA%A5%D5%A5%A1%A5%EC%A5%F3%A5%B9]]
-[[PostgreSQL SQL言語入門:http://cyberam.dip.jp/database/postgres/sql.html]]
-[[PostgreSQL・Tips:http://ash.or.jp/db/pg_tips.htm]]