質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

5回答

265閲覧

一重引用符の必然性について

st-access_91s

総合スコア43

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2018/11/01 23:14

Oracle Master Bronze のSQLを勉強中なのですが、一重引用符について「文字リテラルと日付リテラルは列名と区別できないから一重引用符で囲む」とありました。
列名と同じ値が使われていなければ一重引用符で囲まなくても区別出来るのでは、と疑問に思ったのですが、調べても解説しているページを見つけられませんでした。
どなたかお分かりになる方いらっしゃいますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

端的に言えば、「そういう文法に決まっているから」という、つまらない回答となります。とりわけ、日付リテラルは2018-11-02のような形になるので、引用符など何かしらの区別をつけないと引き算と区別が付きません。

SQLではないのですが、PHPでは「名前だけ書くと(ほかで定義されていない場合)自動的にその名前の定数として解釈する」という仕様がありましたが、「間違えて書いた名前が意図せず有効になってしまう」など弊害も多かったので、PHP 7.2で非推奨に切り替えられました。…というように、「自動で文字列として認識する」というのは、むしろよくない機能だと考えられています。

投稿2018/11/01 23:41

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

st-access_91s

2018/11/01 23:49

あ、なる程…確かに日付リテラルは一重引用符ないと引き算と区別つかなくなりますね。 PHPの例も非常に参考になりました。 ありがとうございます。
guest

0

なんでも許してたら文法エラーが検出できないじゃないですか。

投稿2018/11/01 23:33

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/11/01 23:43

例えば、同じ列名が最初は無かったけど後で作られた場合はどうしますか? 文字列リテラルとして書いたつもりのものが列名として判断されることになりませんか? それを避けようと、列名と同じ文字列リテラルがある場合にだけエラーを出す仕様にした場合、列名と同じ文字列は使えないことになりませんか? 文法がややこしくなればなるほど処理速度も落ちるしメンテもしにくくなります。 引用符で囲まず自動判断されることによるメリットに比べて非常に大きなデメリットを抱えることになります。
st-access_91s

2018/11/02 09:20

確かに後から同じ列名のものを追加ってなると、文字リテラルとの区別が必要ですね。そこまで考え回りませんでした。机上の学習ばかりだと、見解が狭くなりがちですね…。 ありがとうございます。
guest

0

ユーザー視点での解説は他の方が記載されているので、少し別の視点の説明を記載します。

自分が「データベースの中の人(膨大なデータの中から、SQLで指示されたデータを探し出してくる係)」になったつもりで考えていただきたいのですが、「文字リテラルかどうか」の判定、どちらが楽だと思いますか?

1:一重引用符で囲ってあるもの

2:テーブル名やカラム名や予約語等々と重複しないもの

「2」を判定するには、全てのテーブル名やカラム名等々と合致していないか、を毎回調べなくてはならないので、おそらく「1」のほうが楽、となるのではないでしょうか?
実際には、データベースには中の人はいませんが、プログラムがやっている内部処理を考えると「こうだったら文字リテラル」という判定の条件が明確なほうが、処理効率が良くなるのです。

余談ですが、数字は一重引用符で囲わなくて良い、となっています。
これは、テーブル名やカラム名等々のルールとして「一文字目が数字ではないこと」というものが定義されているからです。

また、囲ってしまうと、今度は文字や日付と区別がつかなくなる、というのもあるかもしれません。

投稿2018/11/02 00:06

nak

総合スコア696

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

st-access_91s

2018/11/04 22:47

なる程…小さなテーブルならまだしも、多少大きいものや複数テーブルと紐付ける場合を考えると、より一層、一重引用符で囲む方が便利というのが納得です。 作ることの簡単さだけでなく、使う時の性能に目が行ってなかったのは、視野が狭かったですね。 数字に一重引用符が不要というのも納得です。 ありがとうございます。
guest

0

型を軽視しすぎじゃないですかね。

文字列リテラルを表明する記号がないということは、文字列カラムに日付っぽいデータや数値っぽいデータは入れられなくなる、ということになりませんか?

具体的に、欲しいものメモというテーブルを作ろうとして、型番というカラムをvarchar(text)で用意したときに(型番なんてどこのメーカーがどういう番号を付けるか分からないので文字にした)、数値様の型番1001や日付様の型番1779-01-01をどう判断するのでしょうか?数値様文字の+-10や日付様型番02000-12-31は?パースエラー?型が合わないからエラー?
何でも文字にはキャストできるようにするのですか?NULLも文字にはキャストしますか?あるいは何でもキャストするなら(insert into valuesの構文で)カラム間違いを防げないってことですよね?
(実装上は数値リテラルは文字になりそうな気もしますが、+10が数値リテラルと解釈されて10になってから文字になるか+10がそのまま文字と認識されるかで格納値が違ってきます)

クオートは型を宣言しているのだと思います。その説明は、それを分かり易く言おうとしているのだと思います。

投稿2018/11/02 01:04

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

st-access_91s

2018/11/05 23:06

詳しい例示付きの解説、ありがとうございます。あなたの解説を読む中で、確かに型を軽視してたと気付きました…。 キャストも多用するわけにいかない手法だから、そうなると一重引用符での指定は理に敵ってますね…。
guest

0

空白を含む文字列を考えたら一目瞭然ですな。
どこからどこまでが文字列リテラルなのか判別できないです。

投稿2018/11/02 00:19

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

st-access_91s

2018/11/04 22:49

そういえば空白を含む文字列を指定する場合もありましたね…想像力が足りなかった…。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問