Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 31/07/2011, 03h54   #1
Candidat au titre de Membre du Club
 
Homme Romain BILLOIR
Inscription : février 2007
Messages : 21
Détails du profil
Informations personnelles :
Nom : Homme Romain BILLOIR
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : février 2007
Messages : 21
Points : 10
Points : 10
Par défaut Procédure: Update or Delete si <= 0

Bonjour, j'aimerais faire une fonction SQL me permettant de:
Soustraire à un champ d'une table, une valeur n, et si le résultat de cette soustraction est égal ou inférieur à 0, supprimer la ligne identifiée par son id, le tout donné en paramètre.

Exemple:
Table joueur:
id | vie
1 | 100
2 | 25

Appel de la fonction:
Code :
SELECT mafonction('joueur', 'vie', 1, 50);
résultat:
id | vie
1 | 50
2 | 25

Code :
SELECT mafonction('joueur', 'vie', 2, 30);
résultat:
id | vie
1 | 50

Je veux que tous les noms des champs & table soient donnés en paramètre car je compte utiliser cette fonction sur plusieurs table(vie des joueurs, nombre de ressources, etc...).
Cette fonction peut paraître archi simple, mais pour un débutant en fonction SQL comme moi, je ne sais pas par où commencer. Si vous avez un tuto sur les fonctions SQL je suis preneur.

Merci d'avance.
Mazike est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 08h25   #2
Membre éprouvé
 
Inscription : janvier 2009
Messages : 301
Détails du profil
Informations personnelles :
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2009
Messages : 301
Points : 454
Points : 454
Bonjour,

Citation:
Soustraire à un champs d'une table, une valeur n, et si le résultat de cette soustraction est égal ou inférieur a 0, supprimer la ligne identifié par son id, le tout donnée en paramètre.
Tu veux soustraire la valeur N de la colonne VIE. Dans le cas ou le résultat devient inférieur à 0, tu supprimes la ligne.

Il est impossible de faire l'ensemble de ces opérations dans une seule requête. Pour parvenir à ce résultat, il faut passer par un procédure stockée.

Dans le respect des règles du forum, il serait bien de mentionner la base de données utilisée.

En SQL, à ma connaissance, il n'est pas possible de passer le nom des tables en paramètres.

Pour la lecture sur SQL, tu peux aller visite ce site http://sqlpro.developpez.com/ dans la partie "Initiation à SQL"

Tu essaies de résoudre ta demande avec les éléments fournis, si tu as des difficultés, tu reviens nous les présenter.

Bon courage
seabs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 10h43   #3
Membre éclairé
 
Avatar de boussafi
 
Homme
Ingénieur développement logiciels
Inscription : septembre 2007
Messages : 342
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Algérie

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Industrie

Informations forums :
Inscription : septembre 2007
Messages : 342
Points : 397
Points : 397
Envoyer un message via Yahoo à boussafi Envoyer un message via Skype™ à boussafi
seabs, en Oracle, on peut le nom de la table en parametre:

Code :
SELECT * FROM &nom_table


Mazike, sur quelle SGDB tu travail?
boussafi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 11h42   #4
Candidat au titre de Membre du Club
 
Homme Romain BILLOIR
Inscription : février 2007
Messages : 21
Détails du profil
Informations personnelles :
Nom : Homme Romain BILLOIR
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : février 2007
Messages : 21
Points : 10
Points : 10
Je suis sous PostgreSQL.
Si le passage en paramètre du nom de la table n'est pas possible je ferais plusieurs fonctions pour chaque table, enlevervie, soustraireressource, etc... mais une seul serait moins le foutoir
Mazike est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 12h17   #5
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 639
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 639
Points : 2 632
Points : 2 632
Bonjour,

Si, vous pouvez le faire sans problème au travers d'une procédure stocké.
Recherchez un peu sur google il y a plein d'exemple dispo.

