ちょっと疑問に思ったことがあるので質問です。
例えば以下のようなselect文があるとします。
(keyというカラムはint型です)
select * from hogehoge where key = 1;
これでselectは問題なく出来るのですが、以下のように値を単一引用符で囲っても、やはりselectは可能でした。
select * from hogehoge where key = '1';
カラムの型が文字列であれば単一引用符で囲まなくてはいけないですが、数値は逆に単一引用符で囲ってはいけないとばかり思っていました。
数値を単一引用符で囲むのと囲まないのとでは、何が違うのでしょうか?御存知の方、教えて下さい。
No.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では、文字から数値への自動的な型変換も行ってくれるようですが、型変換のオーバヘッドがある上、見た目だけで判断すると、列のデータ型を勘違いすることになり兼ねないので、こういった使用は行わない方がいいと思います。
詳しいご説明をありがとうございました。''で括った場合は、第一義的には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さんはどう思われますでしょうか?(質問ばっかりですみません・・)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle SQL update方法 2 2022/06/22 14:07
- MySQL 共通点はあります。何が違うのでしょうか? 1 2023/01/27 05:22
- JavaScript 電車の運賃を出すプログラムを作っています。 2 2022/06/22 09:36
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- 数学 数学 解き方の違い 1 2022/03/23 21:37
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- MySQL うまくいきません教えてくださいお願いしますSQLです。クエリ構文です。 1 2023/07/07 12:39
- MySQL SQLです。こんな感じですか?あってますか? うまくいきません教えてくださいお願いします 1 2023/07/08 15:27
- MySQL SQLについて教えて下さい。 SELECT分で、あるカラムにある日付の 半年先のデータを取って来たい 3 2022/12/07 22:28
- Excel(エクセル) エクセルの関数で質問です。 3 2023/02/24 14:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SELECT INTOで一度に複数の変数...
-
oleDBでnumeric形式の小数部分...
-
UPDATEの更新前の値を取得したい
-
SELECTした結果に行番号を求めたい
-
SQLで小数点の計算がしたいです。
-
テーブル間の差分抽出方法は?...
-
フラグをたてるってどういうこ...
-
【SQL】他テーブルに含まれる値...
-
sqlに記述できない文字
-
Accessで今日から5日後
-
timestampのデータはどのように...
-
UPDATEで既存のレコードに文字...
-
オラクルのUPDATEで複数テーブル
-
エラーを起こす方法
-
テーブル名が可変の場合のクエ...
-
truncate tableを使って複数の...
-
データ無し時は空白行にしたい...
-
ACCESSのVBAにてExcelに行...
-
chr(13) と char(13) の違いっ...
-
2つのテーブルをLIKE演算子のよ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SELECT INTOで一度に複数の変数...
-
SELECTした結果に行番号を求めたい
-
複数の条件に該当する結果を、...
-
データの入れ替えを同時に行な...
-
UPDATEの更新前の値を取得したい
-
SQL 表の結合
-
副問合せで複数列の値リストの...
-
テーブル間の差分抽出方法は?...
-
SQLで任意の列の最大値の定数は...
-
SQLで小数点の計算がしたいです。
-
複数カラムでdistinct
-
pg/plsqlでのカーソルのLIK...
-
数値を単一引用符で囲むのはど...
-
order by int型の降順(DESC)でn...
-
FETCH した行が取り出せない
-
PLPGSQLでの複数行複数列
-
ダブリ数字の有無の確認にのマ...
-
フラグをたてるってどういうこ...
-
【SQL】他テーブルに含まれる値...
-
sqlに記述できない文字
おすすめ情報