Étiquette : SQL Server

Vincent Lecomte
[SQL] Insertion multiple

[SQL] Insertion multiple

Dans de nombreuses bases de données, il existe la possibilité d’effectuer une insertion multiple avec une seule requête SQL. La syntaxe suivante montre comment écrire la requête pour ajouter deux enregistrements.

INSERT INTO ma_table (col1, col2, ..., col n) 
VALUES 
  (val1, 'val2',..., val n),
  (val4, 'val5',..., val z)

La même requête en omettant le nom des colonnes.

INSERT ALL INTO ma_table (col1, col2,..., col n) 
VALUES (val1, 'val2',..., val n) 
INTO ma_table (col1, col2,..., col n) 
VALUES (val4, 'val5',..., val z)

Compatibilité

Disponible sur (liste non exhaustive) :

  • MySQL.
  • DB2 (idem sur OS/400).
  • HFSQL (à partir de la version 20).
  • PostgreSQL.
  • SQL Server 2008 et supérieur.
  • (…)

Si vous utilisez la base de données Oracle, la syntaxe est différente.

INSERT ALL INTO ma_table (col1, col2,..., col n) 
VALUES (val1, 'val2',..., val n)
INTO ma_table (col1, col2,..., col n) 
VALUES (val4, 'val5',..., val z)

Si vous utilisez une ancienne version de SQL Server (l’astuce suivante peut aussi être adaptée pour une base SQLite ou même Firebird).

INSERT INTO [schema.]MaTable (ID, Nom) 
SELECT 200, 'Vincent' 
UNION ALL 
SELECT 300, 'Cyril' 
UNION ALL 
SELECT 400, 'Rudi'

Avec Firebird 2.0 et supérieur on peut exécuter sous forme de bloc (voir la documentation officielle). N’hésitez pas à partager la syntaxe pour effectuer la même opération dans des bases de données différentes !

[SQL] Convertir une colonne Date/Heure

[SQL] Convertir une colonne Date/Heure

Dans SQL Server, il est possible de convertir en date courte ou en chaine de caractères une colonne de type DATETIME. On peut utiliser la fonction CONVERT() ou encore la fonction CAST(). Dans cet exemple, nous utilisons la première qui prend en paramètre le type de données de destination ainsi que sa longueur (facultative), l’expression à convertir et enfin le style qui spécifie comment doit être traduite l’expression.

SELECT CONVERT(VARCHAR(10), [ma_colonne], 112) 
FROM table

La requête va renvoyer des dates au format ISO “AAAAMMJJ” soit l’année, le mois et le jour. Si on regarde la documentation, c’est grâce à la valeur 112 spécifiée pour le style que l’on obtient ce résultat. On peut donc facilement personnaliser la valeur retournée par la requête. Cela peut également être très pratique dans une condition.

[SQL] Mémo – Modifier le type d’une colonne

[SQL] Mémo – Modifier le type d’une colonne

Pour modifier le type d’une colonne dans une table DB2/400, vous pouvez utiliser la syntaxe ALTER TABLE … ALTER COLUMN. Il faudra cependant spécifier une clause supplémentaire : SET DATA TYPE. Cela vous permettra de changer la taille par exemple, ou bien passer d’un entier sur 4 octets à un entier sur 8. Exemple :

ALTER TABLE 'biblio.table' ALTER COLUMN email 
SET DATA TYPE varchar(50);

Dans cet exemple nous modifions la colonne qui contient l’e-mail en indiquant qu’on souhaite une chaine de caractères à taille variable d’un maximum de 50 caractères. Dans SQL Server, cela donnerait quelque chose comme ceci :

ALTER TABLE 'schema.table' ALTER COLUMN email varchar(50);

Et dans Oracle ou même MySQL :

ALTER TABLE 'schema.table' MODIFIY COLUMN email varchar(50);

Bon développement !

[SQL] 80040e57 : Arithmetic Overflow SQL Server

[SQL] 80040e57 : Arithmetic Overflow SQL Server

Lorsque vous effectuez une insertion dans une colonne avec une valeur numérique trop grande ou lorsque vous effectuez par exemple une somme impliquant une ou plusieurs colonnes numérique dont le résultat dépasse le type imposé (par exemple, le résultat obtenu dépasse l’entier), vous obtenez l’exception 80040e57 avec par exemple le message d’erreur suivant : “Arithmetic overflow error converting expression to data type int”.

Par exemple, supposons la requête suivante :

SELECT b.Cart, SUM(a.QTE * b.POIDS) 
FROM Commande a JOIN Article b 
ON a.cart = b.cart 
WHERE ... 
GROUP BY ...

