Construisez vos requêtes SQL SELECT, INSERT, UPDATE et DELETE visuellement. Choisissez table, colonnes, WHERE, JOIN et ORDER BY sans écrire de code.
Générateur SQL visuel — Builder de requêtes
Pourquoi utiliser un builder SQL visuel ?
Écrire des requêtes SQL à la main est une compétence fondamentale pour tout développeur back-end. Mais pour les débutants, les juniors ou les développeurs front-end qui touchent occasionnellement aux bases de données, cela représente une source d'erreurs fréquentes : fautes de syntaxe, oubli de virgules, JOIN mal formés, conditions WHERE manquantes sur un UPDATE ou un DELETE catastrophique.
Un builder SQL visuel résout ces problèmes en vous permettant de construire vos requêtes point à point, en remplissant des formulaires intuitifs. L'outil génère ensuite un SQL propre, indenté, avec les mots-clés en majuscules — prêt à être copié dans votre client MySQL, phpMyAdmin, TablePlus ou votre code PHP.
Les cas où un builder visuel est le plus utile
- Apprentissage du SQL : Comprendre visuellement comment une clause JOIN ou un WHERE complexe se traduit en syntaxe SQL réelle
- Prototypage rapide : Explorer la structure d'une table sans mémoriser la syntaxe exacte de chaque clause
- Revues de code : Générer une requête de référence pour comparer avec le SQL produit par votre ORM (Eloquent, Doctrine)
- Débogage : Reconstituer manuellement la requête qu'un ORM génère automatiquement afin de l'optimiser
- Formation : Enseigner SQL à des équipes en montrant en temps réel comment chaque option modifie la requête
Qu'est-ce que ce builder génère exactement ?
Notre outil génère les 4 types de requêtes DML (Data Manipulation Language) les plus courants :
| Type | Usage | Options disponibles |
|---|---|---|
| SELECT | Lire des données | Colonnes, WHERE, JOIN (INNER/LEFT/RIGHT/FULL OUTER), ORDER BY, LIMIT/OFFSET |
| INSERT | Insérer des données | Table, paires colonne/valeur |
| UPDATE | Modifier des données | Table, colonnes SET, conditions WHERE |
| DELETE | Supprimer des données | Table, conditions WHERE (avec avertissement si absent) |
Comprendre les requêtes SELECT et leurs options
La requête SELECT est la plus utilisée en SQL. Elle permet de lire et filtrer des données depuis une ou plusieurs tables. Notre builder expose toutes ses options principales :
SELECT * vs colonnes spécifiques
La checkbox "SELECT *" sélectionne toutes les colonnes de la table. C'est pratique pour explorer une table, mais en production, il vaut mieux lister explicitement les colonnes nécessaires pour :
- Réduire la quantité de données transférées entre le SGBD et l'application
- Éviter de récupérer des colonnes sensibles (mot de passe hashé, tokens) par inadvertance
- Rendre la requête plus lisible et maintenable
-- ❌ À éviter en production
SELECT * FROM users WHERE is_active = 1;
-- ✅ Recommandé : colonnes explicites
SELECT
id,
email,
created_at
FROM users
WHERE is_active = 1;
Les conditions WHERE
La clause WHERE filtre les lignes retournées. Notre builder supporte les opérateurs suivants :
| Opérateur | Signification | Exemple |
|---|---|---|
= | Égalité exacte | status = 'actif' |
!= | Différent de | role != 'admin' |
> / < | Supérieur / inférieur | age > 18 |
>= / <= | Supérieur ou égal / inférieur ou égal | score >= 80 |
LIKE | Correspondance partielle | email LIKE '%@gmail.com' |
IS NULL | Valeur nulle | deleted_at IS NULL |
IS NOT NULL | Valeur non nulle | verified_at IS NOT NULL |
= NULL pour tester la nullité — utilisez toujours IS NULL. La comparaison colonne = NULL retourne toujours FALSE en SQL standard.
Les jointures (JOIN)
Un JOIN combine les données de plusieurs tables. Notre builder supporte 4 types :
-- INNER JOIN : lignes présentes dans les 2 tables
SELECT u.id, u.email, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.total > 100;
-- LEFT JOIN : toutes les lignes de gauche + correspondances droite
SELECT u.id, u.email, COUNT(o.id) AS nb_commandes
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.email;
-- RIGHT JOIN : toutes les lignes de droite + correspondances gauche
SELECT u.email, p.name AS produit
FROM users u
RIGHT JOIN purchases p ON u.id = p.user_id;
-- FULL OUTER JOIN : toutes les lignes des 2 tables (PostgreSQL)
SELECT u.id, p.id AS projet_id
FROM users u
FULL OUTER JOIN projects p ON u.id = p.owner_id;
ORDER BY et pagination
ORDER BY trie les résultats. LIMIT et OFFSET permettent la pagination :
-- Pagination page 2 (10 résultats par page)
SELECT id, title, created_at
FROM articles
WHERE status = 'published'
ORDER BY created_at DESC
LIMIT 10 OFFSET 10; -- OFFSET = (page - 1) * limit
INSERT, UPDATE, DELETE : guide pratique
Ces trois types de requêtes constituent le DML (Data Manipulation Language). Elles modifient les données et doivent être utilisées avec précaution, surtout en production.
INSERT — Insérer des données
L'INSERT ajoute une ou plusieurs lignes dans une table. Notre builder génère un INSERT avec les colonnes et valeurs spécifiées :
-- INSERT standard généré par le builder
INSERT INTO users (username, email, password_hash, created_at)
VALUES ('alice', 'alice@example.com', 'bcrypt_hash_here', '2026-05-13');
-- INSERT multiple (plusieurs lignes) — à faire manuellement
INSERT INTO tags (name, slug)
VALUES
('JavaScript', 'javascript'),
('TypeScript', 'typescript'),
('Angular', 'angular');
$stmt = $pdo->prepare("INSERT INTO users (email) VALUES (:email)"). Cela protège contre les injections SQL.
UPDATE — Modifier des données
L'UPDATE modifie les valeurs de colonnes existantes. La règle d'or : toujours inclure une clause WHERE pour éviter de mettre à jour toute la table par inadvertance.
-- ❌ DANGER : met à jour TOUTES les lignes
UPDATE users SET is_active = 0;
-- ✅ Correct : cible une ligne spécifique
UPDATE users
SET
is_active = 0,
deactivated_at = NOW()
WHERE id = 42;
-- UPDATE avec jointure (MySQL)
UPDATE users u
INNER JOIN subscriptions s ON u.id = s.user_id
SET u.plan = 'premium'
WHERE s.expires_at > NOW();
DELETE — Supprimer des données
Le DELETE supprime des lignes. Notre builder affiche un avertissement si aucune condition WHERE n'est définie. En production, toujours tester avec un SELECT d'abord :
-- Vérifier avant de supprimer (remplacer DELETE par SELECT COUNT(*))
SELECT COUNT(*) FROM sessions WHERE expire_at < NOW();
-- Puis supprimer si le nombre est correct
DELETE FROM sessions
WHERE expire_at < NOW();
-- Soft delete (marquer comme supprimé sans réellement effacer)
UPDATE users
SET deleted_at = NOW()
WHERE id = 99;
-- Puis filtrer : WHERE deleted_at IS NULL
- ✅ La clause WHERE est présente et correcte
- ✅ Testé d'abord avec SELECT COUNT(*) pour voir le nombre de lignes affectées
- ✅ Backup de la table effectué si l'opération est critique
- ✅ Requête préparée utilisée si les valeurs viennent de l'utilisateur
- ✅ Transaction utilisée si plusieurs opérations sont liées
Bonnes pratiques SQL et sécurité
La sécurité d'une application web repose en grande partie sur la façon dont elle interagit avec sa base de données. Voici les règles essentielles à connaître et appliquer.
Injection SQL — La menace n°1
L'injection SQL est la vulnérabilité web la plus classique (OWASP Top 10). Elle permet à un attaquant d'exécuter des requêtes arbitraires en manipulant les entrées utilisateur :
// ❌ DANGER : concaténation directe — injection SQL possible
$email = $_POST['email']; // Valeur: "' OR '1'='1"
$query = "SELECT * FROM users WHERE email = '" . $email . "'";
// Requête résultante : SELECT * FROM users WHERE email = '' OR '1'='1'
// Résultat : retourne TOUS les utilisateurs !
// ✅ Solution : requêtes préparées avec PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute([':email' => $_POST['email']]);
$user = $stmt->fetch();
// ✅ Ou avec MySQLi
$stmt = $mysqli->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param('s', $_POST['email']);
$stmt->execute();
Principe du moindre privilège
L'utilisateur MySQL utilisé par votre application ne doit avoir que les droits strictement nécessaires :
-- Créer un utilisateur avec droits limités (MySQL)
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'mot_de_passe_fort';
-- Accorder seulement SELECT, INSERT, UPDATE, DELETE (pas DROP, ALTER, CREATE)
GRANT SELECT, INSERT, UPDATE, DELETE ON ma_base.* TO 'app_user'@'localhost';
-- Pour un utilisateur en lecture seule (reporting)
GRANT SELECT ON ma_base.* TO 'readonly_user'@'localhost';
FLUSH PRIVILEGES;
Performances et index
Un SQL fonctionnel mais lent peut paralyser une application. Les index sont la solution principale :
-- Toujours indexer les colonnes utilisées dans WHERE, JOIN ON et ORDER BY
CREATE INDEX idx_users_email ON users (email);
CREATE INDEX idx_orders_user_id ON orders (user_id);
CREATE INDEX idx_articles_status_date ON articles (status, created_at);
-- Utiliser EXPLAIN pour analyser le plan d'exécution
EXPLAIN SELECT u.id, COUNT(o.id)
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.is_active = 1
GROUP BY u.id;
Transactions pour l'intégrité des données
-- Transfert bancaire : 2 opérations liées → transaction obligatoire
BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;
-- Vérifier que le solde du compte source est >= 0
SELECT balance FROM accounts WHERE id = 1;
-- Si balance >= 0 : COMMIT; sinon : ROLLBACK;
COMMIT;
Cas d'usage réels (PHP/MySQL, Laravel, Symfony)
Voyons comment les requêtes générées par notre builder s'intègrent dans des frameworks PHP courants.
PHP natif avec PDO
<?php
// Connexion PDO (bonne pratique)
$dsn = 'mysql:host=localhost;dbname=ma_base;charset=utf8mb4';
$pdo = new PDO($dsn, 'app_user', 'mot_de_passe', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
// SELECT généré par le builder → adapté en PDO
$stmt = $pdo->prepare("
SELECT
id,
email,
username,
created_at
FROM users
INNER JOIN subscriptions s ON users.id = s.user_id
WHERE users.is_active = 1
AND s.expires_at > NOW()
ORDER BY created_at DESC
LIMIT :limit OFFSET :offset
");
$stmt->bindValue(':limit', 10, PDO::PARAM_INT);
$stmt->bindValue(':offset', 0, PDO::PARAM_INT);
$stmt->execute();
$users = $stmt->fetchAll();
?>
Laravel — Eloquent vs Query Builder
// Query Builder Laravel (proche du SQL généré par notre outil)
$users = DB::table('users')
->select('id', 'email', 'username', 'created_at')
->join('subscriptions', 'users.id', '=', 'subscriptions.user_id')
->where('users.is_active', 1)
->where('subscriptions.expires_at', '>', now())
->orderByDesc('created_at')
->paginate(10);
// Eloquent (ORM) — abstraction plus haute
$users = User::with('subscription')
->where('is_active', true)
->whereHas('subscription', fn($q) => $q->where('expires_at', '>', now()))
->latest()
->paginate(10);
// Afficher le SQL généré par Eloquent (debug)
User::where('is_active', true)->toSql();
// ou avec les bindings :
User::where('is_active', true)->getBindings();
Symfony avec Doctrine Query Builder
// Doctrine QueryBuilder (Symfony)
$users = $entityManager
->createQueryBuilder()
->select('u.id, u.email, u.username, u.createdAt')
->from(User::class, 'u')
->innerJoin('u.subscription', 's')
->where('u.isActive = :active')
->andWhere('s.expiresAt > :now')
->setParameter('active', true)
->setParameter('now', new \DateTime())
->orderBy('u.createdAt', 'DESC')
->setMaxResults(10)
->getQuery()
->getResult();
// DQL équivalent
$dql = "SELECT u FROM App\Entity\User u
JOIN u.subscription s
WHERE u.isActive = :active AND s.expiresAt > :now
ORDER BY u.createdAt DESC";
toSql() (Laravel) ou getDQL() (Doctrine), et optimisez en conséquence.
FAQ — Questions fréquentes
À quoi sert le générateur SQL visuel ?
Il permet de construire des requêtes SQL SELECT, INSERT, UPDATE et DELETE visuellement, sans écrire une seule ligne de code. Idéal pour les débutants, les juniors et les développeurs PHP/MySQL qui souhaitent prototyper rapidement ou apprendre la syntaxe SQL.
Comment construire une requête SELECT avec cet outil ?
Cliquez sur l'onglet SELECT, saisissez le nom de votre table, ajoutez les colonnes souhaitées (ou cochez "SELECT *"), configurez les conditions WHERE, ajoutez des JOIN si nécessaire, définissez le tri ORDER BY et la pagination LIMIT/OFFSET, puis cliquez sur "Générer SQL".
Le SQL généré est-il compatible MySQL et PostgreSQL ?
Le builder génère du SQL standard compatible avec MySQL, MariaDB, PostgreSQL et SQLite. La syntaxe SELECT, INSERT, UPDATE, DELETE avec WHERE, JOIN et ORDER BY est identique entre ces moteurs. Seuls quelques types de données ou fonctions spécifiques diffèrent selon le SGBD.
Mes données sont-elles envoyées à un serveur ?
Non. L'outil fonctionne entièrement dans votre navigateur avec JavaScript. Aucune donnée — ni les noms de tables, ni les valeurs — n'est transmise à un serveur externe. Vous pouvez l'utiliser en toute confidentialité avec des données de production.
Comment éviter le DELETE ou UPDATE accidentel de toute une table ?
Notre builder affiche un avertissement visuel si vous tentez de générer un DELETE ou un UPDATE sans clause WHERE. En pratique, testez toujours d'abord avec un SELECT COUNT(*) utilisant les mêmes conditions WHERE, puis exécutez la modification. En base de production, utilisez des transactions pour pouvoir faire un ROLLBACK.
Quelle est la différence entre JOIN et sous-requête ?
Un JOIN combine des lignes de plusieurs tables dans un seul résultat — c'est la solution recommandée et la plus performante (l'optimiseur peut utiliser les index). Une sous-requête est une requête imbriquée dans une autre — plus lisible pour certains cas (EXISTS, IN), mais parfois moins efficace. Préférez les JOIN pour les relations directes entre tables.
Qu'est-ce qu'un FULL OUTER JOIN ?
Un FULL OUTER JOIN retourne toutes les lignes des deux tables, avec des NULL pour les colonnes sans correspondance de l'autre côté. Il est nativement supporté par PostgreSQL et SQL Server. Sur MySQL, on le simule avec LEFT JOIN UNION RIGHT JOIN. Notre builder le génère directement pour les cas PostgreSQL.
Comment générer un INSERT avec plusieurs lignes ?
Le builder génère actuellement des INSERT avec une seule ligne de valeurs. Pour insérer plusieurs lignes, dupliquez la clause VALUES manuellement : VALUES ('val1a', 'val1b'), ('val2a', 'val2b'). Cette syntaxe est plus performante qu'autant d'INSERT individuels car elle réduit les allers-retours réseau avec le SGBD.
Conclusion
Le générateur SQL visuel d'AngularForAll est un outil gratuit, 100% client-side, conçu pour vous aider à construire des requêtes SQL correctes sans mémoriser chaque détail de la syntaxe. Que vous soyez junior en apprentissage, développeur PHP full-stack ou développeur Angular qui touche occasionnellement au back-end, ce builder vous fait gagner du temps et vous évite les erreurs classiques.
Les requêtes générées respectent les meilleures pratiques : mots-clés en majuscules, indentation propre, avertissement sur DELETE sans WHERE. Utilisez-les directement dans phpMyAdmin, TablePlus, DBeaver, MySQL Workbench ou dans votre code PHP avec des requêtes préparées PDO.