#include #include #include #include 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; }