You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
11 KiB
421 lines
11 KiB
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
EXEC SQL INCLUDE SQLCA.H;
|
|
EXEC SQL INCLUDE SQLDA.H;
|
|
EXEC SQL INCLUDE ORACA.H;
|
|
|
|
#define CLEAR system("clear")
|
|
|
|
/********** Constantes **********/
|
|
#define CONTINUE 0
|
|
#define DATE_LEN 11
|
|
#define DEPT_LEN 3
|
|
#define NOM_LEN 21
|
|
#define NOT_FOUND 1403
|
|
#define REFERENCE_LEN 5
|
|
#define SQL_COMMIT 1
|
|
#define SQL_ROLLBACK 0
|
|
#define SQL_SUCCESS 0
|
|
#define STOP 1
|
|
#define UID_LEN 30
|
|
#define VARCHAR_LEN 51
|
|
|
|
/********** Liste des fonctions **********/
|
|
void connexion(void);
|
|
void erreur_sql(int arret);
|
|
void deconnexion(int validation);
|
|
void q1(void);
|
|
int q1bis(void);
|
|
void q2(void);
|
|
void q3(void);
|
|
void q4(void);
|
|
void q5(void);
|
|
void q6(void);
|
|
void q7(void);
|
|
/*
|
|
* Fonction de connexion à Oracle.
|
|
*
|
|
* Les identifiants sont rentrés en dur pour ne pas avoir à les retaper
|
|
* à la main à chaque test, mais dans l'idéal, on demande à l'utilisateur
|
|
* de les rentrer et on concatène les identifiants à uid.arr.
|
|
*/
|
|
void connexion(void) {
|
|
VARCHAR uid[UID_LEN];
|
|
char identifiants[UID_LEN] = "danguyen1/danguyen1@kirov";
|
|
printf("Connexion avec les identifiants suivants : %s .\n", identifiants);
|
|
strcpy(uid.arr, identifiants);
|
|
uid.len = strlen(uid.arr);
|
|
|
|
EXEC SQL CONNECT :uid;
|
|
if (sqlca.sqlcode == SQL_SUCCESS) {
|
|
printf("Connexion réussie avec succès !\n\n");
|
|
}
|
|
else {
|
|
printf("Connexion échouée !\n\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fonction qui affiche les code et message d'erreur SQL.
|
|
*
|
|
* Paramètres :
|
|
* arret STOP(1) pour quitter, n'importe quoi pour continuer
|
|
*/
|
|
void erreur_sql(int arret) {
|
|
printf("Code d'erreur : %d.\n", sqlca.sqlcode);
|
|
printf("Message erreur : %.*s.\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
|
|
if (arret == STOP) {
|
|
deconnexion(SQL_ROLLBACK);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fonction de déconnexion.
|
|
*
|
|
* Paramètres :
|
|
* validation SQL_COMMIT(1) pour COMMIT, n'importe quoi pour ROLLBACK
|
|
*/
|
|
void deconnexion(int validation) {
|
|
if (validation == SQL_COMMIT) {
|
|
EXEC SQL COMMIT WORK RELEASE;
|
|
}
|
|
else {
|
|
EXEC SQL ROLLBACK WORK RELEASE;
|
|
}
|
|
printf("Déconnexion réussie, travail %s.\n", validation == 1 ? "enregistré" : "annulé");
|
|
}
|
|
|
|
/*
|
|
* Affiche le nombre de produits contenus dans la base (utilisée dans la question 3
|
|
* car pas d'intérêt à être utilisée toute seule).
|
|
*
|
|
* Retourne :
|
|
* le nombre de produits contenus dans la base
|
|
*/
|
|
int q1(void) {
|
|
int nbProd;
|
|
EXEC SQL SELECT COUNT(*) INTO nbProd FROM TPRODUIT;
|
|
printf("Il y a %d produits en base.\n", nbProd);
|
|
return nbProd;
|
|
}
|
|
|
|
/*
|
|
* Modifie un produit en affichant ses anciennes valeurs.
|
|
*/
|
|
void q2(void) {
|
|
char codeRayon[REFERENCE_LEN], dateStock[DATE_LEN], nCodeRayon[REFERENCE_LEN], nDateStock[DATE_LEN], noProd[REFERENCE_LEN];
|
|
int choix, nStock, stock;
|
|
float nPrixV, prixV;
|
|
VARCHAR des[VARCHAR_LEN], nDes[VARCHAR_LEN];
|
|
|
|
printf("Saisir numéro produit : ");
|
|
scanf("%s%*c", noProd);
|
|
|
|
EXEC SQL
|
|
SELECT des, stock, prixV, codeRayon, dateStock
|
|
INTO :des, :stock, :prixV, :codeRayon, :dateStock
|
|
FROM TPRODUIT
|
|
WHERE noProd = :noProd;
|
|
|
|
printf("1 - Désignation : %.*s.\n", des.len, des.arr);
|
|
printf("2 - Stock : %d.\n", stock);
|
|
printf("3 - Prix de vente : %.2f€.\n", prixV);
|
|
printf("4 - Code rayon : %s.\n", codeRayon);
|
|
printf("5 - Date : %s.\n", dateStock);
|
|
|
|
while (choix != 9) {
|
|
printf("Que voulez-vous modifier (9: quitter) ?\n");
|
|
scanf("%d%*c", &choix);
|
|
|
|
switch (choix) {
|
|
case 1:
|
|
printf("Entrez la nouvelle désignation : ");
|
|
fgets(nDes, sizeof nDes, stdin);
|
|
if (nDes[strlen(nDes) - 1] == '\n') {
|
|
nDes[strlen(nDes) - 1] = '\0';
|
|
}
|
|
EXEC SQL
|
|
UPDATE TPRODUIT
|
|
SET des = :nDes
|
|
WHERE noProd = :noProd;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
break;
|
|
case 2:
|
|
printf("Entrez le nouveau stock : ");
|
|
scanf("%d%*c", &nStock);
|
|
EXEC SQL
|
|
UPDATE TPRODUIT
|
|
SET stock = :nStock
|
|
WHERE noProd = :noProd;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
break;
|
|
case 3:
|
|
printf("Entrez le nouveau prix : ");
|
|
scanf("%f%*c", &nPrixV);
|
|
EXEC SQL
|
|
UPDATE TPRODUIT
|
|
SET prixV = :nPrixV
|
|
WHERE noProd = :noProd;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
break;
|
|
case 4:
|
|
printf("Entrez le nouveau code rayon : ");
|
|
scanf("%s", &nCodeRayon);
|
|
EXEC SQL
|
|
UPDATE TPRODUIT
|
|
SET codeRayon = :nCodeRayon
|
|
WHERE noProd = :noProd;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
break;
|
|
case 5:
|
|
printf("Entrez la date : ");
|
|
scanf("%s", &nDateStock);
|
|
EXEC SQL
|
|
UPDATE TPRODUIT
|
|
SET dateStock = :nDateStock
|
|
WHERE noProd = :noProd;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
break;
|
|
default:
|
|
printf("Choix inconnu.\n");
|
|
break;
|
|
}
|
|
EXEC SQL COMMIT;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Affiche le nombre de produits en base et les affiche.
|
|
*/
|
|
void q3(void) {
|
|
char noProd[REFERENCE_LEN], codeRayon[REFERENCE_LEN], dateStock[DATE_LEN];
|
|
int cpt = 0, nbProd, stock;
|
|
float prixV;
|
|
VARCHAR des[REFERENCE_LEN1];
|
|
|
|
nbProd = q1bis();
|
|
if (nbProd > 0) {
|
|
EXEC SQL
|
|
DECLARE cprod CURSOR FOR
|
|
SELECT noProd, des, stock, prixV, codeRayon, dateStock
|
|
FROM TPRODUIT;
|
|
EXEC SQL OPEN cprod;
|
|
EXEC SQL FETCH cprod INTO :noProd, :des, :stock, :prixV, :codeRayon, :dateStock;
|
|
|
|
while (sqlca.sqlcode != NOT_FOUND) {
|
|
printf("----- Produit n°%d -----\n", ++cpt);
|
|
printf("Numéro produit : %s.\n", noProd);
|
|
printf("Désignation : %.*s.\n", des.len, des.arr);
|
|
printf("Stock : %d.\n", stock);
|
|
printf("Prix de vente : %.2f.\n", prixV);
|
|
printf("Code rayon : %s.\n", codeRayon);
|
|
printf("Date stock : %s.\n", dateStock);
|
|
EXEC SQL
|
|
FETCH cprod INTO :noProd, :des, :stock, :prixV, :codeRayon, :dateStock;
|
|
if (sqlca.sqlcode < SQL_SUCCESS) {
|
|
erreur_sql(STOP);
|
|
}
|
|
}
|
|
EXEC SQL CLOSE cprod;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Ajoute un produit saisi.
|
|
*/
|
|
void q4(void) {
|
|
char choix, noProd[REFERENCE_LEN], dateStock[DATE_LEN];
|
|
int stock;
|
|
float prixV;
|
|
short indicateurDes = 0, indicateurStock = 0, indicateurPrixV = 0, indicateurCodeRayon = 0, indicateurDateStock = 0;
|
|
VARCHAR des[VARCHAR_LEN];
|
|
|
|
printf("Saisir numéro produit : ");
|
|
scanf("%s%*c", noProd);
|
|
printf("Saisir une désignation (O/*) ? ");
|
|
scanf("%c%*c", &choix);
|
|
if (toUpper(choix) == 'O') {
|
|
printf("Saisir la désignation : ");
|
|
fgets(des, sizeof des, stdin);
|
|
if (des[strlen(des) - 1] == '\n') {
|
|
des[strlen(des) - 1] = '\0';
|
|
}
|
|
}
|
|
else {
|
|
indicateurDes = -1;
|
|
}
|
|
|
|
printf("Saisir un stock (O/*) ? ");
|
|
scanf("%c%*c", &choix);
|
|
if (toUpper(choix) == 'O') {
|
|
printf("Saisir le stock : ");
|
|
scanf("%d%*c", &stock);
|
|
}
|
|
else {
|
|
indicateurStock = -1;
|
|
}
|
|
|
|
printf("Saisir un prix de vente : ");
|
|
scanf("%c%*c", &choix);
|
|
if (toUpper(choix) == 'O') {
|
|
printf("Saisir le prix de vente : ");
|
|
scanf("%f%*c", &prixV);
|
|
}
|
|
else {
|
|
indicateurPrixV = -1;
|
|
}
|
|
|
|
printf("Saisir un code rayon (O/*) ? ");
|
|
scanf("%c%*c", &choix);
|
|
if (toUpper(choix) == 'O') {
|
|
printf("Saisir le code rayon : ");
|
|
scanf("%d%*c", codeRayon);
|
|
}
|
|
else {
|
|
indicateurCodeRayon = -1;
|
|
}
|
|
|
|
if (indicateurStock == 0) {
|
|
EXEC SQL
|
|
SELECT SYSDATE
|
|
INTO :dateStock
|
|
FROM DUAL;
|
|
|
|
}
|
|
else {
|
|
indicateurDateStock = -1;
|
|
}
|
|
|
|
EXEC SQL
|
|
INSERT INTO TPRODUIT
|
|
VALUES(
|
|
:noProd,
|
|
:des INDICATOR :indicateurDes,
|
|
:stock INDICATOR :indicateurStock,
|
|
:codeRayon INDICATOR :indicateurCodeRayon,
|
|
:dateStock INDICATOR :indicateurDateStock
|
|
);
|
|
|
|
EXEC SQL COMMIT;
|
|
}
|
|
|
|
/*
|
|
* Affiche les produits d'un fournisseur saisi.
|
|
*/
|
|
void q5(void) {
|
|
char noProd[REFERENCE_LEN], refFourn[REFERENCE_LEN];
|
|
printf("Saisir référence fournisseur : ");
|
|
scanf("%s%*c", refFourn);
|
|
|
|
EXEC SQL
|
|
DECLARE cprod CURSOR FOR
|
|
SELECT noProd
|
|
FROM TPRODUITFOURN
|
|
WHERE pf.refFourn = :refFourn;
|
|
|
|
EXEC SQL OPEN cprod;
|
|
|
|
EXEC SQL FETCH cprod INTO :noProd;
|
|
if (sqlca.sqlcode == NOT_FOUND) {
|
|
printf("Aucun produit trouvé !\n");
|
|
}
|
|
|
|
printf("Liste des numéros de produits pour ce fournisseur :\n");
|
|
while (sqlca.sqlcode != NOT_FOUND) {
|
|
printf("\t%s\n", noProd);
|
|
EXEC SQL FETCH cprod INTO :noProd;
|
|
|
|
}
|
|
|
|
EXEC SQL
|
|
CLOSE cprod;
|
|
}
|
|
|
|
/*
|
|
* Enregistre un fournisseur saisi.
|
|
*/
|
|
void q6(void) {
|
|
char refFourn[REFERENCE_LEN], dept[DEPT_LEN];
|
|
VARCHAR nom[NOM_LEN];
|
|
|
|
printf("Saisir la référence fournisseur : ");
|
|
scanf("%s%*c", refFourn);
|
|
printf("Saisir le département : ");
|
|
scanf("%s%*c", dept);
|
|
printf("Saisir le nom du fournisseur : ");
|
|
fgets(nom, sizeof nom, stdin);
|
|
if (nom[strlen(nom) - 1] == '\n') {
|
|
nom[strlen(nom) - 1] = '\0';
|
|
}
|
|
|
|
EXEC SQL
|
|
INSERT INTO TFOURNISSEUR
|
|
VALUES(:refFourn, :nom, :dept);
|
|
|
|
EXEC SQL COMMIT;
|
|
}
|
|
|
|
/*
|
|
* Supprime un fournisseur en prenant le soin de supprimer ses produits de la table de liaison.
|
|
*/
|
|
void q7(void) {
|
|
char refFourn[REFERENCE_LEN];
|
|
|
|
printf("Saisir la référence du fournisseur à supprimer : ");
|
|
scanf("%s%*c", refFourn);
|
|
|
|
EXEC SQL
|
|
DELETE FROM TPRODUITFOURN
|
|
WHERE refFourn = :refFourn;
|
|
|
|
EXEC SQL
|
|
DELETE FROM TFOURNISSEUR
|
|
WHERE refFourn = :refFourn;
|
|
}
|
|
|
|
/*
|
|
* Fonction principale.
|
|
*
|
|
* Paramètres :
|
|
* argc Le nombre d'arguments
|
|
* argv Le tableau d'arguments
|
|
*
|
|
* Retourne :
|
|
* le code de retour défini dans stdlib.h
|
|
* (EXIT_SUCCESS = 0)
|
|
*/
|
|
int main(int argc, char const *argv[]) {
|
|
int validation;
|
|
|
|
CLEAR;
|
|
|
|
connexion();
|
|
|
|
EXEC SQL
|
|
WHENEVER SQLERROR
|
|
DO erreur_sql(STOP);
|
|
|
|
// qX();
|
|
|
|
printf("Enregistrer le travail ? (1 = oui, * = non)\n");
|
|
scanf("%d%*c", &validation);
|
|
deconnexion(validation);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|