What does the SQL Standard say about usage of backtick(`)?
Asked Answered
H

2

54

Once I had spent hours in debugging a simple SQL query using mysql_query() in PHP/MySQL only to realise that I had missed bactick around the table name. From then I had been always using it around table names.

But when I used the same in SQLite/C++, the symbol is not even recognized. It's confusing, whether to use this or not? What does standard say about usage of it?

Also, it would be helpful if anyone could tell me when to use quotes and when not. I mean around values and field names.

Halo answered 13/5, 2012 at 17:53 Comment(1)
By the way, some languages offer functions to enquote identifier names in a manner specific to your database engine. For Java, see this Answer on How to quote/escape identifiers such as column names with JDBC?.Volteface
M
89

The SQL standard (current version is ISO/IEC 9075:2011, in multiple parts) says nothing about the 'back-tick' or 'back-quote' symbol (Unicode U+0060 or GRAVE ACCENT); it doesn't recognize it as a character with special meaning that can appear in SQL.

The Standard SQL mechanism for quoting identifiers is with delimited identifiers enclosed in double quotes:

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

In MySQL, that might be written:

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

In MS SQL Server, that might be written:

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

The trouble with the SQL Standard notation is that C programmers are used to enclosing strings in double quotes, so most DBMS use double quotes as an alternative to the single quotes recognized by the standard. But that then leaves you with a problem when you want to enclose identifiers.

Microsoft took one approach; MySQL took another; Informix allows interchangeable use of single and double quotes, but if you want delimited identifiers, you set an environment variable and then you have to follow the standard (single quotes for strings, double quotes for identifiers); DB2 only follows the standard, AFAIK; SQLite appears to follow the standard; Oracle also appears to follow the standard; Sybase appears to allow either double quotes (standard) or square brackets (as with MS SQL Server — which means SQL Server might allow double quotes too). This page (link AWOL since 2013 — now available in The Wayback Machine) documents documented all these servers (and was helpful filling out the gaps in my knowledge) and notes whether the strings inside delimited identifiers are case-sensitive or not.


As to when to use a quoting mechanism around identifiers, my attitude is 'never'. Well, not quite never, but only when absolutely forced into doing so.

Note that delimited identifiers are case-sensitive; that is, "from" and "FROM" refer to different columns (in most DBMS — see URL above). Most of SQL is not case-sensitive; it is a nuisance to know which case to use. (The SQL Standard has a mainframe orientation — it expects names to be converted to upper-case; most DBMS convert names to lower-case, though.)

In general, you must delimit identifiers which are keywords to the version of SQL you are using. That means most of the keywords in Standard SQL, plus any extras that are part of the particular implementation(s) that you are using.

One continuing source of trouble is when you upgrade the server, where a column name that was not a keyword in release N becomes a keyword in release N+1. Existing SQL that worked before the upgrade stops working afterwards. Then, at least as a short-term measure, you may be forced into quoting the name. But in the ordinary course of events, you should aim to avoid needing to quote identifiers.

Of course, my attitude is coloured by the fact that Informix (which is what I work with mostly) accepts this SQL verbatim, whereas most DBMS would choke on it:

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

Of course, the person who produces such a ridiculous table for anything other than demonstration purposes should be hung, drawn, quartered and then the residue should be made to fix the mess they've created. But, within some limits which customers routinely manage to hit, keywords can be used as identifiers in many contexts. That is, of itself, a useful form of future-proofing. If a word becomes a keyword, there's a moderate chance that the existing code will continue to work unaffected by the change. However, the mechanism is not perfect; you can't create a table with a column called PRIMARY, but you can alter a table to add such a column. There is a reason for the idiosyncrasy, but it is hard to explain.

Menu answered 13/5, 2012 at 18:7 Comment(3)
Although I don't necessarily agree, I liked this answer a lot, and it added much to my knowledge, +1 thanks. I will still go on using backticks though! :) I am more worried about many old programs suddenly failing to work than having to pass queries into a conversion function that replaces backticks with [ and ] if I happen to change the database..Baras
Keep in mind that MariaDB a fork off MySQL supports [] beside backticks aswell when running in SQL_MODE=MSSQLKoheleth
Besides MySQL and MariaDB also support double qoutes when sql_mode ANSI_QUOTES is active ... -> "ANSI_QUOTES Treat " as an identifier quote character (like the ` quote character) and not as a string quote character. You can still use ` to quote identifiers with this mode enabled. With ANSI_QUOTES enabled, you cannot use double quotation marks to quote literal strings because they are interpreted as identifiers. " this is in line with the ANSI SQL standard..Koheleth
V
3

Trailing underscore

You said:

it would be helpful if anyone could tell me when to use quotes and when not

Years ago I surveyed several relational database products looking for commands, keywords, and reserved words. Shockingly, I found over a thousand distinct words.

Many of them were surprisingly counter-intuitive as a "database word". So I feared there was no simple way to avoid unintentional collisions with reserved words while naming my tables, columns, and such.

Then I found this tip some where on the internets:

Use a trailing underscore in all your SQL naming.

Turns out the SQL specification makes an explicit promise to never use a trailing underscore in any SQL-related names.

Being copyright-protected, I cannot quote the SQL spec directly. But section 5.2.11 <token> and <separator> from a supposed-draft of ISO/IEC 9075:1992, Database Language SQL (SQL-92) says (in my own re-wording):

In the current and future versions of the SQL spec, no keyword will end with an underscore

➥ Though oddly dropped into the SQL spec without discussion, that simple statement to me screams out “Name your stuff with a trailing underscore to avoid all naming collisions”.

Instead of:

  • person
  • name
  • address

…use:

  • person_
  • name_
  • address_

Since adopting this practice, I have found a nice side-effect. In our apps we generally have classes and variables with the same names as the database objects (tables, columns, etc.). So an inherent ambiguity arises as to when referring to the database object versus when referring to the app state (classes, vars). Now the context is clear: When seeing a trailing underscore on a name, the database is specifically indicated. No underscore means the app programming (Java, etc.).


Further tip on SQL naming: For maximum portability, use all-lowercase with underscore between words, as well as the trailing underscore. While the SQL spec requires (not suggests) an implementation to store identifiers in all uppercase while accepting other casing, most/all products ignore this requirement. So after much reading and experimenting, I learned the all-lowercase with underscores will be most portable.

If using all-lowercase, underscores between words, plus a trailing underscore, you may never need to care about enquoting with single-quotes, double-quotes, back-ticks, or brackets.

Volteface answered 1/5, 2021 at 23:49 Comment(2)
"Being copyright-protected, I cannot quote the SQL spec directly." -> This is BS, see this: en.wikipedia.org/wiki/Right_to_quoteInterlaken
@Interlaken Define “reasonable limit”, “intended use”, “scope of this right”. You may choose to engage in a legal battle; I do not. If the SQL committee wanted me to quote their materials without concern, they would have granted me a license. I’ll counter your Wikipedia link with mine: Creative Commons.Volteface

© 2022 - 2024 — McMap. All rights reserved.