On sait que la colonne QTE et la colonne POIDS sont au format entier (int). Si le résultat de la somme pour l’article vient à dépasser la limite maximale définie par le type entier, une erreur sera renvoyée. Une solution consiste donc à convertir chaque colonne dans un autre type (exemple: bigint). Cela donnerait par exemple :

SELECT b.Cart, SUM( CAST(a.QTE AS BIGINT) 
  * CAST(b.POIDS AS BIGINT)) 
FROM Commande a JOIN Article b 
ON a.cart = b.cart 
WHERE ... GROUP BY ...

Dans le cas d’une opération d’insertion ou de mise à jour, il faudra peut-être envisager de modifier le type de la colonne destination ou restreindre les valeurs possibles qui peuvent être stockées dans la table. Pour obtenir davantage d’informations consultez la base de connaissances Microsoft Technet (MS163363).

[WD17] Le délai d’attente de la requête a expiré

[WD17] Le délai d’attente de la requête a expiré

Lorsque vous tentez d’exécuter une requête sur un serveur distant SQL Server, vous pouvez obtenir l’erreur suivante : “Erreur 80040e31, le délai d’attente de la requête a expiré”. En fait, le serveur n’a pas répondu assez vite à la commande envoyée. En effet, il faut bien distinguer le temps d’exécution maximum d’une requête distante (qu’on définit dans les paramètres de SQL Server) et le temps accordé avant qu’une commande envoyée n’expire. C’est pour cela qu’on ne doit pas modifier directement de paramètre sur le serveur mais bien dans la chaine de connexion à la base de données.

Avec HDécritConnexion, vous pouvez définir des informations étendues. Vous pouvez également faire de même en éditant la propriété “InfosEtendues” de la variable de type “Connexion”. La documentation vous indique quelles sont les informations optionnelles utilisables dans la chaine de connexion. Celle qui attire notre attention ici est “WD Command Timeout”, qui permet de fixer la durée maximale de l’exécution d’une commande.

Les valeurs possibles sont :

  • -1 : valeur par défaut définie par la couche client (dans WinDev, il s’agit de 30 secondes – cela s’applique aussi à HyperFileSQL C/S).
  • 0 : illimité. Faites bien attention car des blocages peuvent survenir.
  • > 0 : temps en secondes (dans notre exemple, nous avons indiqué 600 secondes, soit 10 minutes).

En .NET (par exemple en VB ou en C#), il est également possible de définir ce timeout en le précisant dans une propriété (CommandTimeout) de la variable SqlCommand. L’exemple ci-dessous permet d’augmenter le temps jusqu’à 90 secondes avant l’expiration.

Enfin, en Java, il suffit d’appeler la fonction “setQueryTimeOut” de l’objet “Statement” qu’on aura au préalable initialisé. Dans l’exemple, on laisse un délai de 60 secondes pour envoyer la commande, avant qu’elle n’expire. Il faut impérativement utiliser cette fonction avant d’exécuter la requête.

Nous pouvons évidemment continuer à citer les différentes analogies entre les nombreux langages de programmation qui existent, mais cela risquerait de prendre beaucoup trop de temps. Ainsi, voici un billet qui pourra servir de mémo dans le futur, au cas où cela vous échapperait à nouveau.

[SQL] Nouvelle table via un SELECT INTO

[SQL] Nouvelle table via un SELECT INTO

Pour certains, il pourrait s’agir d’un rappel de syntaxe, pour d’autres, et ce fut mon cas, ceci est plutôt une découverte. Lorsque vous souhaitez sauvegarder rapidement le contenu d’une table sans passer par un système complexe, il vous suffit d’utiliser une requête de type SELECT … INTO … FROM.

Voici la syntaxe pouvant être utilisée :

SELECT * | champ1, champ2… champ n 
INTO nouvelle_table [IN base_externe] 
FROM ancienne_table
  • Possibilité de reprendre toute la table ou une partie de celles-ci.
  • La base de données externe peut être une base Access par exemple.
  • Une jointure peut être faite dans le FROM et des conditions peuvent être ajoutées dans la clause WHERE (comme s’il s’agissait d’une requête tout à fait classique).

Certaines bases de données comme MySQL ne supportent pas la copie vers une table avec cette syntaxe. Par exemple, sous cette dernière, la clause SELECT INTO existe bel et bien, mais elle permet de générer un fichier en sortie ou de stocker le résultat dans des variables. Sous DB2/400, il est impossible d’exécuter ce type de requête en mode interactif.

En revanche, cette syntaxe est applicable dans Microsoft Access, puisqu’il est possible de générer la nouvelle table dans une base externe, comme il a été détaillé ci-dessus. On retrouve également cette fonctionnalité dans PostgreSQL. Dans Oracle, il est préférable d’utiliser l’instruction CREATE TABLE x AS SELECT.

Sources

MySQL Select Into Outfile
PostgreSQL – Select into
W3Schools