ラベル database の投稿を表示しています。 すべての投稿を表示
ラベル database の投稿を表示しています。 すべての投稿を表示

2008/10/18

[memo] How to get Database Metadata by PHP

普段データベースのメタデータを取得する機会なぞあまりない。だが、ORMを弄るときは別だ。ユーザがそうしたものを全部プログラムに書いてくれれば不要なのだが、今時の怠惰なプログラマはそれらを自動生成または補完することを求めるからである。

ということで、ちょっと Creoleadodb の場合を調べたのでメモしておく。test というテーブルのメタデータを取得する流れを記してある。尚、エラー処理は省略してある。

----

1. adodb の場合

require_once 'adodb/adodb.inc.php';

$dsn = 'mysql://foo:bar@localhost/test';
$conn = NewADOConnection($dsn);

// get ADOFieldObject
// A field object is a class instance with (name, type, max_length) defined.
// @see http://phplens.com/adodb/reference.functions.metacolumns.html
$columns = $conn->MetaColumns('test');
foreach ($columns as $column) {
var_dump($column->name);
var_dump($column->type);
var_dump($column->max_length);
}


2. Creole の場合

require_once 'creole/Creole.php';

// first get DatabaseInfo object.
$dsn = 'mysql://foo:bar@localhost/test';
$conn = Creole::getConnection($dsn);
$info = $conn->getDatabaseInfo();

$test_info = $info->getTable('test'); // TableInfo object.
$test_columns = $test_info->getColumns(); // ColumnInfo object.

// finally get as you like.
// @see http://creole.phpdb.org/docs/api/creole.metadata/ColumnInfo.html
foreach ($test_columns as $column) {
var_dump($column->getName());
var_dump($column->getNativeType());
}

2008/10/16

SQL QUOTED IDENTIFIER

SQLのキーワード を含んだ識別子は、ANSI/ISO SQL規格によれば ダブルクォートで括ることになっているようだ(※)。ただ、その扱いは RDBMS によって様々である。これは ORM 等で、SQLを自動生成するプログラムを書く人にとっては割と問題になる。なぜなら、ユーザが識別子として何を書いてくるかわからないからである。

そのまとめとしては、PEAR::MDB2 での扱いが非常にわかりやすかったりするのだが、私が触れている主なRDBMS上での扱いを以下にメモしておく。基本的にダブルクォートが可搬性が高いわけだが、そのデフォルトは異なったりするので、やはり RDBMS を見てクォートする文字を変えるライブラリが存在している。

----

・MySQL - http://dev.mysql.com/doc/refman/5.1/ja/identifiers.html
デフォルトは「`」を使う。目立つわけだが、そんなエンジンでも ANSI SQLモードは用意されている

・SQLite - http://sqlite.org/lang_keywords.html
[] も区切り文字として許されている。Access や SQL Server への互換性のためのものだが、これも目立つ。

・Microsoft SQL Server - http://support.microsoft.com/kb/156501/ja
設定すれば強制クォートしてくれるモードが用意されている。

・PostgreSQL - http://www.postgresql.jp/document/current/html/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

え、Oracle がないって? 俺普段触らないのでどなたか補足よろしく(´ー`; )

----

※ ダブルクォートで括らねばならないとされる根拠は、ANSI/ISO SQL規格にある。SQL 92 で言えば、5.2 <token> and <separator> にある。そこでは、識別子 (regular identifier body) は SQL のキーワードであってはならない (shall not) とされている。delimited identifier(ダブルクォートで括られた識別子)についてはこの規定はない。ただ、その comparion rule は複雑過ぎたので読むのを止めた、、(´ー`; )