web-dev-qa-db-fra.com

La syntaxe SQL est-elle sensible à la casse?

Le code SQL est-il sensible à la casse? J'ai utilisé MySQL et SQL Server, qui semblent tous deux être sensibles à la casse. Est-ce toujours le cas? La norme définit-elle la sensibilité à la casse?

189
Steve Tranby

Les mots-clés SQL ne sont pas sensibles à la casse (SELECT, FROM, WHERE, etc.), mais sont souvent écrits en majuscules. Cependant, dans certaines configurations, les noms de table et de colonne sont sensibles à la casse. MySQL a une option de configuration pour l'activer/la désactiver. Les noms de table et de colonne sensibles à la casse sont généralement les noms par défaut sous Linux MySQL et insensibles à la casse sous Windows, mais le programme d’installation l’a demandé lors de l’installation. Pour MSSQL, il s'agit d'une fonction du paramètre de classement de la base de données.

Voici le page MySQL sur la sensibilité à la casse des noms

Voici le article dans MSDN sur les classements pour MSSQL

173
Stefan Rusek

Ce n'est pas strictement le langage SQL, mais dans SQL Server, si le classement de votre base de données est sensible à la casse, tous les noms de table le sont.

21
Cade Roux

Dans Sql Server c'est une option . Allumer c'est nul.

Je ne suis pas sûr de MySql.

15
JosephStyons

Les identifiants et les mots réservés ne doivent pas être sensibles à la casse, bien que beaucoup suivent une convention consistant à utiliser des majuscules pour les mots réservés et des majuscules Pascal pour les identifiants.

Voir SQL-92 Sec. 5.2

14
Turnkey

Le spécification SQL92 indique que les identificateurs peuvent être cités ou non cités. Si les deux côtés ne sont pas cotés, ils sont toujours insensibles à la casse, par ex. table_name == TAble_nAmE.

Cependant, les identifiants cités sont sensibles à la casse, par ex. "table_name" != "TAble_naME". Si vous souhaitez également comparer des identificateurs non spécifiés avec des guillemets, les identificateurs non mis entre guillemets et entre guillemets peuvent également être considérés comme identiques, si les caractères non guillemets sont en majuscule, par exemple. TABLE_NAME == "TABLE_NAME", mais TABLE_NAME != "table_name" ou TABLE_NAME != "TAble_NaMe".

Voici la partie pertinente de la spécification (section 5.2.13):

     13)A <regular identifier> and a <delimited identifier> are equiva-
        lent if the <identifier body> of the <regular identifier> (with
        every letter that is a lower-case letter replaced by the equiva-
        lent upper-case letter or letters) and the <delimited identifier
        body> of the <delimited identifier> (with all occurrences of
        <quote> replaced by <quote symbol> and all occurrences of <dou-
        blequote symbol> replaced by <double quote>), considered as
        the repetition of a <character string literal> that specifies a
        <character set specification> of SQL_TEXT and an implementation-
        defined collation that is sensitive to case, compare equally
        according to the comparison rules in Subclause 8.2, "<comparison
        predicate>".

Notez que comme dans d’autres parties de la norme SQL, toutes les bases de données ne suivent pas entièrement cette section. PostgreSQL, par exemple, stocke tous les identificateurs non cités en minuscules au lieu de les en majuscules, donc table_name == "table_name" (ce qui est exactement le contraire de la norme). De plus, certaines bases de données sont sensibles à la casse tout le temps, ou la sensibilité à la casse dépend de certains paramètres de la base de données ou dépend de certaines propriétés du système, que le système de fichiers respecte ou non la casse.

Notez que certains outils de base de données peuvent envoyer des identificateurs entre guillemets. Par conséquent, dans les cas où vous mélangez des requêtes générées par un outil (comme une requête CREATE TABLE générée par Liquibase ou un autre outil de migration de base de données), des requêtes manuelles (comme une simple sélection JDBC). dans votre application), vous devez vous assurer que les cas sont cohérents, en particulier sur les bases de données où les identificateurs entre guillemets et entre guillemets sont différents (DB2, PostgreSQL, etc.)

11
SztupY

D'après ce que je comprends, le standard SQL appelle à une insensibilité à la casse. Je ne crois cependant pas que les bases de données respectent complètement la norme.

MySQL propose un paramètre de configuration dans le cadre de son "mode strict" (une corbeille de plusieurs paramètres rendant MySQL plus conforme aux normes) pour les noms de table sensibles à la casse ou insensibles. Indépendamment de ce paramètre, les noms de colonne ne sont toujours pas sensibles à la casse, bien que je pense que cela affecte la manière dont les noms de colonne sont affichés. Je pense que ce paramètre concerne l'ensemble des bases de données du SGBDR, bien que je fasse des recherches aujourd'hui pour le confirmer (en espérant que la réponse est non).

