Les commentaires SQL

MySQL

-- Cette ligne est en commentaire
SELECT * # Sur une ligne tout ce qui suit le '#' est en commentaire
FROM maTable

Les délimiteurs de nom d'objets : bases, tables et colonnes

Quelle est la différence entre les caractères ', ` et '' ? ? ` (accent grave ou backtick, touches Alt Gr + 7) sert à entourer les noms des objets de la BDD (base, table, colonne)

MySQL

SELECT * FROM maTable;
SELECT * FROM `maTable`;

MsSqlCe (sqlce ou mssql ce)

SELECT * FROM maTable;
SELECT * FROM "maTable";
SELECT * FROM [maTable];

Oracle

SELECT * FROM maTable;
SELECT * FROM "maTable";

Une explication par Doctrine PHP : Identifier quoting data for your database table

Une explication par Doctrine PHP : Defining Models meta data for your database table

Colonnes

Un problème de compatibilité de base de données est que les nombreuses bases de données diffèrent dans leur comportement de la façon dont le jeu de résultats d'une requête est renvoyée. MySQL laisse inchangés les noms de champ, ce qui signifie que si vous émettez une requête de la forme "SELECT ... FROM MyField" alors le résultat contient la MyField domaine.

Malheureusement, ce n'est que le méthode utilisée par MySQL et par d'autres bases de données. Postgres pour les retourne tout en minuscules tandis qu'Oracle retourne tous les noms de champs en majuscules. "Et alors? De quelle manière cela influence-t-moi lorsque vous utilisez la doctrine?", Vous pouvez demander. Heureusement, vous n'avez pas à vous soucier de cette question à tous.

Doctrine s'occupe de ce problème de manière transparente. Cela signifie que si vous définissez un enregistrement classe dérivée et de définir un champ appelé MyField vous serez toujours y accéder par le biais de $record->myField (ou $record['myField'], celui que vous préférez), peu importe si vous utilisez MySQL ou Postgres ou Oracle, etc...

En bref: Vous pouvez nommer vos champs comme vous le souhaitez, en utilisant sous_ligne, camelCase ou ce que vous préférez.

Dans les colonnes de la doctrine et les alias de colonnes sont sensibles à la casse. Ainsi, lorsque vous utilisez des colonnes dans vos requêtes DQL, les noms des colonnes / domaine doit correspondre le cas dans votre définition du modèle.

L'obtention d'une colonne différente entre MySQL et Oracle

Si sous MySQL vous avez la colonne "maColonne" et sous Oracle "MACOLONNE" et que vous utilisez PHP en FETCH ASSOC, vous allez vous retrouvez avec des index différents dans vos tableaux php de row :

// MySQL
$row['maColonne']
// Oracle
$row['MACOLONNE']

Si sous MySQL vous avez la colonne "maColonne" et sous Oracle "maColonne" et que vous utilisez PHP en FETCH ASSOC, vous allez vous retrouvez avec des index identiques dans vos tableaux php de row, mais vous devrez faire des select différents :

-- MySQL
SELECT maColonne FROM maTable;
-- Oracle
SELECT "maColonne" FROM maTable;

On peut imaginer utiliser AS pour uniformiser, mais guère pratique sur un SELECT *

-- MySQL
SELECT maColonne AS "maColonne" FROM maTable;
-- Oracle
SELECT MACOLONNE AS "maColonne" FROM maTable;

La sélection de colonne fixe statique

MySQL
SELECT colonneReelle FROM maTable; # valeur du row de la colonne : colonneReelle 
SELECT 'stringStatique' FROM maTable; # valeur "stringStatique"
SELECT "stringStatique" FROM maTable; # valeur "stringStatique"

Oracle

SELECT colonneReelle FROM maTable; # valeur du row de la colonne : colonneReelle (si la colonne COLONEREELLE existe)
SELECT 'stringStatique' FROM maTable; # valeur "stringStatique"
SELECT "colonneReelle" FROM maTable; # valeur du row de la colonne : colonneReelle (si la colonne colonneReelle existe)

Les noms des index

Au sein d'une même base de donnée, le nom attribués aux index, clefs primaires ou contraints des tables :

  • MySQL : peuvent êtres identiques
  • Oracle : doivent être distincts

MySQL

  • "PRIMARY" doit et ne peut être que le nom d'une clé primaire !
  • Le nom d'une clé primaire doit être PRIMARY!

Voyez la syntaxe d'ALTER TABLE

ADD PRIMARY KEY [index_type] (index_col_name,...)
ADD INDEX [index_name] [index_type] (index_col_name,...)

LIMIT

Oracle, SQL et LIMIT : Sous Oracle, le langage SQL ne comporte pas la fonction LIMIT, bien utile pour paginer les résultats d'une requête SELECT. Afin de pallier à cette absence, il est possible d'utiliser la pseudo-colonne ROWNUM.

