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

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