48

mysql_query()を使用して単純なSQLクエリのデバッグに何時間も費やした後PHP/MySQL、テーブル名の周りのbactickを見逃したことに気づきました。それ以来、私は常にテーブル名の周りでそれを使用していました。

しかし、で同じものを使用した場合SQLite/C++、記号も認識されません。これを使うかどうか、混乱しますか?標準はそれの使用法について何と言っていますか?

また、引用符を使用する場合と使用しない場合を誰かに教えてもらえると助かります。値とフィールド名の周りを意味します。

4

2 に答える 2

82

SQL標準(現在のバージョンはISO / IEC 9075:2011、複数の部分で)は、「バックティック」または「バッククォート」記号(Unicode U +0060またはGRAVEACCENT)については何も述べていません。SQLに表示される可能性のある特別な意味を持つ文字としては認識されません。

識別子を引用するための標準SQLメカニズムは、二重引用符で囲まれた区切り識別子を使用します。

SELECT "select" FROM "from" WHERE "where" = "group by";

MySQLでは、次のように記述されている可能性があります。

SELECT `select` FROM `from` WHERE `where` = `group by`;

MS SQL Serverでは、次のように記述される場合があります。

SELECT [select] FROM [from] WHERE [where] = [group by];

SQL標準表記の問題は、Cプログラマーが文字列を二重引用符で囲むことに慣れているため、ほとんどのDBMSは、標準で認識される一重引用符の代わりに二重引用符を使用することです。ただし、識別子を囲む場合は問題が発生します。

Microsoftは1つのアプローチを採用しました。MySQLは別のものを取りました。Informixでは、一重引用符と二重引用符を交換して使用できますが、区切り識別子が必要な場合は、環境変数を設定してから、標準(文字列の場合は一重引用符、識別子の場合は二重引用符)に従う必要があります。DB2は、標準のAFAIKのみに従います。SQLiteは標準に従っているようです。Oracleも標準に従っているようです。Sybaseでは、二重引用符(標準)または角かっこ(MS SQL Serverの場合と同様)のいずれかが許可されているようです。つまり、SQL Serverでも二重引用符が許可される場合があります)。このページ(2013年以降のリンクAWOL — Wayback Machineで利用可能になりました)ドキュメントこれらすべてのサーバーを文書化し(そして私の知識のギャップを埋めるのに役立ちました)、区切られた識別子内の文字列が大文字と小文字を区別するかどうかを記録しました。


識別子の周りに引用メカニズムをいつ使用するかについては、私の態度は「決して」ではありません。まあ、まったく決してではありませんが、絶対にそうすることを余儀なくされたときだけです。

区切られた識別子では大文字と小文字が区別されることに注意してください。つまり、さまざまな列"from""FROM"参照します(ほとんどのDBMSでは、上記のURLを参照してください)。SQLのほとんどは大文字と小文字を区別しません。どのケースを使用するかを知るのは厄介です。(SQL標準にはメインフレームの方向性があります。名前は大文字に変換される必要がありますが、ほとんどのDBMSは名前を小文字に変換します。)

一般に、キーワードである識別子は、使用しているSQLのバージョンに区切る必要があります。これは、標準SQLのほとんどのキーワードに加えて、使用している特定の実装の一部である追加機能を意味します。

継続的な問題の原因の1つは、サーバーをアップグレードする場合です。この場合、リリースNでキーワードではなかった列名が、リリースN+1でキーワードになります。アップグレード前に機能していた既存のSQLは、アップグレード後に機能しなくなります。次に、少なくとも短期的な対策として、名前を引用することを余儀なくされる可能性があります。ただし、通常のイベントでは、識別子を引用する必要がないようにする必要があります。

もちろん、私の態度は、Informix(私が主に使用しているもの)がこのSQLを逐語的に受け入れるという事実によって色付けされていますが、ほとんどのDBMSはそれに窒息します:

CREATE TABLE TABLE
(
    DATE    INTEGER NOT NULL,
    NULL    FLOAT   NOT NULL,
    FLOAT   INTEGER NOT NULL,
    NOT     DATE    NOT NULL,
    INTEGER FLOAT   NOT NULL
);

もちろん、デモンストレーション目的以外の目的でこのようなばかげたテーブルを作成する人は、吊るし、描画し、四分の一にし、残りを作成して、作成した混乱を修正する必要があります。しかし、顧客が日常的にヒットすることができるいくつかの制限内で、キーワードは多くのコンテキストで識別子として使用できます。つまり、それ自体が将来を保証するための便利な形式です。単語がキーワードになった場合、既存のコードが変更の影響を受けずに機能し続ける可能性は中程度です。ただし、メカニズムは完全ではありません。PRIMARYという列を持つテーブルを作成することはできませんが、そのような列を追加するようにテーブルを変更することはできます。特異性には理由がありますが、説明するのは難しいです。

于 2012-05-13T18:07:37.887 に答える
0

末尾の下線

あなたが言った:

引用符を使用する場合と使用しない場合を誰かに教えてもらえれば助かります

数年前、私はコマンド、キーワード、予約語を探しているいくつかのリレーショナルデータベース製品を調査しました。驚いたことに、私は千以上の異なる単語を見つけました。

それらの多くは、「データベースワード」として驚くほど直感に反していました。そのため、テーブルや列などに名前を付けるときに、予約語との意図しない衝突を回避する簡単な方法がないのではないかと心配しました。

それから私はこのヒントをインターネット上のどこかで見つけました:

すべてのSQL命名に末尾の下線を使用します。

SQL仕様では、SQL関連の名前に末尾の下線を使用しないことを明示的に約束していることがわかりました。

著作権で保護されているため、SQL仕様を直接引用することはできません。しかし、 ISO / IEC 9075:19925.2.11 <token> and <separator>の想定ドラフトのセクションでは、データベース言語SQL (SQL-92)は次のように述べています(私自身の言い換えで):

SQL仕様の現在および将来のバージョンでは、アンダースコアで終わるキーワードはありません。

➥議論せずに奇妙なことにSQL仕様に落とし込まれましたが、私にとってのその単純なステートメントは、「すべての名前の衝突を避けるために、末尾にアンダースコアを付けて名前を付けてください」と叫びます。

それ以外の:

  • person
  • name
  • address

…使用する:

  • person_
  • name_
  • address_

この方法を採用して以来、私は素晴らしい副作用を発見しました。私たちのアプリには、通常、データベースオブジェクト(テーブル、列など)と同じ名前のクラスと変数があります。したがって、データベースオブジェクトを参照する場合と、アプリの状態(クラス、変数)を参照する場合とでは、固有のあいまいさが生じます。これでコンテキストが明確になります。名前の末尾にアンダースコアが表示されると、データベースが具体的に示されます。アンダースコアがないということは、アプリのプログラミング(Javaなど)を意味します。


SQLの命名に関するヒント:移植性を最大限に高めるには、単語の間にアンダースコアを付けたすべて小文字と、末尾の下線を使用します。SQL仕様では、他の大文字小文字を受け入れながら識別子をすべて大文字で格納する実装が必要ですが(提案されていません)、ほとんど/すべての製品はこの要件を無視しています。ですから、よく読んで実験した結果、アンダースコア付きのすべて小文字が最も移植性が高いことを学びました。

単語の間にすべて小文字のアンダースコアと末尾の下線を使用する場合は、一重引用符、二重引用符、バックティック、または角かっこで引用する必要がない場合があります。

于 2021-05-01T23:49:33.010 に答える