Concernant votre problème initiale faites donc 2 requêtes (une pour update, suivi d'une pour delete).
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 12h25   #6
Membre éclairé
 
Avatar de boussafi
 
Homme
Ingénieur développement logiciels
Inscription : septembre 2007
Messages : 342
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Algérie

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Industrie

Informations forums :
Inscription : septembre 2007
Messages : 342
Points : 397
Points : 397
Envoyer un message via Yahoo à boussafi Envoyer un message via Skype™ à boussafi
je ne maitrise pas le PostgreSQL; mais j'essayé un sql standard:

pour ma mise à jour

exemple
Code :
1
2
3
4
5
6
7
8
9
10
UPDATE
(
 
SELECT * 
FROM joueur AS t  
WHERE id=1
AND ((vie-50)>0 )
 
)  
 SET vie=50

et la suppression

exemple
Code :
1
2
3
4
5
6
7
8
9
DELETE FROM
(
 
SELECT * 
FROM joueur AS t  
WHERE id=1
AND ((vie-50)<=0 )
 
)
boussafi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 12h28   #7
Candidat au titre de Membre du Club
 
Homme Romain BILLOIR
Inscription : février 2007
Messages : 21
Détails du profil
Informations personnelles :
Nom : Homme Romain BILLOIR
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : février 2007
Messages : 21
Points : 10
Points : 10
Citation:
Envoyé par boussafi Voir le message
je ne maitrise pas le PostgreSQL; mais j'essayé un sql standard: [...]
Le tout est de mettre ça dans une procédure stocké. J'ai essayé quelque chose:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE OR REPLACE FUNCTION soustraireousupprimer(identifiant integer, nbreasoustraire integer)
  RETURNS void AS
$BODY$DECLARE ligneResultat base%ROWTYPE;
BEGIN
	SELECT id, vie INTO ligneResultat FROM base WHERE id = identifiant;
	IF FOUND THEN
		IF ligneResultat.vie < nbreASoustraire THEN
			DELETE FROM base WHERE id = identifiant;
		ELSE
			UPDATE base SET vie = vie - nbreASoustraire WHERE id = identifiant;
		END IF;
	END IF;
END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Celà fonctionne, mais j'aimerais vraiment ne pas créer 20fonctions différentes pour mes 20tables... :/ je vais essayer d'amélioré ça.
Mazike est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 15h09   #8
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
On peut utiliser du SQL généré en plpgsql avec la fonction EXECUTE.

En revanche il n'est pas possible d'utiliser un type table%ROWTYPE comme tu l'as fait si "table" arrive dans la fonction sous la forme d'une chaine de caractères. Il faut utiliser directement le type final.

A noter aussi que ce code n'est pas valable pour une exécution simultanée de la fonction par plusieurs appelants, car le contenu de la table peut changer entre le SELECT et l'UPDATE ou DELETE.

Il serait préférable de faire directement de l'UPDATE et de faire ou non le DELETE en fonction du résultat de l'UPDATE, lequel peut être renvoyé avec une clause RETURNING.
Faire directement l'UPDATE met de fait un verrou sur la ligne, ce qui assure l'exclusion mutuelle d'une manière simple et sûre.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2011, 16h25   #9
Candidat au titre de Membre du Club
 
Homme Romain BILLOIR
Inscription : février 2007
Messages : 21
Détails du profil
Informations personnelles :
Nom : Homme Romain BILLOIR
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : février 2007
Messages : 21
Points : 10
Points : 10
Je vais aller voir ça, mais finalement je pense qu'il est plus pratique dans mon cas de faire plusieurs fonctions car finalement les données à gérer, bien que tous des integer doivent être traitées différemment: la vie qui atteint 0 doit être supprimée, en revanche la ressource qui est demandée en trop grand nombre, doit renvoyer un message d'erreur et ne pas être modifiée, des échanges de ressources entre les tables(donc INSERT et non DELETE, etc...). Et merci pour le tuyau de l'update puis delete.
Mazike est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h36.


 
 
 
 
Partenaires

Hébergement Web