Les résultats à partir de la 10ème ligne jusqu'à la 20ème :

SELECT colonne1
FROM maTable
WHERE <conditions> 
AND ROWNUM BETWEEN 10 AND 20;

Prendre en compte que la 1ère ligne de résultats d'un SELECT :

SELECT colonne1
FROM maTable
WHERE <conditions>
AND ROWNUM = 1;

Insertion multiples (mutiple insert sql)

MySQL

INSERT INTO tblName (column1,column2)
VALUES
('Value1','Fernando'),
('Value2','Carlos'),
('Value3','Vincent')

Oracle

INSERT INTO tblName (column1,column2)
SELECT 'Value1','Fernando' FROM dual
UNION ALL
SELECT 'Value2','Carlos' FROM dual
UNION ALL
SELECT 'Value3','Vincent' FROM dual

MS SQL CE

INSERT INTO [TABLE] (column1,column2)
SELECT 'Value1','Fernando'
UNION ALL
SELECT 'Value2','Carlos'
UNION ALL
SELECT 'Value3','Vincent'

La gestion des dates

La date actuelle (maintenant)

MS SQL Compact Edition

GETDATE()

MySQL

CURRENT_TIMESTAMP
-- NOW()	Return the current date and time
-- CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP	Synonyms for NOW()

DateTime MySQL, Oracle et SQL CE

Un champs datetime MySQL ou date Oracle peut être null, à la différence de SQL CE.

ISNULL MySQL with Oracle ?

Le nombre de colonnes maximum par table

Le nombre maximal de colonnes par table sous MySQL est limité en dur à 4096, mais dépends de nombreux facteurs :

  • Chaque table (quel que soit le moteur de stockage) a une taille maximale d'une ligne de 65.535 octets. Every table (regardless of storage engine) has a maximum row size of 65,535 bytes.
  • Chaque moteurs de stockage peuvent imposer des restrictions supplémentaires qui limitent le nombre de colonnes de table. Individual storage engines might impose additional restrictions that limit table column count. Exemples :
    • InnoDB permits no more than 1000 columns.
    • InnoDB restricts row size to something less than half a database page (approximately 8000 bytes), not including VARBINARY, VARCHAR, BLOB, or TEXT columns.
    • Different InnoDB storage formats (COMPRESSED, REDUNDANT) use different amounts of page header and trailer data, which affects the amount of storage available for rows.

For MyISAM tables, the maximum row length in bytes can be calculated as follows:

row length = 1
            + (sum of column lengths)
            + (number of NULL columns + delete_flag + 7)/8
            + (number of variable-length columns)
-- Listing de la taille des objets
SELECT *
FROM `COLUMNS`
WHERE `TABLE_SCHEMA` = 'ma_base'
AND TABLE_NAME = 'ma_table';
 
-- Somme des octets/bytes des colonnes
SELECT SUM(CHARACTER_OCTET_LENGTH) AS SUM_CHARACTER_OCTET_LENGTH
FROM `COLUMNS`
WHERE `TABLE_SCHEMA` = 'ma_base'
AND TABLE_NAME = 'ma_table';
-- 137663
 
-- Somme des octets/bytes des colonnes
SELECT SUM(CHARACTER_OCTET_LENGTH) AS SUM_CHARACTER_OCTET_LENGTH
FROM `COLUMNS`
WHERE `TABLE_SCHEMA` = 'ma_base'
AND TABLE_NAME = 'ma_table'
AND DATA_TYPE NOT IN ('BLOB','TEXT');
-- 6593

La taille de la longueur des noms des tables, des colonnes et des alias

Connaitre sous MySQL la taille des noms d'objets supérieurs à 30 caractères (bytes)

-- Taille des colonnes
SELECT *, LENGTH(COLUMN_NAME) FROM information_schema.COLUMNS WHERE LENGTH(COLUMN_NAME) > 30;
-- Tailles des routines : procédures et fonctions
SELECT *, LENGTH(ROUTINE_NAME) FROM information_schema.ROUTINES WHERE LENGTH(ROUTINE_NAME) > 30;
-- Taille des schémas
SELECT *, LENGTH(SCHEMA_NAME) FROM information_schema.SCHEMATA WHERE LENGTH(SCHEMA_NAME) > 30;
-- Taille des tables
SELECT *, LENGTH(TABLE_NAME) FROM information_schema.TABLES WHERE LENGTH(TABLE_NAME) > 30;
-- Taille des contraintes
SELECT *, LENGTH(CONSTRAINT_NAME) FROM information_schema.TABLE_CONSTRAINTS WHERE LENGTH(	CONSTRAINT_NAME) > 30;
SELECT *, LENGTH(CONSTRAINT_NAME) FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE LENGTH(CONSTRAINT_NAME) > 30;
-- Taille des triggers
SELECT *, LENGTH(TRIGGER_NAME) FROM information_schema.TRIGGERS WHERE LENGTH(TRIGGER_NAME) > 30;
-- Taille des vues
SELECT *, LENGTH(TABLE_NAME) FROM information_schema.VIEWS WHERE LENGTH(TABLE_NAME) > 30;

