アプリ版:「スタンプのみでお礼する」機能のリリースについて

ちょっと疑問に思ったことがあるので質問です。
例えば以下のようなselect文があるとします。
(keyというカラムはint型です)

select * from hogehoge where key = 1;

これでselectは問題なく出来るのですが、以下のように値を単一引用符で囲っても、やはりselectは可能でした。

select * from hogehoge where key = '1';

カラムの型が文字列であれば単一引用符で囲まなくてはいけないですが、数値は逆に単一引用符で囲ってはいけないとばかり思っていました。

数値を単一引用符で囲むのと囲まないのとでは、何が違うのでしょうか?御存知の方、教えて下さい。

A 回答 (1件)

PostgreSQLの独自仕様のようです。



'1'は数値でなく文字なのですが、数値との型変換を自動的に行ってくれるようです。

以下の操作を試して、定数の型を確認してみました。
(1)select 1→int4
(2)select 1.→numeric
(3)select '1'→unknown
(4)select '1'::int→int4
(5)select 1::dec→numeric
(6)select 'A'→unknown

'1'だけ入力した場合は、'A'と同じ、つまり文字として認識されています。

C1がdecで、「where C1=1」と指定した場合、内部的にはint→decの型変換が行われています。
この場合、型変換を行わせないためには、「where C1=1.」と指定する必要があります。

これと同様に、PostgreSQLでは、「where C1='1'」と指定した場合、文字→intの型変換が行われています。

型変換はオーバーヘッドになりますので、できるだけ列の型にあった定数を指定した方がいいというのが、どのDBMSにも共通の常識だと思います。

PostgreSQLでは、文字から数値への自動的な型変換も行ってくれるようですが、型変換のオーバヘッドがある上、見た目だけで判断すると、列のデータ型を勘違いすることになり兼ねないので、こういった使用は行わない方がいいと思います。
    • good
    • 0
この回答へのお礼

詳しいご説明をありがとうございました。''で括った場合は、第一義的にはunknownなんですね。それを内部的に型変換してintに直していると。これは確かにオーバーヘッドですね。勉強になりました。

Postgresの話とちょっとズレるのですが、例えばPHPのPEAR::DBクラスでプレースホルダーを使って、

$sth = $dbh->prepare("select * from hoge where key = ?");
$sth->query($sth, array(1));

とやると、実行時のクエリーは、

select * from hoge where key = '1'

というものが生成されていました。これは、自動型変換を前提にしたクエリーが生成されているという事ですよね。

PHPに限らず、プレースホルダーは値のエスケープに便利なのですが、自動型変換のオーバーヘッドを考えると、少なくとも数値型にはプレースホルダーは使用しない方がいいのかな、と思いました。

その辺り、chukenkenkouさんはどう思われますでしょうか?(質問ばっかりですみません・・)

お礼日時:2006/01/29 15:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!