J'aime la façon dont Oracle gère cela beaucoup mieux. En SQL simple, les identificateurs tels que les noms de table et de colonne ne tiennent pas compte de la casse. Toutefois, si, pour une raison quelconque, vous souhaitez réellement utiliser une casse explicite, vous pouvez inclure l'identifiant entre guillemets (qui sont assez différents dans Oracle SQL des guillemets simples utilisés pour inclure les données de chaîne). Alors:

SELECT fieldName
FROM tableName;

interrogera nom de champ à partir de nomtable , mais

SELECT "fieldName"
FROM "tableName";

interrogera fieldName à partir de nomTable .

Je suis presque sûr que vous pourriez même utiliser ce mécanisme pour insérer des espaces ou d'autres caractères non standard dans un identifiant.

Dans cette situation, si, pour une raison quelconque, vous estimiez que les noms de table et de colonne explicitement placés étaient souhaitables, vous pouviez le faire, mais je le déconseillais vivement.

Ma convention quand j’utilisais Oracle quotidiennement était que, dans le code, je mettrais tous les mots-clés SQL d’Oracle en majuscules et tous les identificateurs en minuscules. Dans la documentation, je mettrais tous les noms de table et de colonne en majuscule. C'était très pratique et lisible de pouvoir le faire (bien que parfois il soit difficile de taper autant de majuscules dans le code - je suis sûr que j'aurais pu trouver une fonctionnalité de l'éditeur pour aider, ici).

À mon avis, MySQL est particulièrement mauvais pour différer à ce sujet sur différentes plates-formes. Nous devons être en mesure de vider des bases de données sous Windows et de les charger sous UNIX. Si l'installateur sous Windows oublie de mettre le SGBDR en mode sensible à la casse, cela risque de provoquer un sinistre. (Pour être honnête, c’est en partie pour cette catastrophe que nos programmeurs ont pris la mauvaise décision, il y a longtemps, de s’en remettre à la casse de MySQL sous UNIX). Il ressemblait beaucoup à Windows, et c’était bien de pouvoir donner aux gens une case à cocher disant "Voulez-vous activer le mode strict et rendre MySQL plus conforme aux normes?" Mais il est très pratique pour MySQL de différer de manière si significative du standard, puis d’aggraver les choses en se retournant et en différant de son propre standard de facto sur différentes plates-formes. Je suis sûr que cela peut être aggravé par les différentes distributions Linux, car les emballeurs de différentes distributions ont probablement parfois incorporé leurs propres paramètres de configuration MySQL préférés.

Ici une autre SO question qui permet de déterminer si la sensibilité à la casse est souhaitable dans un SGBDR.

10
skiphoppy

J'ai trouvé cet article de blog très utile (je ne suis pas l'auteur). Résumant (s'il vous plaît lire, cependant):

... les identifiants délimités respectent la casse ("nom_table"! = "nom_table"), alors que les identificateurs non cités ne le sont pas et sont transformés en majuscules (nom_table => NOM_TABLES).

Il a constaté que DB2, Oracle et Interbase/Firebird étaient 100% compatibles:

PostgreSQL ... met tous les identificateurs non cités en minuscules, au lieu de les mettre en majuscules. MySQL ... dépend du système de fichiers. SQLite et SQL Server ... les noms de table et de champ sont conservés à la création, mais ils sont complètement ignorés par la suite.

4
Matthew Cornell

Non. MySQL ne respecte pas la casse, ni le standard SQL. C'est une pratique courante d'écrire les commandes en majuscule.

Maintenant, si vous parlez de noms de table/colonne, alors oui, mais les commandes elles-mêmes.

Alors

SELECT * FROM foo;

est le même que

select * from foo;

mais pas la même chose que

select * from FOO;
4
cmcculloh

Les mots-clés SQL sont eux-mêmes sensibles à la casse.

Les noms de tables, de colonnes, etc., ont une distinction de casse qui dépend de la base de données - vous devriez probablement supposer qu’ils sont sensibles à la casse, sauf indication contraire (dans de nombreuses bases de données, ils ne le sont pas; dans MySQL, les noms de table sont parfois sensibles à la casse, mais la plupart des autres les noms ne sont pas).

La comparaison de données à l'aide de =,>, <etc. a une connaissance de la casse qui dépend des paramètres de classement utilisés dans la base de données, la table ou même la colonne en question. Il est toutefois normal de maintenir la cohérence des collations dans une base de données. Nous avons quelques colonnes qui doivent stocker des valeurs sensibles à la casse; ils ont une collation spécifiquement définie.

2
MarkR

Je ne pense pas que SQL Server respecte la casse, du moins pas par défaut.

Lorsque j'interroge manuellement via Management Studio, je gâche tout le temps le cas et il l'accepte gaiement:

select cOL1, col2 FrOM taBLeName WheRE ...
1
Dana