Et pour connaitre tous les objets d'une taille > à 30 char d'un schéma spécifié :

-- Taille de tous les objets d'un schéma dont la taille dépasse celle spécifiée (30)
SET @schema='mysql_to_oracle';
SET @taille_max = 30;
-- Taille des colonnes
SELECT 'COLUMN_NAME' AS objet_type, CONCAT( TABLE_NAME, '.', COLUMN_NAME ) AS objet_nom, LENGTH(COLUMN_NAME) AS taille FROM information_schema.COLUMNS WHERE LENGTH(COLUMN_NAME) > @taille_max
AND TABLE_SCHEMA = @schema
-- Taille des routines
UNION
SELECT 'ROUTINE_NAME', ROUTINE_NAME, LENGTH(ROUTINE_NAME) FROM information_schema.ROUTINES WHERE LENGTH(ROUTINE_NAME) > @taille_max
AND ROUTINE_SCHEMA = @schema
-- Taille des schémas
UNION
SELECT 'SCHEMA_NAME', SCHEMA_NAME, LENGTH(SCHEMA_NAME) FROM information_schema.SCHEMATA WHERE LENGTH(SCHEMA_NAME) > @taille_max
AND SCHEMA_NAME = @schema
-- Taille des tables
UNION
SELECT 'TABLE_NAME', TABLE_NAME, LENGTH(TABLE_NAME) FROM information_schema.TABLES WHERE LENGTH(TABLE_NAME) > @taille_max
AND TABLE_SCHEMA = @schema
-- Taille des contraintes
UNION
SELECT 'CONSTRAINT_NAME_TABLE', CONSTRAINT_NAME, LENGTH(CONSTRAINT_NAME) FROM information_schema.TABLE_CONSTRAINTS WHERE LENGTH(CONSTRAINT_NAME) > @taille_max
AND CONSTRAINT_SCHEMA = @schema
UNION
SELECT 'CONSTRAINT_NAME_CONSTRAINTS', CONSTRAINT_NAME, LENGTH(CONSTRAINT_NAME) FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE LENGTH(CONSTRAINT_NAME) > @taille_max
AND CONSTRAINT_SCHEMA = @schema
-- Taille des triggers
UNION
SELECT 'TRIGGER_NAME', TRIGGER_NAME, LENGTH(TRIGGER_NAME) FROM information_schema.TRIGGERS WHERE LENGTH(TRIGGER_NAME) > @taille_max
AND TRIGGER_SCHEMA = @schema
-- Taille des vues
UNION
SELECT 'TABLE_NAME', TABLE_NAME, LENGTH(TABLE_NAME) FROM information_schema.VIEWS WHERE LENGTH(TABLE_NAME) > @taille_max
AND TABLE_SCHEMA = @schema
;

Case sensitive

Les types sql

L'assistant de migration rapide de Oracle SQL Developer propose les options de conversion de types sources vers ces types de données oracle :

bigint  number(24,0)
binary  blob
bit     raw(10)
bit(1)  char(1)
blob    blob
char    char
date    date
datetime  date
decimal float(24,0)
double  float(24,0)
enum    varchar2(4000,0)
float   float(0,0)
int     number(10,0)
integer number(10,0)
longblob  blob
longtext  clob
mediumblob  blob
mediumint number(12.0)
mediumtext  clob
numeric   number
real    float(24,0)
set     varchar(1000,0)
smallint  number(5,0)
text    clob
time    date
timestamp date
tinyblob  blob
tinyint   number(3,0)
tinytext  clob
varbinary long raw
varchar varchar2
year  date

Scroll

Ressources

Les tutoriels, FAQ, forums et autres documentations relatives aux SGBD sur developpez.net :

SQL is un langage standard pour accéder aux bases de données. W3Schools SQL Tutorial vous apprendra comment utiliser SQL pour accéder et manipuler les données avec : MySQL, SQL Server, Access, Oracle, Sybase, DB2, et d'autres systèmes de base de données.

Les moteurs de données

MySQL

Oracle

SQL Server 2005 Compact Edition

Divers

Wikibooks.org semble très prometteur, en effet un article simple mais efficace vous montre les différences d'administration de 3 SGBD. Comparatif entre MySQL, PostgreSQL et Oracle.

Définitions Wikipédia

Forums developpez.net