Cosa dice lo standard SQL sull’utilizzo di backtick (`)?

Una volta ho passato ore a eseguire il debug di una semplice query SQL utilizzando mysql_query() in PHP/MySQL solo per rendermi conto che mi mancava il bactick attorno al nome della tabella. Da quel momento lo usavo sempre attorno ai nomi delle tabelle.

Ma quando ho usato lo stesso in SQLite/C++ , il simbolo non è nemmeno riconosciuto. È confusionario, se usarlo o no? Che cosa dice lo standard sull’utilizzo di esso?

Inoltre, sarebbe utile se qualcuno potesse dirmi quando usare le virgolette e quando no. Intendo intorno ai valori e ai nomi dei campi.

Lo standard SQL (la versione corrente è ISO / IEC 9075: 2011, in più parti) non dice nulla sul simbolo “back-tick” o “back-quote” (Unicode U + 0060 o GRAVE ACCENT); non lo riconosce come un personaggio con un significato speciale che può apparire in SQL.

Il meccanismo SQL standard per la citazione degli identificatori è con identificatori delimitati racchiusi tra virgolette:

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

In MySQL, potrebbe essere scritto:

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

In MS SQL Server, potrebbe essere scritto:

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

Il problema con la notazione SQL Standard è che i programmatori C sono usati per racchiudere stringhe tra virgolette doppie, quindi la maggior parte dei DBMS usa virgolette doppie in alternativa alle virgolette singole riconosciute dallo standard. Ma questo ti lascia un problema quando vuoi racchiudere gli identificatori.

Microsoft ha preso un approccio; MySQL ne ha preso un altro; Informix consente l’uso intercambiabile di virgolette singole e doppie, ma se si vogliono identificatori delimitati, si imposta una variabile di ambiente e quindi si deve seguire lo standard (virgolette singole per stringhe, virgolette doppie per identificatori); DB2 segue solo lo standard, AFAIK; SQLite sembra seguire lo standard; Anche Oracle sembra seguire lo standard; Sybase sembra consentire tra virgolette (standard) o parentesi quadre (come con MS SQL Server – il che significa che SQL Server potrebbe consentire anche le virgolette doppie). Questa pagina documenta tutti questi server (ed è stato utile per colmare le lacune nelle mie conoscenze) e nota se le stringhe all’interno degli identificatori delimitati sono sensibili al maiuscolo / minuscolo.


Quanto a quando utilizzare un meccanismo di quotatura attorno agli identificatori, il mio atteggiamento è “mai”. Beh, non proprio mai, ma solo quando è assolutamente obbligato a farlo.

Si noti che gli identificatori delimitati fanno distinzione tra maiuscole e minuscole; cioè "from" e "FROM" riferiscono a colonne diverse (nella maggior parte dei DBMS – vedi l’URL sopra). La maggior parte di SQL non è sensibile al maiuscolo / minuscolo; è una seccatura sapere quale caso usare. (Lo standard SQL ha un orientamento mainframe – si aspetta che i nomi vengano convertiti in lettere maiuscole, la maggior parte dei DBMS convertono i nomi in lettere minuscole, però).

In generale, è necessario delimitare gli identificatori che sono parole chiave per la versione di SQL che si sta utilizzando. Ciò significa la maggior parte delle parole chiave in SQL standard , oltre a tutti gli extra che fanno parte delle particolari implementazioni che stai utilizzando.

Una fonte continua di problemi è l’aggiornamento, in cui il nome di una colonna che non era una parola chiave nella versione N diventa una parola chiave nella versione N + 1. SQL esistente che ha funzionato prima dell’aggiornamento smette di funzionare in seguito. Quindi, almeno come misura a breve termine, potresti essere costretto a citare il nome. Ma nel corso ordinario degli eventi, dovresti mirare ad evitare di dover citare gli identificatori.

Ovviamente, il mio atteggiamento è influenzato dal fatto che Informix (che è quello con cui lavoro principalmente) accetta questo SQL testualmente, mentre la maggior parte dei DBMS si soffre su questo:

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

Ovviamente, la persona che produce un tavolo così ridicolo per scopi diversi da quelli dimostrativi dovrebbe essere appesa, disegnata, squartata e quindi i residui dovrebbero essere fatti per sistemare il disastro che hanno creato. Tuttavia, entro certi limiti che i clienti riescono a colpire regolarmente, le parole chiave possono essere utilizzate come identificatori in molti contesti. Questo è di per sé una forma utile di prova del futuro. Se una parola diventa una parola chiave, esiste una moderata possibilità che il codice esistente continui a funzionare indipendentemente dalla modifica. Tuttavia, il meccanismo non è perfetto; non è ansible creare una tabella con una colonna denominata PRIMARY, ma è ansible modificare una tabella per aggiungere una colonna di questo tipo. C’è una ragione per l’idiosincrasia, ma è difficile da spiegare.